aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/memory.c
diff options
context:
space:
mode:
authorZhang Zhen <zhenzhang.zhang@huawei.com>2014-10-09 18:26:31 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-10-09 22:25:52 -0400
commited2f240094f900833ac06f533ab8bbcf0a1e8199 (patch)
treea29d18bd9463645fa6ecdab3dd90945f861097d2 /drivers/base/memory.c
parentcc71aba348906ff93a4ad2f600045ee2d1ecc291 (diff)
memory-hotplug: add sysfs valid_zones attribute
Currently memory-hotplug has two limits: 1. If the memory block is in ZONE_NORMAL, you can change it to ZONE_MOVABLE, but this memory block must be adjacent to ZONE_MOVABLE. 2. If the memory block is in ZONE_MOVABLE, you can change it to ZONE_NORMAL, but this memory block must be adjacent to ZONE_NORMAL. With this patch, we can easy to know a memory block can be onlined to which zone, and don't need to know the above two limits. Updated the related Documentation. [akpm@linux-foundation.org: use conventional comment layout] [akpm@linux-foundation.org: fix build with CONFIG_MEMORY_HOTREMOVE=n] [akpm@linux-foundation.org: remove unused local zone_prev] Signed-off-by: Zhang Zhen <zhenzhang.zhang@huawei.com> Cc: Dave Hansen <dave.hansen@intel.com> Cc: David Rientjes <rientjes@google.com> Cc: Toshi Kani <toshi.kani@hp.com> Cc: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com> Cc: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com> Cc: Wang Nan <wangnan0@huawei.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/base/memory.c')
-rw-r--r--drivers/base/memory.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index a2e13e250bba..7c5d87191b28 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -373,6 +373,45 @@ static ssize_t show_phys_device(struct device *dev,
373 return sprintf(buf, "%d\n", mem->phys_device); 373 return sprintf(buf, "%d\n", mem->phys_device);
374} 374}
375 375
376#ifdef CONFIG_MEMORY_HOTREMOVE
377static ssize_t show_valid_zones(struct device *dev,
378 struct device_attribute *attr, char *buf)
379{
380 struct memory_block *mem = to_memory_block(dev);
381 unsigned long start_pfn, end_pfn;
382 unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block;
383 struct page *first_page;
384 struct zone *zone;
385
386 start_pfn = section_nr_to_pfn(mem->start_section_nr);
387 end_pfn = start_pfn + nr_pages;
388 first_page = pfn_to_page(start_pfn);
389
390 /* The block contains more than one zone can not be offlined. */
391 if (!test_pages_in_a_zone(start_pfn, end_pfn))
392 return sprintf(buf, "none\n");
393
394 zone = page_zone(first_page);
395
396 if (zone_idx(zone) == ZONE_MOVABLE - 1) {
397 /*The mem block is the last memoryblock of this zone.*/
398 if (end_pfn == zone_end_pfn(zone))
399 return sprintf(buf, "%s %s\n",
400 zone->name, (zone + 1)->name);
401 }
402
403 if (zone_idx(zone) == ZONE_MOVABLE) {
404 /*The mem block is the first memoryblock of ZONE_MOVABLE.*/
405 if (start_pfn == zone->zone_start_pfn)
406 return sprintf(buf, "%s %s\n",
407 zone->name, (zone - 1)->name);
408 }
409
410 return sprintf(buf, "%s\n", zone->name);
411}
412static DEVICE_ATTR(valid_zones, 0444, show_valid_zones, NULL);
413#endif
414
376static DEVICE_ATTR(phys_index, 0444, show_mem_start_phys_index, NULL); 415static DEVICE_ATTR(phys_index, 0444, show_mem_start_phys_index, NULL);
377static DEVICE_ATTR(state, 0644, show_mem_state, store_mem_state); 416static DEVICE_ATTR(state, 0644, show_mem_state, store_mem_state);
378static DEVICE_ATTR(phys_device, 0444, show_phys_device, NULL); 417static DEVICE_ATTR(phys_device, 0444, show_phys_device, NULL);
@@ -523,6 +562,9 @@ static struct attribute *memory_memblk_attrs[] = {
523 &dev_attr_state.attr, 562 &dev_attr_state.attr,
524 &dev_attr_phys_device.attr, 563 &dev_attr_phys_device.attr,
525 &dev_attr_removable.attr, 564 &dev_attr_removable.attr,
565#ifdef CONFIG_MEMORY_HOTREMOVE
566 &dev_attr_valid_zones.attr,
567#endif
526 NULL 568 NULL
527}; 569};
528 570