aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/memory.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/memory.c')
-rw-r--r--drivers/base/memory.c52
1 files changed, 28 insertions, 24 deletions
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index 1e884d82af6f..b86fda30ce62 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -392,39 +392,43 @@ static ssize_t show_valid_zones(struct device *dev,
392 struct device_attribute *attr, char *buf) 392 struct device_attribute *attr, char *buf)
393{ 393{
394 struct memory_block *mem = to_memory_block(dev); 394 struct memory_block *mem = to_memory_block(dev);
395 unsigned long start_pfn, end_pfn; 395 unsigned long start_pfn = section_nr_to_pfn(mem->start_section_nr);
396 unsigned long valid_start, valid_end, valid_pages;
397 unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block; 396 unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block;
398 struct zone *zone; 397 unsigned long valid_start_pfn, valid_end_pfn;
399 int zone_shift = 0; 398 bool append = false;
399 int nid;
400 400
401 start_pfn = section_nr_to_pfn(mem->start_section_nr); 401 /*
402 end_pfn = start_pfn + nr_pages; 402 * The block contains more than one zone can not be offlined.
403 403 * This can happen e.g. for ZONE_DMA and ZONE_DMA32
404 /* The block contains more than one zone can not be offlined. */ 404 */
405 if (!test_pages_in_a_zone(start_pfn, end_pfn, &valid_start, &valid_end)) 405 if (!test_pages_in_a_zone(start_pfn, start_pfn + nr_pages, &valid_start_pfn, &valid_end_pfn))
406 return sprintf(buf, "none\n"); 406 return sprintf(buf, "none\n");
407 407
408 zone = page_zone(pfn_to_page(valid_start)); 408 start_pfn = valid_start_pfn;
409 valid_pages = valid_end - valid_start; 409 nr_pages = valid_end_pfn - start_pfn;
410
411 /* MMOP_ONLINE_KEEP */
412 sprintf(buf, "%s", zone->name);
413 410
414 /* MMOP_ONLINE_KERNEL */ 411 /*
415 zone_can_shift(valid_start, valid_pages, ZONE_NORMAL, &zone_shift); 412 * Check the existing zone. Make sure that we do that only on the
416 if (zone_shift) { 413 * online nodes otherwise the page_zone is not reliable
417 strcat(buf, " "); 414 */
418 strcat(buf, (zone + zone_shift)->name); 415 if (mem->state == MEM_ONLINE) {
416 strcat(buf, page_zone(pfn_to_page(start_pfn))->name);
417 goto out;
419 } 418 }
420 419
421 /* MMOP_ONLINE_MOVABLE */ 420 nid = pfn_to_nid(start_pfn);
422 zone_can_shift(valid_start, valid_pages, ZONE_MOVABLE, &zone_shift); 421 if (allow_online_pfn_range(nid, start_pfn, nr_pages, MMOP_ONLINE_KERNEL)) {
423 if (zone_shift) { 422 strcat(buf, NODE_DATA(nid)->node_zones[ZONE_NORMAL].name);
424 strcat(buf, " "); 423 append = true;
425 strcat(buf, (zone + zone_shift)->name);
426 } 424 }
427 425
426 if (allow_online_pfn_range(nid, start_pfn, nr_pages, MMOP_ONLINE_MOVABLE)) {
427 if (append)
428 strcat(buf, " ");
429 strcat(buf, NODE_DATA(nid)->node_zones[ZONE_MOVABLE].name);
430 }
431out:
428 strcat(buf, "\n"); 432 strcat(buf, "\n");
429 433
430 return strlen(buf); 434 return strlen(buf);