diff options
Diffstat (limited to 'drivers/base/memory.c')
-rw-r--r-- | drivers/base/memory.c | 52 |
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 | } | ||
431 | out: | ||
428 | strcat(buf, "\n"); | 432 | strcat(buf, "\n"); |
429 | 433 | ||
430 | return strlen(buf); | 434 | return strlen(buf); |