From: Wen Congyang <redacted>
This patch series aims to support physical memory hot-remove.
The patches can free/remove the following things:
- acpi_memory_info : [RFC PATCH 4/19]
- /sys/firmware/memmap/X/{end, start, type} : [RFC PATCH 8/19]
- iomem_resource : [RFC PATCH 9/19]
- mem_section and related sysfs files : [RFC PATCH 10-11, 13-16/19]
- page table of removed memory : [RFC PATCH 12/19]
- node and related sysfs files : [RFC PATCH 18-19/19]
If you find lack of function for physical memory hot-remove, please let me
know.
How to test this patchset?
1. apply this patchset and build the kernel. MEMORY_HOTPLUG, MEMORY_HOTREMOVE,
ACPI_HOTPLUG_MEMORY must be selected.
2. load the module acpi_memhotplug
3. hotplug the memory device(it depends on your hardware)
You will see the memory device under the directory /sys/bus/acpi/devices/.
Its name is PNP0C80:XX.
4. online/offline pages provided by this memory device
You can write online/offline to /sys/devices/system/memory/memoryX/state to
online/offline pages provided by this memory device
5. hotremove the memory device
You can hotremove the memory device by the hardware, or writing 1 to
/sys/bus/acpi/devices/PNP0C80:XX/eject.
Note: if the memory provided by the memory device is used by the kernel, it
can't be offlined. It is not a bug.
Known problems:
1. memory can't be offlined when CONFIG_MEMCG is selected.
For example: there is a memory device on node 1. The address range
is [1G, 1.5G). You will find 4 new directories memory8, memory9, memory10,
and memory11 under the directory /sys/devices/system/memory/.
If CONFIG_MEMCG is selected, we will allocate memory to store page cgroup
when we online pages. When we online memory8, the memory stored page cgroup
is not provided by this memory device. But when we online memory9, the memory
stored page cgroup may be provided by memory8. So we can't offline memory8
now. We should offline the memory in the reversed order.
When the memory device is hotremoved, we will auto offline memory provided
by this memory device. But we don't know which memory is onlined first, so
offlining memory may fail. In such case, you should offline the memory by
hand before hotremoving the memory device.
2. hotremoving memory device may cause kernel panicked
This bug will be fixed by Liu Jiang's patch:
https://lkml.org/lkml/2012/7/3/1
change log of v9:
[RFC PATCH v9 8/21]
* add a lock to protect the list map_entries
* add an indicator to firmware_map_entry to remember whether the memory
is allocated from bootmem
[RFC PATCH v9 10/21]
* change the macro to inline function
[RFC PATCH v9 19/21]
* don't offline the node if the cpu on the node is onlined
[RFC PATCH v9 21/21]
* create new patch: auto offline page_cgroup when onlining memory block
failed
change log of v8:
[RFC PATCH v8 17/20]
* Fix problems when one node's range include the other nodes
[RFC PATCH v8 18/20]
* fix building error when CONFIG_MEMORY_HOTPLUG_SPARSE or CONFIG_HUGETLBFS
is not defined.
[RFC PATCH v8 19/20]
* don't offline node when some memory sections are not removed
[RFC PATCH v8 20/20]
* create new patch: clear hwpoisoned flag when onlining pages
change log of v7:
[RFC PATCH v7 4/19]
* do not continue if acpi_memory_device_remove_memory() fails.
[RFC PATCH v7 15/19]
* handle usemap in register_page_bootmem_info_section() too.
change log of v6:
[RFC PATCH v6 12/19]
* fix building error on other archtitectures than x86
[RFC PATCH v6 15-16/19]
* fix building error on other archtitectures than x86
change log of v5:
* merge the patchset to clear page table and the patchset to hot remove
memory(from ishimatsu) to one big patchset.
[RFC PATCH v5 1/19]
* rename remove_memory() to offline_memory()/offline_pages()
[RFC PATCH v5 2/19]
* new patch: implement offline_memory(). This function offlines pages,
update memory block's state, and notify the userspace that the memory
block's state is changed.
[RFC PATCH v5 4/19]
* offline and remove memory in acpi_memory_disable_device() too.
[RFC PATCH v5 17/19]
* new patch: add a new function __remove_zone() to revert the things done
in the function __add_zone().
[RFC PATCH v5 18/19]
* flush work befor reseting node device.
change log of v4:
* remove "memory-hotplug : unify argument of firmware_map_add_early/hotplug"
from the patch series, since the patch is a bugfix. It is being disccussed
on other thread. But for testing the patch series, the patch is needed.
So I added the patch as [PATCH 0/13].
[RFC PATCH v4 2/13]
* check memory is online or not at remove_memory()
* add memory_add_physaddr_to_nid() to acpi_memory_device_remove() for
getting node id
[RFC PATCH v4 3/13]
* create new patch : check memory is online or not at online_pages()
[RFC PATCH v4 4/13]
* add __ref section to remove_memory()
* call firmware_map_remove_entry() before remove_sysfs_fw_map_entry()
[RFC PATCH v4 11/13]
* rewrite register_page_bootmem_memmap() for removing page used as PT/PMD
change log of v3:
* rebase to 3.5.0-rc6
[RFC PATCH v2 2/13]
* remove extra kobject_put()
* The patch was commented by Wen. Wen's comment is
"acpi_memory_device_remove() should ignore a return value of
remove_memory() since caller does not care the return value".
But I did not change it since I think caller should care the
return value. And I am trying to fix it as follow:
https://lkml.org/lkml/2012/7/5/624
[RFC PATCH v2 4/13]
* remove a firmware_memmap_entry allocated by kzmalloc()
change log of v2:
[RFC PATCH v2 2/13]
* check whether memory block is offline or not before calling offline_memory()
* check whether section is valid or not in is_memblk_offline()
* call kobject_put() for each memory_block in is_memblk_offline()
[RFC PATCH v2 3/13]
* unify the end argument of firmware_map_add_early/hotplug
[RFC PATCH v2 4/13]
* add release_firmware_map_entry() for freeing firmware_map_entry
[RFC PATCH v2 6/13]
* add release_memory_block() for freeing memory_block
[RFC PATCH v2 11/13]
* fix wrong arguments of free_pages()
Wen Congyang (8):
memory-hotplug: implement offline_memory()
memory-hotplug: store the node id in acpi_memory_device
memory-hotplug: export the function acpi_bus_remove()
memory-hotplug: call acpi_bus_remove() to remove memory device
memory-hotplug: introduce new function arch_remove_memory()
memory-hotplug: remove sysfs file of node
memory-hotplug: clear hwpoisoned flag when onlining pages
memory-hotplug: auto offline page_cgroup when onlining memory block
failed
Yasuaki Ishimatsu (13):
memory-hotplug: rename remove_memory() to
offline_memory()/offline_pages()
memory-hotplug: offline and remove memory when removing the memory
device
memory-hotplug: check whether memory is present or not
memory-hotplug: remove /sys/firmware/memmap/X sysfs
memory-hotplug: does not release memory region in PAGES_PER_SECTION
chunks
memory-hotplug: add memory_block_release
memory-hotplug: remove_memory calls __remove_pages
memory-hotplug: check page type in get_page_bootmem
memory-hotplug: move register_page_bootmem_info_node and
put_page_bootmem for sparse-vmemmap
memory-hotplug: implement register_page_bootmem_info_section of
sparse-vmemmap
memory-hotplug: free memmap of sparse-vmemmap
memory_hotplug: clear zone when the memory is removed
memory-hotplug: add node_device_release
arch/ia64/mm/discontig.c | 14 +
arch/ia64/mm/init.c | 16 +
arch/powerpc/mm/init_64.c | 14 +
arch/powerpc/mm/mem.c | 14 +
arch/powerpc/platforms/pseries/hotplug-memory.c | 16 +-
arch/s390/mm/init.c | 12 +
arch/s390/mm/vmem.c | 14 +
arch/sh/mm/init.c | 15 +
arch/sparc/mm/init_64.c | 14 +
arch/tile/mm/init.c | 8 +
arch/x86/include/asm/pgtable_types.h | 1 +
arch/x86/mm/init_32.c | 10 +
arch/x86/mm/init_64.c | 331 ++++++++++++++++++
arch/x86/mm/pageattr.c | 47 ++--
drivers/acpi/acpi_memhotplug.c | 54 +++-
drivers/acpi/scan.c | 3 +-
drivers/base/memory.c | 88 ++++-
drivers/base/node.c | 11 +
drivers/firmware/memmap.c | 98 +++++-
include/acpi/acpi_bus.h | 1 +
include/linux/firmware-map.h | 6 +
include/linux/memory.h | 5 +
include/linux/memory_hotplug.h | 25 +-
include/linux/mm.h | 5 +-
include/linux/mmzone.h | 19 +
mm/memory_hotplug.c | 424 +++++++++++++++++++++--
mm/page_cgroup.c | 3 +
mm/sparse.c | 5 +-
28 files changed, 1181 insertions(+), 92 deletions(-)
From: Wen Congyang <redacted>
The memory device has been ejected and powoffed, so we can call
acpi_bus_remove() to remove the memory device from acpi bus.
CC: David Rientjes <rientjes@google.com>
CC: Jiang Liu <redacted>
CC: Len Brown <redacted>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <redacted>
CC: Christoph Lameter <redacted>
Cc: Minchan Kim <redacted>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: KOSAKI Motohiro <redacted>
CC: Yasuaki Ishimatsu <redacted>
Signed-off-by: Wen Congyang <redacted>
---
drivers/acpi/acpi_memhotplug.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
From: Wen Congyang <redacted>
The memory device has only one node id. Store the node id when
enable the memory device, and we can reuse it when removing the
memory device.
CC: David Rientjes <rientjes@google.com>
CC: Jiang Liu <redacted>
CC: Len Brown <redacted>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <redacted>
CC: Christoph Lameter <redacted>
Cc: Minchan Kim <redacted>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: KOSAKI Motohiro <redacted>
CC: Yasuaki Ishimatsu <redacted>
Signed-off-by: Wen Congyang <redacted>
Reviewed-by: Yasuaki Ishimatsu <redacted>
---
drivers/acpi/acpi_memhotplug.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
@@ -83,6 +83,7 @@ struct acpi_memory_info {structacpi_memory_device{structacpi_device*device;unsignedintstate;/* State of the memory device */+intnid;structlist_headres_list;};
@@ -256,6 +257,9 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device)info->enabled=1;num_enabled++;}++mem_device->nid=node;+if(!num_enabled){printk(KERN_ERRPREFIX"add_memory failed\n");mem_device->state=MEMORY_INVALID_STATE;
From: Wen Congyang <redacted>
The function acpi_bus_remove() can remove a acpi device from acpi device.
When a acpi device is removed, we need to call this function to remove
the acpi device from acpi bus. So export this function.
CC: David Rientjes <rientjes@google.com>
CC: Jiang Liu <redacted>
CC: Len Brown <redacted>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <redacted>
CC: Christoph Lameter <redacted>
Cc: Minchan Kim <redacted>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: KOSAKI Motohiro <redacted>
CC: Yasuaki Ishimatsu <redacted>
Signed-off-by: Wen Congyang <redacted>
---
drivers/acpi/scan.c | 3 ++-
include/acpi/acpi_bus.h | 1 +
2 files changed, 3 insertions(+), 1 deletions(-)
From: Yasuaki Ishimatsu <redacted>
When (hot)adding memory into system, /sys/firmware/memmap/X/{end, start, type}
sysfs files are created. But there is no code to remove these files. The patch
implements the function to remove them.
Note : The code does not free firmware_map_entry since there is no way to free
memory which is allocated by bootmem.
CC: David Rientjes <rientjes@google.com>
CC: Jiang Liu <redacted>
CC: Len Brown <redacted>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <redacted>
CC: Christoph Lameter <redacted>
Cc: Minchan Kim <redacted>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: KOSAKI Motohiro <redacted>
Signed-off-by: Yasuaki Ishimatsu <redacted>
Signed-off-by: Wen Congyang <redacted>
---
drivers/firmware/memmap.c | 98 +++++++++++++++++++++++++++++++++++++++++-
include/linux/firmware-map.h | 6 +++
mm/memory_hotplug.c | 9 +++-
3 files changed, 109 insertions(+), 4 deletions(-)
@@ -41,6 +42,7 @@ struct firmware_map_entry {constchar*type;/* type of the memory range */structlist_headlist;/* entry for the linked list */structkobjectkobj;/* kobject for each entry */+unsignedintbootmem:1;/* allocated from bootmem */};/*
@@ -79,7 +81,26 @@ static const struct sysfs_ops memmap_attr_ops = {.show=memmap_attr_show,};++staticinlinestructfirmware_map_entry*+to_memmap_entry(structkobject*kobj)+{+returncontainer_of(kobj,structfirmware_map_entry,kobj);+}++staticvoidrelease_firmware_map_entry(structkobject*kobj)+{+structfirmware_map_entry*entry=to_memmap_entry(kobj);++if(entry->bootmem)+/* There is no way to free memory allocated from bootmem */+return;++kfree(entry);+}+staticstructkobj_typememmap_ktype={+.release=release_firmware_map_entry,.sysfs_ops=&memmap_attr_ops,.default_attrs=def_attrs,};
From: Wen Congyang <redacted>
When a memory block is onlined, we will try allocate memory on that node
to store page_cgroup. If onlining the memory block failed, we don't
offline the page cgroup, and we have no chance to offline this page cgroup
unless the memory block is onlined successfully again. It will cause
that we can't hot-remove the memory device on that node, because some
memory is used to store page cgroup. If onlining the memory block
is failed, there is no need to stort page cgroup for this memory. So
auto offline page_cgroup when onlining memory block failed.
CC: David Rientjes <rientjes@google.com>
CC: Jiang Liu <redacted>
CC: Len Brown <redacted>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <redacted>
CC: Christoph Lameter <redacted>
Cc: Minchan Kim <redacted>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: KOSAKI Motohiro <redacted>
CC: Yasuaki Ishimatsu <redacted>
Signed-off-by: Wen Congyang <redacted>
---
mm/page_cgroup.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
From: Wen Congyang <redacted>
hwpoisoned may set when we offline a page by the sysfs interface
/sys/devices/system/memory/soft_offline_page or
/sys/devices/system/memory/hard_offline_page. If we don't clear
this flag when onlining pages, this page can't be freed, and will
not in free list. So we can't offline these pages again. So we
should clear this flag when onlining pages.
CC: David Rientjes <rientjes@google.com>
CC: Jiang Liu <redacted>
CC: Len Brown <redacted>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <redacted>
CC: Christoph Lameter <redacted>
Cc: Minchan Kim <redacted>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: KOSAKI Motohiro <redacted>
CC: Yasuaki Ishimatsu <redacted>
Signed-off-by: Wen Congyang <redacted>
---
mm/memory_hotplug.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
@@ -661,6 +661,11 @@ EXPORT_SYMBOL_GPL(__online_page_increment_counters);void__online_page_free(structpage*page){+#ifdef CONFIG_MEMORY_FAILURE+/* The page may be marked HWPoisoned by soft/hard offline page */+ClearPageHWPoison(page);+#endif+ClearPageReserved(page);init_page_count(page);__free_page(page);
From: Yasuaki Ishimatsu <redacted>
For removing memmap region of sparse-vmemmap which is allocated bootmem,
memmap region of sparse-vmemmap needs to be registered by get_page_bootmem().
So the patch searches pages of virtual mapping and registers the pages by
get_page_bootmem().
Note: register_page_bootmem_memmap() is not implemented for ia64, ppc, s390,
and sparc.
CC: David Rientjes <rientjes@google.com>
CC: Jiang Liu <redacted>
CC: Len Brown <redacted>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <redacted>
CC: Christoph Lameter <redacted>
Cc: Minchan Kim <redacted>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: KOSAKI Motohiro <redacted>
Signed-off-by: Yasuaki Ishimatsu <redacted>
Signed-off-by: Wen Congyang <redacted>
---
arch/ia64/mm/discontig.c | 6 ++++
arch/powerpc/mm/init_64.c | 6 ++++
arch/s390/mm/vmem.c | 6 ++++
arch/sparc/mm/init_64.c | 6 ++++
arch/x86/mm/init_64.c | 52 ++++++++++++++++++++++++++++++++++++++++
include/linux/memory_hotplug.h | 2 +
include/linux/mm.h | 3 +-
mm/memory_hotplug.c | 31 +++++++++++++++++++++--
8 files changed, 108 insertions(+), 4 deletions(-)
From: Wen Congyang <redacted>
The function offline_memory() will be called when hot removing a
memory device. The memory device may contain more than one memory
block. If the memory block has been offlined, __offline_pages()
will fail. So we should try to offline one memory block at a
time.
If the memory block is offlined in offline_memory(), we also
update it's state, and notify the userspace that its state is
changed.
The function offline_memory() also check each memory block's
state. So there is no need to check the memory block's state
before calling offline_memory().
CC: David Rientjes <rientjes@google.com>
CC: Jiang Liu <redacted>
CC: Len Brown <redacted>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <redacted>
CC: Christoph Lameter <redacted>
Cc: Minchan Kim <redacted>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: KOSAKI Motohiro <redacted>
CC: Yasuaki Ishimatsu <redacted>
CC: Vasilis Liaskovitis <redacted>
Signed-off-by: Wen Congyang <redacted>
---
drivers/base/memory.c | 31 +++++++++++++++++++++++++++----
include/linux/memory_hotplug.h | 2 ++
mm/memory_hotplug.c | 37 ++++++++++++++++++++++++++++++++++++-
3 files changed, 65 insertions(+), 5 deletions(-)
@@ -275,13 +275,11 @@ memory_block_action(unsigned long phys_index, unsigned long action)returnret;}-staticintmemory_block_change_state(structmemory_block*mem,+staticint__memory_block_change_state(structmemory_block*mem,unsignedlongto_state,unsignedlongfrom_state_req){intret=0;-mutex_lock(&mem->state_mutex);-if(mem->state!=from_state_req){ret=-EINVAL;gotoout;
@@ -309,10 +307,20 @@ static int memory_block_change_state(struct memory_block *mem,break;}out:-mutex_unlock(&mem->state_mutex);returnret;}+staticintmemory_block_change_state(structmemory_block*mem,+unsignedlongto_state,unsignedlongfrom_state_req)+{+intret;++mutex_lock(&mem->state_mutex);+ret=__memory_block_change_state(mem,to_state,from_state_req);+mutex_unlock(&mem->state_mutex);++returnret;+}staticssize_tstore_mem_state(structdevice*dev,structdevice_attribute*attr,constchar*buf,size_tcount)
@@ -653,6 +661,21 @@ int unregister_memory_section(struct mem_section *section)}/*+*offlineonememoryblock.Ifthememoryblockhasbeenofflined,donothing.+*/+intoffline_memory_block(structmemory_block*mem)+{+intret=0;++mutex_lock(&mem->state_mutex);+if(mem->state!=MEM_OFFLINE)+ret=__memory_block_change_state(mem,MEM_OFFLINE,MEM_ONLINE);+mutex_unlock(&mem->state_mutex);++returnret;+}++/**Initializethesysfssupportformemorydevices...*/int__initmemory_dev_init(void)
@@ -1001,7 +1001,42 @@ int offline_pages(unsigned long start_pfn, unsigned long nr_pages)intoffline_memory(u64start,u64size){-return-EINVAL;+structmemory_block*mem=NULL;+structmem_section*section;+unsignedlongstart_pfn,end_pfn;+unsignedlongpfn,section_nr;+intret;++start_pfn=PFN_DOWN(start);+end_pfn=start_pfn+PFN_DOWN(size);++for(pfn=start_pfn;pfn<end_pfn;pfn+=PAGES_PER_SECTION){+section_nr=pfn_to_section_nr(pfn);+if(!present_section_nr(section_nr))+continue;++section=__nr_to_section(section_nr);+/* same memblock? */+if(mem)+if((section_nr>=mem->start_section_nr)&&+(section_nr<=mem->end_section_nr))+continue;++mem=find_memory_block_hinted(section,mem);+if(!mem)+continue;++ret=offline_memory_block(mem);+if(ret){+kobject_put(&mem->dev.kobj);+returnret;+}+}++if(mem)+kobject_put(&mem->dev.kobj);++return0;}#elseintoffline_pages(unsignedlongstart,unsignedlongsize)
@@ -467,6 +467,19 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages)structmemory_notifyarg;lock_memory_hotplug();+/*+*Ifsystemsupportsmemoryhot-remove,thememorymayhavebeen+*removed.Sowecheckwhetherthememoryhasbeenremovedornot.+*+*Note:WhenCONFIG_SPARSEMEMisdefined,pfns_present()become+*effective.IfCONFIG_SPARSEMEMisnotdefined,pfns_present()+*alwaysreturns0.+*/+ret=pfns_present(pfn,nr_pages);+if(ret){+unlock_memory_hotplug();+returnret;+}arg.start_pfn=pfn;arg.nr_pages=nr_pages;arg.status_change_nid=-1;
From: Yasuaki Ishimatsu <redacted>
We should offline and remove memory when removing the memory device.
The memory device can be removed by 2 ways:
1. send eject request by SCI
2. echo 1 >/sys/bus/pci/devices/PNP0C80:XX/eject
In the 1st case, acpi_memory_disable_device() will be called. In the 2nd
case, acpi_memory_device_remove() will be called. acpi_memory_device_remove()
will also be called when we unbind the memory device from the driver
acpi_memhotplug. If the type is ACPI_BUS_REMOVAL_EJECT, it means
that the user wants to eject the memory device, and we should offline
and remove memory in acpi_memory_device_remove().
The function remove_memory() is not implemeted now. It only check whether
all memory has been offllined now.
CC: David Rientjes <rientjes@google.com>
CC: Jiang Liu <redacted>
CC: Len Brown <redacted>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <redacted>
CC: Christoph Lameter <redacted>
Cc: Minchan Kim <redacted>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: KOSAKI Motohiro <redacted>
Signed-off-by: Yasuaki Ishimatsu <redacted>
Signed-off-by: Wen Congyang <redacted>
---
drivers/acpi/acpi_memhotplug.c | 45 +++++++++++++++++++++++++++++++++------
drivers/base/memory.c | 39 ++++++++++++++++++++++++++++++++++
include/linux/memory.h | 5 ++++
include/linux/memory_hotplug.h | 5 ++++
mm/memory_hotplug.c | 22 +++++++++++++++++++
5 files changed, 109 insertions(+), 7 deletions(-)
@@ -310,25 +311,44 @@ static int acpi_memory_powerdown_device(struct acpi_memory_device *mem_device)return0;}-staticintacpi_memory_disable_device(structacpi_memory_device*mem_device)+staticint+acpi_memory_device_remove_memory(structacpi_memory_device*mem_device){intresult;structacpi_memory_info*info,*n;+intnode=mem_device->nid;--/*-*AsktheVMtoofflinethismemoryrange.-*Note:Assumethatthisfunctionreturnszeroonsuccess-*/list_for_each_entry_safe(info,n,&mem_device->res_list,list){if(info->enabled){result=offline_memory(info->start_addr,info->length);if(result)returnresult;++result=remove_memory(node,info->start_addr,+info->length);+if(result)+returnresult;}++list_del(&info->list);kfree(info);}+return0;+}++staticintacpi_memory_disable_device(structacpi_memory_device*mem_device)+{+intresult;++/*+*AsktheVMtoofflinethismemoryrange.+*Note:Assumethatthisfunctionreturnszeroonsuccess+*/+result=acpi_memory_device_remove_memory(mem_device);+if(result)+returnresult;+/* Power-off and eject the device */result=acpi_memory_powerdown_device(mem_device);if(result){
@@ -477,12 +497,23 @@ static int acpi_memory_device_add(struct acpi_device *device)staticintacpi_memory_device_remove(structacpi_device*device,inttype){structacpi_memory_device*mem_device=NULL;-+intresult;if(!device||!acpi_driver_data(device))return-EINVAL;mem_device=acpi_driver_data(device);++if(type==ACPI_BUS_REMOVAL_EJECT){+/*+*offlineandremovememoryonlywhenthememorydeviceis+*ejected.+*/+result=acpi_memory_device_remove_memory(mem_device);+if(result)+returnresult;+}+kfree(mem_device);return0;
@@ -1038,6 +1038,28 @@ int offline_memory(u64 start, u64 size)return0;}++intremove_memory(intnid,u64start,u64size)+{+intret=-EBUSY;+lock_memory_hotplug();+/*+*Thememorymightbecomeonlinebyothertask,evenifyouoffineit.+*Sowecheckwhetherthememoryhasbeenonlinedornot.+*/+if(!is_memblk_offline(start,size)){+pr_warn("memory removing [mem %#010llx-%#010llx] failed, "+"because the memmory range is online\n",+start,start+size);+ret=-EAGAIN;+}++unlock_memory_hotplug();+returnret;++}+EXPORT_SYMBOL_GPL(remove_memory);+#elseintoffline_pages(unsignedlongstart,unsignedlongsize){
From: Yasuaki Ishimatsu <redacted>
remove_memory() only try to offline pages. It is called in two cases:
1. hot remove a memory device
2. echo offline >/sys/devices/system/memory/memoryXX/state
In the 1st case, we should also change memory block's state, and notify
the userspace that the memory block's state is changed after offlining
pages.
So rename remove_memory() to offline_memory()/offline_pages(). And in
the 1st case, offline_memory() will be used. The function offline_memory()
is not implemented. In the 2nd case, offline_pages() will be used.
CC: David Rientjes <rientjes@google.com>
CC: Jiang Liu <redacted>
CC: Len Brown <redacted>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <redacted>
CC: Christoph Lameter <redacted>
Cc: Minchan Kim <redacted>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: KOSAKI Motohiro <redacted>
Signed-off-by: Yasuaki Ishimatsu <redacted>
Signed-off-by: Wen Congyang <redacted>
---
drivers/acpi/acpi_memhotplug.c | 2 +-
drivers/base/memory.c | 9 +++------
include/linux/memory_hotplug.h | 3 ++-
mm/memory_hotplug.c | 22 ++++++++++++++--------
4 files changed, 20 insertions(+), 16 deletions(-)
@@ -233,7 +233,8 @@ static inline int is_mem_section_removable(unsigned long pfn,externintmem_online_node(intnid);externintadd_memory(intnid,u64start,u64size);externintarch_add_memory(intnid,u64start,u64size);-externintremove_memory(u64start,u64size);+externintoffline_pages(unsignedlongstart_pfn,unsignedlongnr_pages);+externintoffline_memory(u64start,u64size);externintsparse_add_one_section(structzone*zone,unsignedlongstart_pfn,intnr_pages);externvoidsparse_remove_one_section(structzone*zone,structmem_section*ms);
@@ -866,7 +866,7 @@ check_pages_isolated(unsigned long start_pfn, unsigned long end_pfn)returnofflined;}-staticint__refoffline_pages(unsignedlongstart_pfn,+staticint__ref__offline_pages(unsignedlongstart_pfn,unsignedlongend_pfn,unsignedlongtimeout){unsignedlongpfn,nr_pages,expire;
From: Yasuaki Ishimatsu <redacted>
Since applying a patch(de7f0cba96786c), release_mem_region() has been changed
as called in PAGES_PER_SECTION chunks because register_memory_resource() is
called in PAGES_PER_SECTION chunks by add_memory(). But it seems firmware
dependency. If CRS are written in the PAGES_PER_SECTION chunks in ACPI DSDT
Table, register_memory_resource() is called in PAGES_PER_SECTION chunks.
But if CRS are written in the DIMM unit in ACPI DSDT Table,
register_memory_resource() is called in DIMM unit. So release_mem_region()
should not be called in PAGES_PER_SECTION chunks. The patch fixes it.
CC: David Rientjes <rientjes@google.com>
CC: Jiang Liu <redacted>
CC: Len Brown <redacted>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <redacted>
CC: Christoph Lameter <redacted>
Cc: Minchan Kim <redacted>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: KOSAKI Motohiro <redacted>
CC: Wen Congyang <redacted>
Signed-off-by: Yasuaki Ishimatsu <redacted>
---
arch/powerpc/platforms/pseries/hotplug-memory.c | 13 +++++++++----
mm/memory_hotplug.c | 4 ++--
2 files changed, 11 insertions(+), 6 deletions(-)
@@ -77,7 +77,8 @@ static int pseries_remove_memblock(unsigned long base, unsigned int memblock_siz{unsignedlongstart,start_pfn;structzone*zone;-intret;+inti,ret;+intsections_to_remove;start_pfn=base>>PAGE_SHIFT;
@@ -97,9 +98,13 @@ static int pseries_remove_memblock(unsigned long base, unsigned int memblock_siz*tosysfs"state"fileandwecan'tremovesysfsentries*whilewritingtoit.Sowehavetodeferittohere.*/-ret=__remove_pages(zone,start_pfn,memblock_size>>PAGE_SHIFT);-if(ret)-returnret;+sections_to_remove=(memblock_size>>PAGE_SHIFT)/PAGES_PER_SECTION;+for(i=0;i<sections_to_remove;i++){+unsignedlongpfn=start_pfn+i*PAGES_PER_SECTION;+ret=__remove_pages(zone,start_pfn,PAGES_PER_SECTION);+if(ret)+returnret;+}/**Updatememoryregionsformemoryremove
@@ -358,11 +358,11 @@ int __remove_pages(struct zone *zone, unsigned long phys_start_pfn,BUG_ON(phys_start_pfn&~PAGE_SECTION_MASK);BUG_ON(nr_pages%PAGES_PER_SECTION);+release_mem_region(phys_start_pfn<<PAGE_SHIFT,nr_pages*PAGE_SIZE);+sections_to_remove=nr_pages/PAGES_PER_SECTION;for(i=0;i<sections_to_remove;i++){unsignedlongpfn=phys_start_pfn+i*PAGES_PER_SECTION;-release_mem_region(pfn<<PAGE_SHIFT,-PAGES_PER_SECTION<<PAGE_SHIFT);ret=__remove_section(zone,__pfn_to_section(pfn));if(ret)break;
From: Yasuaki Ishimatsu <redacted>
The function get_page_bootmem() may be called more than one time to the same
page. There is no need to set page's type, private if the function is not
the first time called to the page.
Note: the patch is just optimization and does not fix any problem.
CC: David Rientjes <rientjes@google.com>
CC: Jiang Liu <redacted>
CC: Len Brown <redacted>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <redacted>
CC: Christoph Lameter <redacted>
Cc: Minchan Kim <redacted>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: KOSAKI Motohiro <redacted>
CC: Wen Congyang <redacted>
Signed-off-by: Yasuaki Ishimatsu <redacted>
---
mm/memory_hotplug.c | 15 +++++++++++----
1 files changed, 11 insertions(+), 4 deletions(-)
From: Yasuaki Ishimatsu <redacted>
When calling remove_memory_block(), the function shows following message at
device_release().
Device 'memory528' does not have a release() function, it is broken and must
be fixed.
remove_memory_block() calls kfree(mem). I think it shouled be called from
device_release(). So the patch implements memory_block_release()
CC: David Rientjes <rientjes@google.com>
CC: Jiang Liu <redacted>
CC: Len Brown <redacted>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <redacted>
CC: Christoph Lameter <redacted>
Cc: Minchan Kim <redacted>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: KOSAKI Motohiro <redacted>
CC: Wen Congyang <redacted>
Signed-off-by: Yasuaki Ishimatsu <redacted>
---
drivers/base/memory.c | 9 ++++++++-
1 files changed, 8 insertions(+), 1 deletions(-)
From: Wen Congyang <redacted>
This patch introduces a new function try_offline_node() to
remove sysfs file of node when all memory sections of this
node are removed. If some memory sections of this node are
not removed, this function does nothing.
CC: David Rientjes <rientjes@google.com>
CC: Jiang Liu <redacted>
CC: Len Brown <redacted>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <redacted>
CC: Christoph Lameter <redacted>
Cc: Minchan Kim <redacted>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: KOSAKI Motohiro <redacted>
CC: Yasuaki Ishimatsu <redacted>
Signed-off-by: Wen Congyang <redacted>
---
mm/memory_hotplug.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 54 insertions(+), 0 deletions(-)
@@ -1285,6 +1286,57 @@ int offline_memory(u64 start, u64 size)return0;}+staticintcheck_cpu_on_node(void*data)+{+structpglist_data*pgdat=data;+intcpu;++for_each_online_cpu(cpu){+if(cpu_to_node(cpu)==pgdat->node_id)+/*+*thecpuonthisnodeisonlined,andwecan't+*offlinethisnode.+*/+return-EBUSY;+}++return0;+}++/* offline the node if all memory sections of this node are removed */+staticvoidtry_offline_node(intnid)+{+unsignedlongstart_pfn=NODE_DATA(nid)->node_start_pfn;+unsignedlongend_pfn=start_pfn+NODE_DATA(nid)->node_spanned_pages;+unsignedlongpfn;++for(pfn=start_pfn;pfn<end_pfn;pfn+=PAGES_PER_SECTION){+unsignedlongsection_nr=pfn_to_section_nr(pfn);++if(!present_section_nr(section_nr))+continue;++if(pfn_to_nid(pfn)!=nid)+continue;++/*+*somememorysectionsofthisnodearenotremoved,andwe+*can'tofflinenodenow.+*/+return;+}++if(stop_machine(check_cpu_on_node,NODE_DATA(nid),NULL))+return;++/*+*allmemorysectionsofthisnodeareremoved,wecanofflinethis+*nodenow.+*/+node_set_offline(nid);+unregister_one_node(nid);+}+int__refremove_memory(intnid,u64start,u64size){intret=0;
From: Yasuaki Ishimatsu <redacted>
The patch adds __remove_pages() to remove_memory(). Then the range of
phys_start_pfn argument and nr_pages argument in __remove_pagse() may
have different zone. So zone argument is removed from __remove_pages()
and __remove_pages() caluculates zone in each section.
When CONFIG_SPARSEMEM_VMEMMAP is defined, there is no way to remove a memmap.
So __remove_section only calls unregister_memory_section().
CC: David Rientjes <rientjes@google.com>
CC: Jiang Liu <redacted>
CC: Len Brown <redacted>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <redacted>
CC: Christoph Lameter <redacted>
Cc: Minchan Kim <redacted>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: KOSAKI Motohiro <redacted>
CC: Wen Congyang <redacted>
Signed-off-by: Yasuaki Ishimatsu <redacted>
---
arch/powerpc/platforms/pseries/hotplug-memory.c | 5 +----
include/linux/memory_hotplug.h | 3 +--
mm/memory_hotplug.c | 17 ++++++++++-------
3 files changed, 12 insertions(+), 13 deletions(-)
@@ -76,7 +76,6 @@ unsigned long memory_block_size_bytes(void)staticintpseries_remove_memblock(unsignedlongbase,unsignedintmemblock_size){unsignedlongstart,start_pfn;-structzone*zone;inti,ret;intsections_to_remove;
@@ -87,8 +86,6 @@ static int pseries_remove_memblock(unsigned long base, unsigned int memblock_sizreturn0;}-zone=page_zone(pfn_to_page(start_pfn));-/**Removesectionmappingsandsysfsentriesforthe*sectionofthememoryweareremoving.
@@ -101,7 +98,7 @@ static int pseries_remove_memblock(unsigned long base, unsigned int memblock_sizsections_to_remove=(memblock_size>>PAGE_SHIFT)/PAGES_PER_SECTION;for(i=0;i<sections_to_remove;i++){unsignedlongpfn=start_pfn+i*PAGES_PER_SECTION;-ret=__remove_pages(zone,start_pfn,PAGES_PER_SECTION);+ret=__remove_pages(start_pfn,PAGES_PER_SECTION);if(ret)returnret;}
@@ -90,8 +90,7 @@ extern bool is_pageblock_removable_nolock(struct page *page);/* reasonably generic interface to expand the physical pages in a zone */externint__add_pages(intnid,structzone*zone,unsignedlongstart_pfn,unsignedlongnr_pages);-externint__remove_pages(structzone*zone,unsignedlongstart_pfn,-unsignedlongnr_pages);+externint__remove_pages(unsignedlongstart_pfn,unsignedlongnr_pages);#ifdef CONFIG_NUMAexternintmemory_add_physaddr_to_nid(u64start);
@@ -363,6 +365,7 @@ int __remove_pages(struct zone *zone, unsigned long phys_start_pfn,sections_to_remove=nr_pages/PAGES_PER_SECTION;for(i=0;i<sections_to_remove;i++){unsignedlongpfn=phys_start_pfn+i*PAGES_PER_SECTION;+structzone*zone=page_zone(pfn_to_page(pfn));ret=__remove_section(zone,__pfn_to_section(pfn));if(ret)break;
From: Wen Congyang <redacted>
We don't call __add_pages() directly in the function add_memory()
because some other architecture related things need to be done
before or after calling __add_pages(). So we should introduce
a new function arch_remove_memory() to revert the things
done in arch_add_memory().
Note: the function for s390 is not implemented(I don't know how to
implement it for s390).
CC: David Rientjes <rientjes@google.com>
CC: Jiang Liu <redacted>
CC: Len Brown <redacted>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <redacted>
CC: Christoph Lameter <redacted>
Cc: Minchan Kim <redacted>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: KOSAKI Motohiro <redacted>
CC: Yasuaki Ishimatsu <redacted>
Signed-off-by: Wen Congyang <redacted>
---
arch/ia64/mm/init.c | 16 ++++
arch/powerpc/mm/mem.c | 14 +++
arch/s390/mm/init.c | 12 +++
arch/sh/mm/init.c | 15 +++
arch/tile/mm/init.c | 8 ++
arch/x86/include/asm/pgtable_types.h | 1 +
arch/x86/mm/init_32.c | 10 ++
arch/x86/mm/init_64.c | 160 ++++++++++++++++++++++++++++++++++
arch/x86/mm/pageattr.c | 47 +++++-----
include/linux/memory_hotplug.h | 1 +
mm/memory_hotplug.c | 1 +
11 files changed, 263 insertions(+), 22 deletions(-)
@@ -85,6 +85,7 @@ extern void __online_page_free(struct page *page);#ifdef CONFIG_MEMORY_HOTREMOVEexternboolis_pageblock_removable_nolock(structpage*page);+externintarch_remove_memory(u64start,u64size);#endif /* CONFIG_MEMORY_HOTREMOVE *//* reasonably generic interface to expand the physical pages in a zone */
From: Yasuaki Ishimatsu <redacted>
All pages of virtual mapping in removed memory cannot be freed, since some pages
used as PGD/PUD includes not only removed memory but also other memory. So the
patch checks whether page can be freed or not.
How to check whether page can be freed or not?
1. When removing memory, the page structs of the revmoved memory are filled
with 0FD.
2. All page structs are filled with 0xFD on PT/PMD, PT/PMD can be cleared.
In this case, the page used as PT/PMD can be freed.
Applying patch, __remove_section() of CONFIG_SPARSEMEM_VMEMMAP is integrated
into one. So __remove_section() of CONFIG_SPARSEMEM_VMEMMAP is deleted.
Note: vmemmap_kfree() and vmemmap_free_bootmem() are not implemented for ia64,
ppc, s390, and sparc.
CC: David Rientjes <rientjes@google.com>
CC: Jiang Liu <redacted>
CC: Len Brown <redacted>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <redacted>
CC: Christoph Lameter <redacted>
Cc: Minchan Kim <redacted>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: KOSAKI Motohiro <redacted>
CC: Wen Congyang <redacted>
Signed-off-by: Yasuaki Ishimatsu <redacted>
---
arch/ia64/mm/discontig.c | 8 +++
arch/powerpc/mm/init_64.c | 8 +++
arch/s390/mm/vmem.c | 8 +++
arch/sparc/mm/init_64.c | 8 +++
arch/x86/mm/init_64.c | 119 +++++++++++++++++++++++++++++++++++++++++++++
include/linux/mm.h | 2 +
mm/memory_hotplug.c | 17 +------
mm/sparse.c | 5 +-
8 files changed, 158 insertions(+), 17 deletions(-)
@@ -1620,6 +1620,8 @@ int vmemmap_populate(struct page *start_page, unsigned long pages, int node);voidvmemmap_populate_print_last(void);voidregister_page_bootmem_memmap(unsignedlongsection_nr,structpage*map,unsignedlongsize);+voidvmemmap_kfree(structpage*memmpa,unsignedlongnr_pages);+voidvmemmap_free_bootmem(structpage*memmpa,unsignedlongnr_pages);enummf_flags{MF_COUNT_INCREASED=1<<0,
@@ -613,12 +613,13 @@ static inline struct page *kmalloc_section_memmap(unsigned long pnum, int nid,/* This will make the necessary allocations eventually. */returnsparse_mem_map_populate(pnum,nid);}-staticvoid__kfree_section_memmap(structpage*memmap,unsignedlongnr_pages)+staticvoid__kfree_section_memmap(structpage*page,unsignedlongnr_pages){-return;/* XXX: Not implemented yet */+vmemmap_kfree(page,nr_pages);}staticvoidfree_map_bootmem(structpage*page,unsignedlongnr_pages){+vmemmap_free_bootmem(page,nr_pages);}#elsestaticstructpage*__kmalloc_section_memmap(unsignedlongnr_pages)
From: Yasuaki Ishimatsu <redacted>
When a memory is added, we update zone's and pgdat's start_pfn and spanned_pages
in the function __add_zone(). So we should revert these when the memory is
removed. Add a new function __remove_zone() to do this.
CC: David Rientjes <rientjes@google.com>
CC: Jiang Liu <redacted>
CC: Len Brown <redacted>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <redacted>
CC: Christoph Lameter <redacted>
Cc: Minchan Kim <redacted>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: KOSAKI Motohiro <redacted>
Signed-off-by: Yasuaki Ishimatsu <redacted>
Signed-off-by: Wen Congyang <redacted>
---
mm/memory_hotplug.c | 207 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 207 insertions(+), 0 deletions(-)
@@ -308,10 +308,213 @@ static int __meminit __add_section(int nid, struct zone *zone,returnregister_new_memory(nid,__pfn_to_section(phys_start_pfn));}+/* find the smallest valid pfn in the range [start_pfn, end_pfn) */+staticintfind_smallest_section_pfn(intnid,structzone*zone,+unsignedlongstart_pfn,+unsignedlongend_pfn)+{+structmem_section*ms;++for(;start_pfn<end_pfn;start_pfn+=PAGES_PER_SECTION){+ms=__pfn_to_section(start_pfn);++if(unlikely(!valid_section(ms)))+continue;++if(unlikely(pfn_to_nid(start_pfn))!=nid)+continue;++if(zone&&zone!=page_zone(pfn_to_page(start_pfn)))+continue;++returnstart_pfn;+}++return0;+}++/* find the biggest valid pfn in the range [start_pfn, end_pfn). */+staticintfind_biggest_section_pfn(intnid,structzone*zone,+unsignedlongstart_pfn,+unsignedlongend_pfn)+{+structmem_section*ms;+unsignedlongpfn;++/* pfn is the end pfn of a memory section. */+pfn=end_pfn-1;+for(;pfn>=start_pfn;pfn-=PAGES_PER_SECTION){+ms=__pfn_to_section(pfn);++if(unlikely(!valid_section(ms)))+continue;++if(unlikely(pfn_to_nid(pfn))!=nid)+continue;++if(zone&&zone!=page_zone(pfn_to_page(pfn)))+continue;++returnpfn;+}++return0;+}++staticvoidshrink_zone_span(structzone*zone,unsignedlongstart_pfn,+unsignedlongend_pfn)+{+unsignedlongzone_start_pfn=zone->zone_start_pfn;+unsignedlongzone_end_pfn=zone->zone_start_pfn+zone->spanned_pages;+unsignedlongpfn;+structmem_section*ms;+intnid=zone_to_nid(zone);++zone_span_writelock(zone);+if(zone_start_pfn==start_pfn){+/*+*Ifthesectionissmallestsectioninthezone,itneed+*shrinkzone->zone_start_pfnandzone->zone_spanned_pages.+*Inthiscase,wefindsecondsmallestvalidmem_section+*forshrinkingzone.+*/+pfn=find_smallest_section_pfn(nid,zone,end_pfn,+zone_end_pfn);+if(pfn){+zone->zone_start_pfn=pfn;+zone->spanned_pages=zone_end_pfn-pfn;+}+}elseif(zone_end_pfn==end_pfn){+/*+*Ifthesectionisbiggestsectioninthezone,itneed+*shrinkzone->spanned_pages.+*Inthiscase,wefindsecondbiggestvalidmem_sectionfor+*shrinkingzone.+*/+pfn=find_biggest_section_pfn(nid,zone,zone_start_pfn,+start_pfn);+if(pfn)+zone->spanned_pages=pfn-zone_start_pfn+1;+}++/*+*Thesectionisnotbiggestorsmallestmem_sectioninthezone,it+*onlycreatesaholeinthezone.Sointhiscase,weneednot+*changethezone.Butperhaps,thezonehasonlyholedata.Thus+*itcheckthezonehasonlyholeornot.+*/+pfn=zone_start_pfn;+for(;pfn<zone_end_pfn;pfn+=PAGES_PER_SECTION){+ms=__pfn_to_section(pfn);++if(unlikely(!valid_section(ms)))+continue;++if(page_zone(pfn_to_page(pfn))!=zone)+continue;++/* If the section is current section, it continues the loop */+if(start_pfn==pfn)+continue;++/* If we find valid section, we have nothing to do */+zone_span_writeunlock(zone);+return;+}++/* The zone has no valid section */+zone->zone_start_pfn=0;+zone->spanned_pages=0;+zone_span_writeunlock(zone);+}++staticvoidshrink_pgdat_span(structpglist_data*pgdat,+unsignedlongstart_pfn,unsignedlongend_pfn)+{+unsignedlongpgdat_start_pfn=pgdat->node_start_pfn;+unsignedlongpgdat_end_pfn=+pgdat->node_start_pfn+pgdat->node_spanned_pages;+unsignedlongpfn;+structmem_section*ms;+intnid=pgdat->node_id;++if(pgdat_start_pfn==start_pfn){+/*+*Ifthesectionissmallestsectioninthepgdat,itneed+*shrinkpgdat->node_start_pfnandpgdat->node_spanned_pages.+*Inthiscase,wefindsecondsmallestvalidmem_section+*forshrinkingzone.+*/+pfn=find_smallest_section_pfn(nid,NULL,end_pfn,+pgdat_end_pfn);+if(pfn){+pgdat->node_start_pfn=pfn;+pgdat->node_spanned_pages=pgdat_end_pfn-pfn;+}+}elseif(pgdat_end_pfn==end_pfn){+/*+*Ifthesectionisbiggestsectioninthepgdat,itneed+*shrinkpgdat->node_spanned_pages.+*Inthiscase,wefindsecondbiggestvalidmem_sectionfor+*shrinkingzone.+*/+pfn=find_biggest_section_pfn(nid,NULL,pgdat_start_pfn,+start_pfn);+if(pfn)+pgdat->node_spanned_pages=pfn-pgdat_start_pfn+1;+}++/*+*Ifthesectionisnotbiggestorsmallestmem_sectioninthepgdat,+*itonlycreatesaholeinthepgdat.Sointhiscase,weneednot+*changethepgdat.+*Butperhaps,thepgdathasonlyholedata.Thusitcheckthepgdat+*hasonlyholeornot.+*/+pfn=pgdat_start_pfn;+for(;pfn<pgdat_end_pfn;pfn+=PAGES_PER_SECTION){+ms=__pfn_to_section(pfn);++if(unlikely(!valid_section(ms)))+continue;++if(pfn_to_nid(pfn)!=nid)+continue;++/* If the section is current section, it continues the loop */+if(start_pfn==pfn)+continue;++/* If we find valid section, we have nothing to do */+return;+}++/* The pgdat has no valid section */+pgdat->node_start_pfn=0;+pgdat->node_spanned_pages=0;+}++staticvoid__remove_zone(structzone*zone,unsignedlongstart_pfn)+{+structpglist_data*pgdat=zone->zone_pgdat;+intnr_pages=PAGES_PER_SECTION;+intzone_type;+unsignedlongflags;++zone_type=zone-pgdat->node_zones;++pgdat_resize_lock(zone->zone_pgdat,&flags);+shrink_zone_span(zone,start_pfn,start_pfn+nr_pages);+shrink_pgdat_span(pgdat,start_pfn,start_pfn+nr_pages);+pgdat_resize_unlock(zone->zone_pgdat,&flags);+}+staticint__remove_section(structzone*zone,structmem_section*ms){unsignedlongflags;structpglist_data*pgdat=zone->zone_pgdat;+unsignedlongstart_pfn;+intscn_nr;intret=-EINVAL;if(!valid_section(ms))
@@ -321,6 +524,10 @@ static int __remove_section(struct zone *zone, struct mem_section *ms)if(ret)returnret;+scn_nr=__section_nr(ms);+start_pfn=section_nr_to_pfn(scn_nr);+__remove_zone(zone,start_pfn);+pgdat_resize_lock(pgdat,&flags);sparse_remove_one_section(zone,ms);pgdat_resize_unlock(pgdat,&flags);
From: Yasuaki Ishimatsu <redacted>
When calling unregister_node(), the function shows following message at
device_release().
Device 'node2' does not have a release() function, it is broken and must be
fixed.
So the patch implements node_device_release()
CC: David Rientjes <rientjes@google.com>
CC: Jiang Liu <redacted>
CC: Len Brown <redacted>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <redacted>
CC: Christoph Lameter <redacted>
Cc: Minchan Kim <redacted>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: KOSAKI Motohiro <redacted>
Signed-off-by: Yasuaki Ishimatsu <redacted>
Signed-off-by: Wen Congyang <redacted>
---
drivers/base/node.c | 11 +++++++++++
1 files changed, 11 insertions(+), 0 deletions(-)
From: Wen Congyang <redacted>
hwpoisoned may set when we offline a page by the sysfs interface
/sys/devices/system/memory/soft_offline_page or
/sys/devices/system/memory/hard_offline_page. If we don't clear
this flag when onlining pages, this page can't be freed, and will
not in free list. So we can't offline these pages again. So we
should clear this flag when onlining pages.
CC: David Rientjes <rientjes@google.com>
CC: Jiang Liu <redacted>
CC: Len Brown <redacted>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <redacted>
CC: Christoph Lameter <redacted>
Cc: Minchan Kim <redacted>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: KOSAKI Motohiro <redacted>
CC: Yasuaki Ishimatsu <redacted>
Signed-off-by: Wen Congyang <redacted>
---
mm/memory_hotplug.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
@@ -661,6 +661,11 @@ EXPORT_SYMBOL_GPL(__online_page_increment_counters);void__online_page_free(structpage*page){+#ifdef CONFIG_MEMORY_FAILURE+/* The page may be marked HWPoisoned by soft/hard offline page */+ClearPageHWPoison(page);
Hi Congyang,
I think you should decrease mce_bad_pages counter her
atomic_long_sub(1, &mce_bad_pages);
+#endif
+
ClearPageReserved(page);
init_page_count(page);
__free_page(page);
--
1.7.1
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
At 09/06/2012 03:27 PM, andywu106=E5=BB=BA=E5=9B=BD Wrote:
2012/9/5 [off-list ref]
quoted
From: Wen Congyang <redacted>
hwpoisoned may set when we offline a page by the sysfs interface
/sys/devices/system/memory/soft=5Foffline=5Fpage or
/sys/devices/system/memory/hard=5Foffline=5Fpage. If we don't clear
this flag when onlining pages, this page can't be freed, and will
not in free list. So we can't offline these pages again. So we
should clear this flag when onlining pages.
CC: David Rientjes <rientjes@google.com>
CC: Jiang Liu <redacted>
CC: Len Brown <redacted>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <redacted>
CC: Christoph Lameter <redacted>
Cc: Minchan Kim <redacted>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: KOSAKI Motohiro <redacted>
CC: Yasuaki Ishimatsu <redacted>
Signed-off-by: Wen Congyang <redacted>
---
mm/memory=5Fhotplug.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
void =5F=5Fonline=5Fpage=5Ffree(struct page *page)
{
+#ifdef CONFIG=5FMEMORY=5FFAILURE
+ /* The page may be marked HWPoisoned by soft/hard offline page */
+ ClearPageHWPoison(page);
=20
Hi Congyang,
I think you should decrease mce=5Fbad=5Fpages counter her
atomic=5Flong=5Fsub(1, &mce=5Fbad=5Fpages);
Yes, thanks for pointing it out.
Thanks
Wen Congyang
=20
quoted
+#endif
+
ClearPageReserved(page);
init=5Fpage=5Fcount(page);
=5F=5Ffree=5Fpage(page);
--
1.7.1
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=3Dmailto:"dont@kvack.org"> email@kvack.org </a>
Hi, ishimatsu
At 09/05/2012 05:25 PM, wency@cn.fujitsu.com Wrote:
quoted
From: Yasuaki Ishimatsu <redacted>
If system supports memory hot-remove, online_pages() may online removed pages.
So online_pages() need to check whether onlining pages are present or not.
Because we use memory_block_change_state() to hotremoving memory, I think
this patch can be removed. What do you think?
Pleae teach me detals a little more. If we use memory_block_change_state(),
does the conflict never occur? Why?
Thansk,
Yasuaki Ishimatsu
Thanks
Wen Congyang
quoted
CC: David Rientjes <rientjes@google.com>
CC: Jiang Liu <redacted>
CC: Len Brown <redacted>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <redacted>
CC: Christoph Lameter <redacted>
Cc: Minchan Kim <redacted>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: KOSAKI Motohiro <redacted>
CC: Wen Congyang <redacted>
Signed-off-by: Yasuaki Ishimatsu <redacted>
---
include/linux/mmzone.h | 19 +++++++++++++++++++
mm/memory_hotplug.c | 13 +++++++++++++
2 files changed, 32 insertions(+), 0 deletions(-)
@@ -467,6 +467,19 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages)structmemory_notifyarg;lock_memory_hotplug();+/*+*Ifsystemsupportsmemoryhot-remove,thememorymayhavebeen+*removed.Sowecheckwhetherthememoryhasbeenremovedornot.+*+*Note:WhenCONFIG_SPARSEMEMisdefined,pfns_present()become+*effective.IfCONFIG_SPARSEMEMisnotdefined,pfns_present()+*alwaysreturns0.+*/+ret=pfns_present(pfn,nr_pages);+if(ret){+unlock_memory_hotplug();+returnret;+}arg.start_pfn=pfn;arg.nr_pages=nr_pages;arg.status_change_nid=-1;
Hi, ishimatsu
At 09/05/2012 05:25 PM, wency@cn.fujitsu.com Wrote:
quoted
From: Yasuaki Ishimatsu <redacted>
If system supports memory hot-remove, online_pages() may online
removed pages.
So online_pages() need to check whether onlining pages are present or
not.
Because we use memory_block_change_state() to hotremoving memory, I think
this patch can be removed. What do you think?
Pleae teach me detals a little more. If we use memory_block_change_state(),
does the conflict never occur? Why?
I misunderstand sth, please ignore it.
Wen Congyang
Thansk,
Yasuaki Ishimatsu
quoted
Thanks
Wen Congyang
quoted
CC: David Rientjes <rientjes@google.com>
CC: Jiang Liu <redacted>
CC: Len Brown <redacted>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <redacted>
CC: Christoph Lameter <redacted>
Cc: Minchan Kim <redacted>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: KOSAKI Motohiro <redacted>
CC: Wen Congyang <redacted>
Signed-off-by: Yasuaki Ishimatsu <redacted>
---
include/linux/mmzone.h | 19 +++++++++++++++++++
mm/memory_hotplug.c | 13 +++++++++++++
2 files changed, 32 insertions(+), 0 deletions(-)
@@ -467,6 +467,19 @@ int __ref online_pages(unsigned long pfn,
unsigned long nr_pages)
struct memory_notify arg;
lock_memory_hotplug();
+ /*
+ * If system supports memory hot-remove, the memory may have been
+ * removed. So we check whether the memory has been removed or not.
+ *
+ * Note: When CONFIG_SPARSEMEM is defined, pfns_present() become
+ * effective. If CONFIG_SPARSEMEM is not defined,
pfns_present()
+ * always returns 0.
+ */
+ ret = pfns_present(pfn, nr_pages);
+ if (ret) {
+ unlock_memory_hotplug();
+ return ret;
+ }
arg.start_pfn = pfn;
arg.nr_pages = nr_pages;
arg.status_change_nid = -1;
Hi, ishimatsu
At 09/05/2012 05:25 PM, wency@cn.fujitsu.com Wrote:
From: Yasuaki Ishimatsu <redacted>
If system supports memory hot-remove, online_pages() may online removed pages.
So online_pages() need to check whether onlining pages are present or not.
Because we use memory_block_change_state() to hotremoving memory, I think
this patch can be removed. What do you think?
Thanks
Wen Congyang
quoted hunk
CC: David Rientjes <rientjes@google.com>
CC: Jiang Liu <redacted>
CC: Len Brown <redacted>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <redacted>
CC: Christoph Lameter <redacted>
Cc: Minchan Kim <redacted>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: KOSAKI Motohiro <redacted>
CC: Wen Congyang <redacted>
Signed-off-by: Yasuaki Ishimatsu <redacted>
---
include/linux/mmzone.h | 19 +++++++++++++++++++
mm/memory_hotplug.c | 13 +++++++++++++
2 files changed, 32 insertions(+), 0 deletions(-)
@@ -467,6 +467,19 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages)structmemory_notifyarg;lock_memory_hotplug();+/*+*Ifsystemsupportsmemoryhot-remove,thememorymayhavebeen+*removed.Sowecheckwhetherthememoryhasbeenremovedornot.+*+*Note:WhenCONFIG_SPARSEMEMisdefined,pfns_present()become+*effective.IfCONFIG_SPARSEMEMisnotdefined,pfns_present()+*alwaysreturns0.+*/+ret=pfns_present(pfn,nr_pages);+if(ret){+unlock_memory_hotplug();+returnret;+}arg.start_pfn=pfn;arg.nr_pages=nr_pages;arg.status_change_nid=-1;
At 09/27/2012 12:58 AM, Vasilis Liaskovitis Wrote:
Testing 3.6.0-rc7 with this v9 patchset plus more recent fixes [1],[2],[3]
Running in a guest (qemu+seabios from [4]).
CONFIG_SLAB=y
CONFIG_DEBUG_SLAB=y
- succesfull hot-add and online
- succesfull hot-remove with SCI (qemu) eject
- attempt to hot-readd same memory
When the pages are re-onlined on hot-readd, I get a bad_page state for many
pages e.g.
Can you provide your config file?
Thanks
Wen Congyang
[ 59.611278] init_memory_mapping: [mem 0x80000000-0x9fffffff]
[ 59.637836] Built 2 zonelists in Node order, mobility grouping on. Total pages: 547617
[ 59.638739] Policy zone: Normal
[ 59.650840] BUG: Bad page state in process bash pfn:9b6dc
[ 59.651124] page:ffffea0002200020 count:0 mapcount:0 mapping: (null) index:0xfdfdfdfdfdfdfdfd
[ 59.651494] page flags: 0x2fdfdfdfd5df9fd(locked|referenced|uptodate|dirty|lru|active|slab|owner_priv_1|private|private_2|writeback|head|tail|swapcache|reclaim|swapbacked|unevictable|uncached|compound_lock)
[ 59.653604] Modules linked in: netconsole acpiphp pci_hotplug acpi_memhotplug loop kvm_amd kvm microcode tpm_tis tpm tpm_bios evdev psmouse serio_raw i2c_piix4 i2c_core parport_pc parport processor button thermal_sys ext3 jbd mbcache sg sr_mod cdrom ata_generic virtio_net ata_piix virtio_blk libata virtio_pci virtio_ring virtio scsi_mod
[ 59.656998] Pid: 988, comm: bash Not tainted 3.6.0-rc7-guest #12
[ 59.657172] Call Trace:
[ 59.657275] [<ffffffff810e9b30>] ? bad_page+0xb0/0x100
[ 59.657434] [<ffffffff810ea4c3>] ? free_pages_prepare+0xb3/0x100
[ 59.657610] [<ffffffff810ea668>] ? free_hot_cold_page+0x48/0x1a0
[ 59.657787] [<ffffffff8112cc08>] ? online_pages_range+0x68/0xa0
[ 59.657961] [<ffffffff8112cba0>] ? __online_page_increment_counters+0x10/0x10
[ 59.658162] [<ffffffff81045561>] ? walk_system_ram_range+0x101/0x110
[ 59.658346] [<ffffffff814c4f95>] ? online_pages+0x1a5/0x2b0
[ 59.658515] [<ffffffff8135663d>] ? __memory_block_change_state+0x20d/0x270
[ 59.658710] [<ffffffff81356756>] ? store_mem_state+0xb6/0xf0
[ 59.658878] [<ffffffff8119e482>] ? sysfs_write_file+0xd2/0x160
[ 59.659052] [<ffffffff8113769a>] ? vfs_write+0xaa/0x160
[ 59.659212] [<ffffffff81137977>] ? sys_write+0x47/0x90
[ 59.659371] [<ffffffff814e2f25>] ? async_page_fault+0x25/0x30
[ 59.659543] [<ffffffff814ea239>] ? system_call_fastpath+0x16/0x1b
[ 59.659720] Disabling lock debugging due to kernel taint
Patch 20/21 deals with a similar scenario, but only for __PG_HWPOISON flag.
Did i miss any other patch for this?
thanks,
- Vasilis
[1] https://lkml.org/lkml/2012/9/6/635
[2] https://lkml.org/lkml/2012/9/11/542
[3] https://lkml.org/lkml/2012/9/20/37
[4] http://permalink.gmane.org/gmane.comp.emulators.kvm.devel/98691
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Hi Vasilis Liaskovitis
At 09/27/2012 12:46 AM, Vasilis Liaskovitis Wrote:
Hi,
I am testing 3.6.0-rc7 with this v9 patchset plus more recent fixes [1],[2],[3]
Running in a guest (qemu+seabios from [4]).
CONFIG_SLAB=y
CONFIG_DEBUG_SLAB=y
After succesfull hot-add and online, I am doing a hot-remove with "echo 1 > /sys/bus/acpi/devices/PNP/eject"
When I do the OSPM-eject, I often get slab corruption in "acpi-state" cache, or in other caches
I can't reproduce this problem. Can you provide the following information:
1. config file
2. qemu's command line
You said you did OSPM-eject. Do you mean write 1 to /sys/bus/acpi/devices/PNP0C80:XX/eject?
Thanks
Wen Congyang
At 09/27/2012 12:58 AM, Vasilis Liaskovitis Wrote:
Testing 3.6.0-rc7 with this v9 patchset plus more recent fixes [1],[2],[3]
Running in a guest (qemu+seabios from [4]).
CONFIG_SLAB=y
CONFIG_DEBUG_SLAB=y
- succesfull hot-add and online
- succesfull hot-remove with SCI (qemu) eject
- attempt to hot-readd same memory
When the pages are re-onlined on hot-readd, I get a bad_page state for many
pages e.g.
I have reproduced this problem, and I investigate it now.
Thanks
Wen Congyang
[ 59.611278] init_memory_mapping: [mem 0x80000000-0x9fffffff]
[ 59.637836] Built 2 zonelists in Node order, mobility grouping on. Total pages: 547617
[ 59.638739] Policy zone: Normal
[ 59.650840] BUG: Bad page state in process bash pfn:9b6dc
[ 59.651124] page:ffffea0002200020 count:0 mapcount:0 mapping: (null) index:0xfdfdfdfdfdfdfdfd
[ 59.651494] page flags: 0x2fdfdfdfd5df9fd(locked|referenced|uptodate|dirty|lru|active|slab|owner_priv_1|private|private_2|writeback|head|tail|swapcache|reclaim|swapbacked|unevictable|uncached|compound_lock)
[ 59.653604] Modules linked in: netconsole acpiphp pci_hotplug acpi_memhotplug loop kvm_amd kvm microcode tpm_tis tpm tpm_bios evdev psmouse serio_raw i2c_piix4 i2c_core parport_pc parport processor button thermal_sys ext3 jbd mbcache sg sr_mod cdrom ata_generic virtio_net ata_piix virtio_blk libata virtio_pci virtio_ring virtio scsi_mod
[ 59.656998] Pid: 988, comm: bash Not tainted 3.6.0-rc7-guest #12
[ 59.657172] Call Trace:
[ 59.657275] [<ffffffff810e9b30>] ? bad_page+0xb0/0x100
[ 59.657434] [<ffffffff810ea4c3>] ? free_pages_prepare+0xb3/0x100
[ 59.657610] [<ffffffff810ea668>] ? free_hot_cold_page+0x48/0x1a0
[ 59.657787] [<ffffffff8112cc08>] ? online_pages_range+0x68/0xa0
[ 59.657961] [<ffffffff8112cba0>] ? __online_page_increment_counters+0x10/0x10
[ 59.658162] [<ffffffff81045561>] ? walk_system_ram_range+0x101/0x110
[ 59.658346] [<ffffffff814c4f95>] ? online_pages+0x1a5/0x2b0
[ 59.658515] [<ffffffff8135663d>] ? __memory_block_change_state+0x20d/0x270
[ 59.658710] [<ffffffff81356756>] ? store_mem_state+0xb6/0xf0
[ 59.658878] [<ffffffff8119e482>] ? sysfs_write_file+0xd2/0x160
[ 59.659052] [<ffffffff8113769a>] ? vfs_write+0xaa/0x160
[ 59.659212] [<ffffffff81137977>] ? sys_write+0x47/0x90
[ 59.659371] [<ffffffff814e2f25>] ? async_page_fault+0x25/0x30
[ 59.659543] [<ffffffff814ea239>] ? system_call_fastpath+0x16/0x1b
[ 59.659720] Disabling lock debugging due to kernel taint
Patch 20/21 deals with a similar scenario, but only for __PG_HWPOISON flag.
Did i miss any other patch for this?
thanks,
- Vasilis
[1] https://lkml.org/lkml/2012/9/6/635
[2] https://lkml.org/lkml/2012/9/11/542
[3] https://lkml.org/lkml/2012/9/20/37
[4] http://permalink.gmane.org/gmane.comp.emulators.kvm.devel/98691
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
@@ -639,7 +639,6 @@ static struct page *__kmalloc_section_memmap(unsigned long nr_pages)got_map_page:ret=(structpage*)pfn_to_kaddr(page_to_pfn(page));got_map_ptr:-memset(ret,0,memmap_size);returnret;}
@@ -761,6 +760,8 @@ int __meminit sparse_add_one_section(struct zone *zone, unsigned long start_pfn,gotoout;}+memset(memmap,0,sizeof(structpage)*nr_pages);+ms->section_mem_map|=SECTION_MARKED_PRESENT;ret=sparse_init_one_section(ms,section_nr,memmap,usemap);
On Thu, Sep 27, 2012 at 02:37:14PM +0800, Wen Congyang wrote:
Hi Vasilis Liaskovitis
At 09/27/2012 12:46 AM, Vasilis Liaskovitis Wrote:
quoted
Hi,
I am testing 3.6.0-rc7 with this v9 patchset plus more recent fixes [1],[2],[3]
Running in a guest (qemu+seabios from [4]).
CONFIG_SLAB=y
CONFIG_DEBUG_SLAB=y
After succesfull hot-add and online, I am doing a hot-remove with "echo 1 > /sys/bus/acpi/devices/PNP/eject"
When I do the OSPM-eject, I often get slab corruption in "acpi-state" cache, or in other caches
I can't reproduce this problem. Can you provide the following information:
1. config file
2. qemu's command line
You said you did OSPM-eject. Do you mean write 1 to /sys/bus/acpi/devices/PNP0C80:XX/eject?
yes.
example qemu command line with one dimm:
"/opt/qemu-kvm-memhp/bin/qemu-system-x86_64 -bios
/opt/extra/vliaskov/devel/seabios-upstream/out/bios.bin -enable-kvm -M pc -smp
4,maxcpus=8 -cpu host -m 2048 -drive file=/opt/extra/debian-template.raw,if=none,id=drive-virtio-disk0,format=raw
-device virtio-blk-pci,bus=pci.0,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1
-vga cirrus -netdev type=tap,id=guest0,vhost=on -device virtio-net-pci,netdev=guest0
-monitor unix:/tmp/qemu.monitor11,server,nowait -chardev stdio,id=seabios -device
isa-debugcon,iobase=0x402,chardev=seabios
-dimm id=n0,size=512M,node=0"
or last line with 2 numa nodes:
"-dimm id=n0,size=512M,node=0 -dimm id=n1,size=512M,node=1 -numa node,nodeid=0 -numa node,nodeid=1"
attached config. Tree is at:
https://github.com/vliaskov/linux/commits/memhp-fujitsu
thanks,
- Vasilis
On Thu, Sep 27, 2012 at 06:06:30PM +0800, Wen Congyang wrote:
Please try the following patch:
From a38ec678e0a9b48b252f457d7910b7527049dc43 Mon Sep 17 00:00:00 2001
From: Wen Congyang <redacted>
Date: Thu, 27 Sep 2012 17:27:57 +0800
Subject: [PATCH] clear the memory to store page information
this solves the hot re-add problem for me.
thanks for the quick solution.
- Vasilis
@@ -639,7 +639,6 @@ static struct page *__kmalloc_section_memmap(unsigned long nr_pages)got_map_page:ret=(structpage*)pfn_to_kaddr(page_to_pfn(page));got_map_ptr:-memset(ret,0,memmap_size);returnret;}
@@ -761,6 +760,8 @@ int __meminit sparse_add_one_section(struct zone *zone, unsigned long start_pfn,gotoout;}+memset(memmap,0,sizeof(structpage)*nr_pages);+ms->section_mem_map|=SECTION_MARKED_PRESENT;ret=sparse_init_one_section(ms,section_nr,memmap,usemap);
At 09/27/2012 06:35 PM, Vasilis Liaskovitis Wrote:
On Thu, Sep 27, 2012 at 02:37:14PM +0800, Wen Congyang wrote:
quoted
Hi Vasilis Liaskovitis
At 09/27/2012 12:46 AM, Vasilis Liaskovitis Wrote:
quoted
Hi,
I am testing 3.6.0-rc7 with this v9 patchset plus more recent fixes [1],[2],[3]
Running in a guest (qemu+seabios from [4]).
CONFIG_SLAB=y
CONFIG_DEBUG_SLAB=y
After succesfull hot-add and online, I am doing a hot-remove with "echo 1 > /sys/bus/acpi/devices/PNP/eject"
When I do the OSPM-eject, I often get slab corruption in "acpi-state" cache, or in other caches
I can't reproduce this problem. Can you provide the following information:
1. config file
2. qemu's command line
You said you did OSPM-eject. Do you mean write 1 to /sys/bus/acpi/devices/PNP0C80:XX/eject?
yes.
example qemu command line with one dimm:
"/opt/qemu-kvm-memhp/bin/qemu-system-x86_64 -bios
/opt/extra/vliaskov/devel/seabios-upstream/out/bios.bin -enable-kvm -M pc -smp
4,maxcpus=8 -cpu host -m 2048 -drive file=/opt/extra/debian-template.raw,if=none,id=drive-virtio-disk0,format=raw
-device virtio-blk-pci,bus=pci.0,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1
-vga cirrus -netdev type=tap,id=guest0,vhost=on -device virtio-net-pci,netdev=guest0
-monitor unix:/tmp/qemu.monitor11,server,nowait -chardev stdio,id=seabios -device
isa-debugcon,iobase=0x402,chardev=seabios
-dimm id=n0,size=512M,node=0"
or last line with 2 numa nodes:
"-dimm id=n0,size=512M,node=0 -dimm id=n1,size=512M,node=1 -numa node,nodeid=0 -numa node,nodeid=1"
I have reproduced this problem. It only can be reproduced when the dimm's memory is on node 0.
I investigate it now.
Thanks
Wen Congyang
From: Ni zhan Chen <hidden> Date: 2012-09-28 02:22:43
On 09/05/2012 05:25 PM, wency@cn.fujitsu.com wrote:
From: Yasuaki Ishimatsu <redacted>
remove_memory() only try to offline pages. It is called in two cases:
1. hot remove a memory device
2. echo offline >/sys/devices/system/memory/memoryXX/state
In the 1st case, we should also change memory block's state, and notify
the userspace that the memory block's state is changed after offlining
pages.
So rename remove_memory() to offline_memory()/offline_pages(). And in
the 1st case, offline_memory() will be used. The function offline_memory()
is not implemented. In the 2nd case, offline_pages() will be used.
But this time there is not a function associated with add_memory.
quoted hunk
CC: David Rientjes <rientjes@google.com>
CC: Jiang Liu <redacted>
CC: Len Brown <redacted>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <redacted>
CC: Christoph Lameter <redacted>
Cc: Minchan Kim <redacted>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: KOSAKI Motohiro <redacted>
Signed-off-by: Yasuaki Ishimatsu <redacted>
Signed-off-by: Wen Congyang <redacted>
---
drivers/acpi/acpi_memhotplug.c | 2 +-
drivers/base/memory.c | 9 +++------
include/linux/memory_hotplug.h | 3 ++-
mm/memory_hotplug.c | 22 ++++++++++++++--------
4 files changed, 20 insertions(+), 16 deletions(-)
@@ -233,7 +233,8 @@ static inline int is_mem_section_removable(unsigned long pfn,externintmem_online_node(intnid);externintadd_memory(intnid,u64start,u64size);externintarch_add_memory(intnid,u64start,u64size);-externintremove_memory(u64start,u64size);+externintoffline_pages(unsignedlongstart_pfn,unsignedlongnr_pages);+externintoffline_memory(u64start,u64size);externintsparse_add_one_section(structzone*zone,unsignedlongstart_pfn,intnr_pages);externvoidsparse_remove_one_section(structzone*zone,structmem_section*ms);
@@ -866,7 +866,7 @@ check_pages_isolated(unsigned long start_pfn, unsigned long end_pfn)returnofflined;}-staticint__refoffline_pages(unsignedlongstart_pfn,+staticint__ref__offline_pages(unsignedlongstart_pfn,unsignedlongend_pfn,unsignedlongtimeout){unsignedlongpfn,nr_pages,expire;
From: Ni zhan Chen <hidden> Date: 2012-09-28 03:21:54
On 09/05/2012 05:25 PM, wency@cn.fujitsu.com wrote:
From: Wen Congyang <redacted>
The memory device has only one node id. Store the node id when
enable the memory device, and we can reuse it when removing the
memory device.
one question:
if use numa emulation, memory device will associated to one node or ...?
quoted hunk
CC: David Rientjes <rientjes@google.com>
CC: Jiang Liu <redacted>
CC: Len Brown <redacted>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <redacted>
CC: Christoph Lameter <redacted>
Cc: Minchan Kim <redacted>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: KOSAKI Motohiro <redacted>
CC: Yasuaki Ishimatsu <redacted>
Signed-off-by: Wen Congyang <redacted>
Reviewed-by: Yasuaki Ishimatsu <redacted>
---
drivers/acpi/acpi_memhotplug.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
@@ -83,6 +83,7 @@ struct acpi_memory_info {structacpi_memory_device{structacpi_device*device;unsignedintstate;/* State of the memory device */+intnid;structlist_headres_list;};
@@ -256,6 +257,9 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device)info->enabled=1;num_enabled++;}++mem_device->nid=node;+if(!num_enabled){printk(KERN_ERRPREFIX"add_memory failed\n");mem_device->state=MEMORY_INVALID_STATE;
From: Ni zhan Chen <hidden> Date: 2012-09-28 03:37:42
On 09/11/2012 10:24 AM, Yasuaki Ishimatsu wrote:
Hi Wen,
2012/09/11 11:15, Wen Congyang wrote:
quoted
Hi, ishimatsu
At 09/05/2012 05:25 PM, wency@cn.fujitsu.com Wrote:
quoted
From: Yasuaki Ishimatsu <redacted>
If system supports memory hot-remove, online_pages() may online
removed pages.
So online_pages() need to check whether onlining pages are present
or not.
Because we use memory_block_change_state() to hotremoving memory, I
think
this patch can be removed. What do you think?
Pleae teach me detals a little more. If we use
memory_block_change_state(),
does the conflict never occur? Why?
since memory hot-add or hot-remove is based on memblock, if check in
memory_block_change_state()
can guarantee conflict never occur?
Thansk,
Yasuaki Ishimatsu
quoted
Thanks
Wen Congyang
quoted
CC: David Rientjes <rientjes@google.com>
CC: Jiang Liu <redacted>
CC: Len Brown <redacted>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <redacted>
CC: Christoph Lameter <redacted>
Cc: Minchan Kim <redacted>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: KOSAKI Motohiro <redacted>
CC: Wen Congyang <redacted>
Signed-off-by: Yasuaki Ishimatsu <redacted>
---
include/linux/mmzone.h | 19 +++++++++++++++++++
mm/memory_hotplug.c | 13 +++++++++++++
2 files changed, 32 insertions(+), 0 deletions(-)
@@ -467,6 +467,19 @@ int __ref online_pages(unsigned long pfn,
unsigned long nr_pages)
struct memory_notify arg;
lock_memory_hotplug();
+ /*
+ * If system supports memory hot-remove, the memory may have been
+ * removed. So we check whether the memory has been removed or
not.
+ *
+ * Note: When CONFIG_SPARSEMEM is defined, pfns_present() become
+ * effective. If CONFIG_SPARSEMEM is not defined,
pfns_present()
+ * always returns 0.
+ */
+ ret = pfns_present(pfn, nr_pages);
+ if (ret) {
+ unlock_memory_hotplug();
+ return ret;
+ }
arg.start_pfn = pfn;
arg.nr_pages = nr_pages;
arg.status_change_nid = -1;
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
On 09/05/2012 05:25 PM, wency@cn.fujitsu.com wrote:
quoted
From: Yasuaki Ishimatsu <redacted>
remove_memory() only try to offline pages. It is called in two cases:
1. hot remove a memory device
2. echo offline >/sys/devices/system/memory/memoryXX/state
In the 1st case, we should also change memory block's state, and notify
the userspace that the memory block's state is changed after offlining
pages.
So rename remove_memory() to offline_memory()/offline_pages(). And in
the 1st case, offline_memory() will be used. The function offline_memory()
is not implemented. In the 2nd case, offline_pages() will be used.
But this time there is not a function associated with add_memory.
To associate with add_memory() later, we renamed it.
Thanks,
Yasuaki Ishimatsu
quoted
CC: David Rientjes <rientjes@google.com>
CC: Jiang Liu <redacted>
CC: Len Brown <redacted>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <redacted>
CC: Christoph Lameter <redacted>
Cc: Minchan Kim <redacted>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: KOSAKI Motohiro <redacted>
Signed-off-by: Yasuaki Ishimatsu <redacted>
Signed-off-by: Wen Congyang <redacted>
---
drivers/acpi/acpi_memhotplug.c | 2 +-
drivers/base/memory.c | 9 +++------
include/linux/memory_hotplug.h | 3 ++-
mm/memory_hotplug.c | 22 ++++++++++++++--------
4 files changed, 20 insertions(+), 16 deletions(-)
@@ -233,7 +233,8 @@ static inline int is_mem_section_removable(unsigned long pfn,externintmem_online_node(intnid);externintadd_memory(intnid,u64start,u64size);externintarch_add_memory(intnid,u64start,u64size);-externintremove_memory(u64start,u64size);+externintoffline_pages(unsignedlongstart_pfn,unsignedlongnr_pages);+externintoffline_memory(u64start,u64size);externintsparse_add_one_section(structzone*zone,unsignedlongstart_pfn,intnr_pages);externvoidsparse_remove_one_section(structzone*zone,structmem_section*ms);
@@ -866,7 +866,7 @@ check_pages_isolated(unsigned long start_pfn, unsigned long end_pfn)returnofflined;}-staticint__refoffline_pages(unsignedlongstart_pfn,+staticint__ref__offline_pages(unsignedlongstart_pfn,unsignedlongend_pfn,unsignedlongtimeout){unsignedlongpfn,nr_pages,expire;
From: Ni zhan Chen <hidden> Date: 2012-09-28 04:49:07
On 09/05/2012 05:25 PM, wency@cn.fujitsu.com wrote:
quoted hunk
From: Yasuaki Ishimatsu <redacted>
We should offline and remove memory when removing the memory device.
The memory device can be removed by 2 ways:
1. send eject request by SCI
2. echo 1 >/sys/bus/pci/devices/PNP0C80:XX/eject
In the 1st case, acpi_memory_disable_device() will be called. In the 2nd
case, acpi_memory_device_remove() will be called. acpi_memory_device_remove()
will also be called when we unbind the memory device from the driver
acpi_memhotplug. If the type is ACPI_BUS_REMOVAL_EJECT, it means
that the user wants to eject the memory device, and we should offline
and remove memory in acpi_memory_device_remove().
The function remove_memory() is not implemeted now. It only check whether
all memory has been offllined now.
CC: David Rientjes <rientjes@google.com>
CC: Jiang Liu <redacted>
CC: Len Brown <redacted>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <redacted>
CC: Christoph Lameter <redacted>
Cc: Minchan Kim <redacted>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: KOSAKI Motohiro <redacted>
Signed-off-by: Yasuaki Ishimatsu <redacted>
Signed-off-by: Wen Congyang <redacted>
---
drivers/acpi/acpi_memhotplug.c | 45 +++++++++++++++++++++++++++++++++------
drivers/base/memory.c | 39 ++++++++++++++++++++++++++++++++++
include/linux/memory.h | 5 ++++
include/linux/memory_hotplug.h | 5 ++++
mm/memory_hotplug.c | 22 +++++++++++++++++++
5 files changed, 109 insertions(+), 7 deletions(-)
@@ -310,25 +311,44 @@ static int acpi_memory_powerdown_device(struct acpi_memory_device *mem_device)return0;}-staticintacpi_memory_disable_device(structacpi_memory_device*mem_device)+staticint+acpi_memory_device_remove_memory(structacpi_memory_device*mem_device){intresult;structacpi_memory_info*info,*n;+intnode=mem_device->nid;--/*-*AsktheVMtoofflinethismemoryrange.-*Note:Assumethatthisfunctionreturnszeroonsuccess-*/list_for_each_entry_safe(info,n,&mem_device->res_list,list){if(info->enabled){result=offline_memory(info->start_addr,info->length);if(result)returnresult;++result=remove_memory(node,info->start_addr,+info->length);+if(result)+returnresult;}++list_del(&info->list);kfree(info);}+return0;+}++staticintacpi_memory_disable_device(structacpi_memory_device*mem_device)+{+intresult;++/*+*AsktheVMtoofflinethismemoryrange.+*Note:Assumethatthisfunctionreturnszeroonsuccess+*/+result=acpi_memory_device_remove_memory(mem_device);+if(result)+returnresult;+/* Power-off and eject the device */result=acpi_memory_powerdown_device(mem_device);if(result){
@@ -477,12 +497,23 @@ static int acpi_memory_device_add(struct acpi_device *device)staticintacpi_memory_device_remove(structacpi_device*device,inttype){structacpi_memory_device*mem_device=NULL;-+intresult;if(!device||!acpi_driver_data(device))return-EINVAL;mem_device=acpi_driver_data(device);++if(type==ACPI_BUS_REMOVAL_EJECT){+/*+*offlineandremovememoryonlywhenthememorydeviceis+*ejected.+*/+result=acpi_memory_device_remove_memory(mem_device);+if(result)+returnresult;+}+kfree(mem_device);return0;
@@ -1038,6 +1038,28 @@ int offline_memory(u64 start, u64 size)return0;}++intremove_memory(intnid,u64start,u64size)+{+intret=-EBUSY;+lock_memory_hotplug();+/*+*Thememorymightbecomeonlinebyothertask,evenifyouoffineit.
s/offine/offline
+ * So we check whether the memory has been onlined or not.
+ */
+ if (!is_memblk_offline(start, size)) {
+ pr_warn("memory removing [mem %#010llx-%#010llx] failed, "
+ "because the memmory range is online\n",
+ start, start + size);
+ ret = -EAGAIN;
+ }
+
+ unlock_memory_hotplug();
+ return ret;
+
+}
+EXPORT_SYMBOL_GPL(remove_memory);
+
#else
int offline_pages(unsigned long start, unsigned long size)
{
On Thu, Sep 27, 2012 at 11:50 PM, Yasuaki Ishimatsu
[off-list ref] wrote:
Hi Chen,
2012/09/28 11:22, Ni zhan Chen wrote:
quoted
On 09/05/2012 05:25 PM, wency@cn.fujitsu.com wrote:
quoted
From: Yasuaki Ishimatsu <redacted>
remove_memory() only try to offline pages. It is called in two cases:
1. hot remove a memory device
2. echo offline >/sys/devices/system/memory/memoryXX/state
In the 1st case, we should also change memory block's state, and notify
the userspace that the memory block's state is changed after offlining
pages.
So rename remove_memory() to offline_memory()/offline_pages(). And in
the 1st case, offline_memory() will be used. The function
offline_memory()
is not implemented. In the 2nd case, offline_pages() will be used.
But this time there is not a function associated with add_memory.
To associate with add_memory() later, we renamed it.
Then, you introduced bisect breakage. It is definitely unacceptable.
NAK.
From: Ni zhan Chen <hidden> Date: 2012-09-29 02:16:11
On 09/05/2012 05:25 PM, wency@cn.fujitsu.com wrote:
From: Yasuaki Ishimatsu <redacted>
The function get_page_bootmem() may be called more than one time to the same
page. There is no need to set page's type, private if the function is not
the first time called to the page.
Note: the patch is just optimization and does not fix any problem.
Hi Yasuaki,
this patch is reasonable to me. I have another question associated to
get_page_bootmem(), the question is from another fujitsu guy's patch
changelog [commit : 04753278769f3], the changelog said that:
1) When the memmap of removing section is allocated on other
section by bootmem, it should/can be free.
2) When the memmap of removing section is allocated on the
same section, it shouldn't be freed. Because the section has to be
logical memory offlined already and all pages must be isolated against
page allocater. If it is freed, page allocator may use it which will
be removed physically soon.
but I don't see his patch guarantee 2), it means that his patch doesn't
guarantee the memmap of removing section which is allocated on other
section by bootmem doesn't be freed. Hopefully get your explaination in
details, thanks in advance. :-)
quoted hunk
CC: David Rientjes <rientjes@google.com>
CC: Jiang Liu <redacted>
CC: Len Brown <redacted>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <redacted>
CC: Christoph Lameter <redacted>
Cc: Minchan Kim <redacted>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: KOSAKI Motohiro <redacted>
CC: Wen Congyang <redacted>
Signed-off-by: Yasuaki Ishimatsu <redacted>
---
mm/memory_hotplug.c | 15 +++++++++++----
1 files changed, 11 insertions(+), 4 deletions(-)
From: Ni zhan Chen <hidden> Date: 2012-09-29 03:45:42
On 09/05/2012 05:25 PM, wency@cn.fujitsu.com wrote:
From: Wen Congyang <redacted>
This patch series aims to support physical memory hot-remove.
The patches can free/remove the following things:
- acpi_memory_info : [RFC PATCH 4/19]
- /sys/firmware/memmap/X/{end, start, type} : [RFC PATCH 8/19]
- iomem_resource : [RFC PATCH 9/19]
- mem_section and related sysfs files : [RFC PATCH 10-11, 13-16/19]
- page table of removed memory : [RFC PATCH 12/19]
- node and related sysfs files : [RFC PATCH 18-19/19]
If you find lack of function for physical memory hot-remove, please let me
know.
Since patchset is too big, could you add more patchset changelog to
describe how this patchset works? in order that it is easier to review.
How to test this patchset?
1. apply this patchset and build the kernel. MEMORY_HOTPLUG, MEMORY_HOTREMOVE,
ACPI_HOTPLUG_MEMORY must be selected.
2. load the module acpi_memhotplug
3. hotplug the memory device(it depends on your hardware)
You will see the memory device under the directory /sys/bus/acpi/devices/.
Its name is PNP0C80:XX.
4. online/offline pages provided by this memory device
You can write online/offline to /sys/devices/system/memory/memoryX/state to
online/offline pages provided by this memory device
5. hotremove the memory device
You can hotremove the memory device by the hardware, or writing 1 to
/sys/bus/acpi/devices/PNP0C80:XX/eject.
Note: if the memory provided by the memory device is used by the kernel, it
can't be offlined. It is not a bug.
Known problems:
1. memory can't be offlined when CONFIG_MEMCG is selected.
For example: there is a memory device on node 1. The address range
is [1G, 1.5G). You will find 4 new directories memory8, memory9, memory10,
and memory11 under the directory /sys/devices/system/memory/.
If CONFIG_MEMCG is selected, we will allocate memory to store page cgroup
when we online pages. When we online memory8, the memory stored page cgroup
is not provided by this memory device. But when we online memory9, the memory
stored page cgroup may be provided by memory8. So we can't offline memory8
now. We should offline the memory in the reversed order.
When the memory device is hotremoved, we will auto offline memory provided
by this memory device. But we don't know which memory is onlined first, so
offlining memory may fail. In such case, you should offline the memory by
hand before hotremoving the memory device.
2. hotremoving memory device may cause kernel panicked
This bug will be fixed by Liu Jiang's patch:
https://lkml.org/lkml/2012/7/3/1
change log of v9:
[RFC PATCH v9 8/21]
* add a lock to protect the list map_entries
* add an indicator to firmware_map_entry to remember whether the memory
is allocated from bootmem
[RFC PATCH v9 10/21]
* change the macro to inline function
[RFC PATCH v9 19/21]
* don't offline the node if the cpu on the node is onlined
[RFC PATCH v9 21/21]
* create new patch: auto offline page_cgroup when onlining memory block
failed
change log of v8:
[RFC PATCH v8 17/20]
* Fix problems when one node's range include the other nodes
[RFC PATCH v8 18/20]
* fix building error when CONFIG_MEMORY_HOTPLUG_SPARSE or CONFIG_HUGETLBFS
is not defined.
[RFC PATCH v8 19/20]
* don't offline node when some memory sections are not removed
[RFC PATCH v8 20/20]
* create new patch: clear hwpoisoned flag when onlining pages
change log of v7:
[RFC PATCH v7 4/19]
* do not continue if acpi_memory_device_remove_memory() fails.
[RFC PATCH v7 15/19]
* handle usemap in register_page_bootmem_info_section() too.
change log of v6:
[RFC PATCH v6 12/19]
* fix building error on other archtitectures than x86
[RFC PATCH v6 15-16/19]
* fix building error on other archtitectures than x86
change log of v5:
* merge the patchset to clear page table and the patchset to hot remove
memory(from ishimatsu) to one big patchset.
[RFC PATCH v5 1/19]
* rename remove_memory() to offline_memory()/offline_pages()
[RFC PATCH v5 2/19]
* new patch: implement offline_memory(). This function offlines pages,
update memory block's state, and notify the userspace that the memory
block's state is changed.
[RFC PATCH v5 4/19]
* offline and remove memory in acpi_memory_disable_device() too.
[RFC PATCH v5 17/19]
* new patch: add a new function __remove_zone() to revert the things done
in the function __add_zone().
[RFC PATCH v5 18/19]
* flush work befor reseting node device.
change log of v4:
* remove "memory-hotplug : unify argument of firmware_map_add_early/hotplug"
from the patch series, since the patch is a bugfix. It is being disccussed
on other thread. But for testing the patch series, the patch is needed.
So I added the patch as [PATCH 0/13].
[RFC PATCH v4 2/13]
* check memory is online or not at remove_memory()
* add memory_add_physaddr_to_nid() to acpi_memory_device_remove() for
getting node id
[RFC PATCH v4 3/13]
* create new patch : check memory is online or not at online_pages()
[RFC PATCH v4 4/13]
* add __ref section to remove_memory()
* call firmware_map_remove_entry() before remove_sysfs_fw_map_entry()
[RFC PATCH v4 11/13]
* rewrite register_page_bootmem_memmap() for removing page used as PT/PMD
change log of v3:
* rebase to 3.5.0-rc6
[RFC PATCH v2 2/13]
* remove extra kobject_put()
* The patch was commented by Wen. Wen's comment is
"acpi_memory_device_remove() should ignore a return value of
remove_memory() since caller does not care the return value".
But I did not change it since I think caller should care the
return value. And I am trying to fix it as follow:
https://lkml.org/lkml/2012/7/5/624
[RFC PATCH v2 4/13]
* remove a firmware_memmap_entry allocated by kzmalloc()
change log of v2:
[RFC PATCH v2 2/13]
* check whether memory block is offline or not before calling offline_memory()
* check whether section is valid or not in is_memblk_offline()
* call kobject_put() for each memory_block in is_memblk_offline()
[RFC PATCH v2 3/13]
* unify the end argument of firmware_map_add_early/hotplug
[RFC PATCH v2 4/13]
* add release_firmware_map_entry() for freeing firmware_map_entry
[RFC PATCH v2 6/13]
* add release_memory_block() for freeing memory_block
[RFC PATCH v2 11/13]
* fix wrong arguments of free_pages()
Wen Congyang (8):
memory-hotplug: implement offline_memory()
memory-hotplug: store the node id in acpi_memory_device
memory-hotplug: export the function acpi_bus_remove()
memory-hotplug: call acpi_bus_remove() to remove memory device
memory-hotplug: introduce new function arch_remove_memory()
memory-hotplug: remove sysfs file of node
memory-hotplug: clear hwpoisoned flag when onlining pages
memory-hotplug: auto offline page_cgroup when onlining memory block
failed
Yasuaki Ishimatsu (13):
memory-hotplug: rename remove_memory() to
offline_memory()/offline_pages()
memory-hotplug: offline and remove memory when removing the memory
device
memory-hotplug: check whether memory is present or not
memory-hotplug: remove /sys/firmware/memmap/X sysfs
memory-hotplug: does not release memory region in PAGES_PER_SECTION
chunks
memory-hotplug: add memory_block_release
memory-hotplug: remove_memory calls __remove_pages
memory-hotplug: check page type in get_page_bootmem
memory-hotplug: move register_page_bootmem_info_node and
put_page_bootmem for sparse-vmemmap
memory-hotplug: implement register_page_bootmem_info_section of
sparse-vmemmap
memory-hotplug: free memmap of sparse-vmemmap
memory_hotplug: clear zone when the memory is removed
memory-hotplug: add node_device_release
arch/ia64/mm/discontig.c | 14 +
arch/ia64/mm/init.c | 16 +
arch/powerpc/mm/init_64.c | 14 +
arch/powerpc/mm/mem.c | 14 +
arch/powerpc/platforms/pseries/hotplug-memory.c | 16 +-
arch/s390/mm/init.c | 12 +
arch/s390/mm/vmem.c | 14 +
arch/sh/mm/init.c | 15 +
arch/sparc/mm/init_64.c | 14 +
arch/tile/mm/init.c | 8 +
arch/x86/include/asm/pgtable_types.h | 1 +
arch/x86/mm/init_32.c | 10 +
arch/x86/mm/init_64.c | 331 ++++++++++++++++++
arch/x86/mm/pageattr.c | 47 ++--
drivers/acpi/acpi_memhotplug.c | 54 +++-
drivers/acpi/scan.c | 3 +-
drivers/base/memory.c | 88 ++++-
drivers/base/node.c | 11 +
drivers/firmware/memmap.c | 98 +++++-
include/acpi/acpi_bus.h | 1 +
include/linux/firmware-map.h | 6 +
include/linux/memory.h | 5 +
include/linux/memory_hotplug.h | 25 +-
include/linux/mm.h | 5 +-
include/linux/mmzone.h | 19 +
mm/memory_hotplug.c | 424 +++++++++++++++++++++--
mm/page_cgroup.c | 3 +
mm/sparse.c | 5 +-
28 files changed, 1181 insertions(+), 92 deletions(-)
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
From: Ni zhan Chen <hidden> Date: 2012-09-29 08:19:59
On 09/05/2012 05:25 PM, wency@cn.fujitsu.com wrote:
From: Wen Congyang <redacted>
This patch series aims to support physical memory hot-remove.
The patches can free/remove the following things:
- acpi_memory_info : [RFC PATCH 4/19]
- /sys/firmware/memmap/X/{end, start, type} : [RFC PATCH 8/19]
- iomem_resource : [RFC PATCH 9/19]
- mem_section and related sysfs files : [RFC PATCH 10-11, 13-16/19]
- page table of removed memory : [RFC PATCH 12/19]
- node and related sysfs files : [RFC PATCH 18-19/19]
If you find lack of function for physical memory hot-remove, please let me
know.
How to test this patchset?
1. apply this patchset and build the kernel. MEMORY_HOTPLUG, MEMORY_HOTREMOVE,
ACPI_HOTPLUG_MEMORY must be selected.
2. load the module acpi_memhotplug
Hi Yasuaki,
where is the acpi_memhotplug module?
3. hotplug the memory device(it depends on your hardware)
You will see the memory device under the directory /sys/bus/acpi/devices/.
Its name is PNP0C80:XX.
4. online/offline pages provided by this memory device
You can write online/offline to /sys/devices/system/memory/memoryX/state to
online/offline pages provided by this memory device
5. hotremove the memory device
You can hotremove the memory device by the hardware, or writing 1 to
/sys/bus/acpi/devices/PNP0C80:XX/eject.
Note: if the memory provided by the memory device is used by the kernel, it
can't be offlined. It is not a bug.
Known problems:
1. memory can't be offlined when CONFIG_MEMCG is selected.
For example: there is a memory device on node 1. The address range
is [1G, 1.5G). You will find 4 new directories memory8, memory9, memory10,
and memory11 under the directory /sys/devices/system/memory/.
If CONFIG_MEMCG is selected, we will allocate memory to store page cgroup
when we online pages. When we online memory8, the memory stored page cgroup
is not provided by this memory device. But when we online memory9, the memory
stored page cgroup may be provided by memory8. So we can't offline memory8
now. We should offline the memory in the reversed order.
When the memory device is hotremoved, we will auto offline memory provided
by this memory device. But we don't know which memory is onlined first, so
offlining memory may fail. In such case, you should offline the memory by
hand before hotremoving the memory device.
2. hotremoving memory device may cause kernel panicked
This bug will be fixed by Liu Jiang's patch:
https://lkml.org/lkml/2012/7/3/1
change log of v9:
[RFC PATCH v9 8/21]
* add a lock to protect the list map_entries
* add an indicator to firmware_map_entry to remember whether the memory
is allocated from bootmem
[RFC PATCH v9 10/21]
* change the macro to inline function
[RFC PATCH v9 19/21]
* don't offline the node if the cpu on the node is onlined
[RFC PATCH v9 21/21]
* create new patch: auto offline page_cgroup when onlining memory block
failed
change log of v8:
[RFC PATCH v8 17/20]
* Fix problems when one node's range include the other nodes
[RFC PATCH v8 18/20]
* fix building error when CONFIG_MEMORY_HOTPLUG_SPARSE or CONFIG_HUGETLBFS
is not defined.
[RFC PATCH v8 19/20]
* don't offline node when some memory sections are not removed
[RFC PATCH v8 20/20]
* create new patch: clear hwpoisoned flag when onlining pages
change log of v7:
[RFC PATCH v7 4/19]
* do not continue if acpi_memory_device_remove_memory() fails.
[RFC PATCH v7 15/19]
* handle usemap in register_page_bootmem_info_section() too.
change log of v6:
[RFC PATCH v6 12/19]
* fix building error on other archtitectures than x86
[RFC PATCH v6 15-16/19]
* fix building error on other archtitectures than x86
change log of v5:
* merge the patchset to clear page table and the patchset to hot remove
memory(from ishimatsu) to one big patchset.
[RFC PATCH v5 1/19]
* rename remove_memory() to offline_memory()/offline_pages()
[RFC PATCH v5 2/19]
* new patch: implement offline_memory(). This function offlines pages,
update memory block's state, and notify the userspace that the memory
block's state is changed.
[RFC PATCH v5 4/19]
* offline and remove memory in acpi_memory_disable_device() too.
[RFC PATCH v5 17/19]
* new patch: add a new function __remove_zone() to revert the things done
in the function __add_zone().
[RFC PATCH v5 18/19]
* flush work befor reseting node device.
change log of v4:
* remove "memory-hotplug : unify argument of firmware_map_add_early/hotplug"
from the patch series, since the patch is a bugfix. It is being disccussed
on other thread. But for testing the patch series, the patch is needed.
So I added the patch as [PATCH 0/13].
[RFC PATCH v4 2/13]
* check memory is online or not at remove_memory()
* add memory_add_physaddr_to_nid() to acpi_memory_device_remove() for
getting node id
[RFC PATCH v4 3/13]
* create new patch : check memory is online or not at online_pages()
[RFC PATCH v4 4/13]
* add __ref section to remove_memory()
* call firmware_map_remove_entry() before remove_sysfs_fw_map_entry()
[RFC PATCH v4 11/13]
* rewrite register_page_bootmem_memmap() for removing page used as PT/PMD
change log of v3:
* rebase to 3.5.0-rc6
[RFC PATCH v2 2/13]
* remove extra kobject_put()
* The patch was commented by Wen. Wen's comment is
"acpi_memory_device_remove() should ignore a return value of
remove_memory() since caller does not care the return value".
But I did not change it since I think caller should care the
return value. And I am trying to fix it as follow:
https://lkml.org/lkml/2012/7/5/624
[RFC PATCH v2 4/13]
* remove a firmware_memmap_entry allocated by kzmalloc()
change log of v2:
[RFC PATCH v2 2/13]
* check whether memory block is offline or not before calling offline_memory()
* check whether section is valid or not in is_memblk_offline()
* call kobject_put() for each memory_block in is_memblk_offline()
[RFC PATCH v2 3/13]
* unify the end argument of firmware_map_add_early/hotplug
[RFC PATCH v2 4/13]
* add release_firmware_map_entry() for freeing firmware_map_entry
[RFC PATCH v2 6/13]
* add release_memory_block() for freeing memory_block
[RFC PATCH v2 11/13]
* fix wrong arguments of free_pages()
Wen Congyang (8):
memory-hotplug: implement offline_memory()
memory-hotplug: store the node id in acpi_memory_device
memory-hotplug: export the function acpi_bus_remove()
memory-hotplug: call acpi_bus_remove() to remove memory device
memory-hotplug: introduce new function arch_remove_memory()
memory-hotplug: remove sysfs file of node
memory-hotplug: clear hwpoisoned flag when onlining pages
memory-hotplug: auto offline page_cgroup when onlining memory block
failed
Yasuaki Ishimatsu (13):
memory-hotplug: rename remove_memory() to
offline_memory()/offline_pages()
memory-hotplug: offline and remove memory when removing the memory
device
memory-hotplug: check whether memory is present or not
memory-hotplug: remove /sys/firmware/memmap/X sysfs
memory-hotplug: does not release memory region in PAGES_PER_SECTION
chunks
memory-hotplug: add memory_block_release
memory-hotplug: remove_memory calls __remove_pages
memory-hotplug: check page type in get_page_bootmem
memory-hotplug: move register_page_bootmem_info_node and
put_page_bootmem for sparse-vmemmap
memory-hotplug: implement register_page_bootmem_info_section of
sparse-vmemmap
memory-hotplug: free memmap of sparse-vmemmap
memory_hotplug: clear zone when the memory is removed
memory-hotplug: add node_device_release
arch/ia64/mm/discontig.c | 14 +
arch/ia64/mm/init.c | 16 +
arch/powerpc/mm/init_64.c | 14 +
arch/powerpc/mm/mem.c | 14 +
arch/powerpc/platforms/pseries/hotplug-memory.c | 16 +-
arch/s390/mm/init.c | 12 +
arch/s390/mm/vmem.c | 14 +
arch/sh/mm/init.c | 15 +
arch/sparc/mm/init_64.c | 14 +
arch/tile/mm/init.c | 8 +
arch/x86/include/asm/pgtable_types.h | 1 +
arch/x86/mm/init_32.c | 10 +
arch/x86/mm/init_64.c | 331 ++++++++++++++++++
arch/x86/mm/pageattr.c | 47 ++--
drivers/acpi/acpi_memhotplug.c | 54 +++-
drivers/acpi/scan.c | 3 +-
drivers/base/memory.c | 88 ++++-
drivers/base/node.c | 11 +
drivers/firmware/memmap.c | 98 +++++-
include/acpi/acpi_bus.h | 1 +
include/linux/firmware-map.h | 6 +
include/linux/memory.h | 5 +
include/linux/memory_hotplug.h | 25 +-
include/linux/mm.h | 5 +-
include/linux/mmzone.h | 19 +
mm/memory_hotplug.c | 424 +++++++++++++++++++++--
mm/page_cgroup.c | 3 +
mm/sparse.c | 5 +-
28 files changed, 1181 insertions(+), 92 deletions(-)
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
On 09/05/2012 05:25 PM, wency@cn.fujitsu.com wrote:
quoted
From: Yasuaki Ishimatsu <redacted>
The function get_page_bootmem() may be called more than one time to the same
page. There is no need to set page's type, private if the function is not
the first time called to the page.
Note: the patch is just optimization and does not fix any problem.
Hi Yasuaki,
this patch is reasonable to me. I have another question associated to get_page_bootmem(), the question is from another fujitsu guy's patch changelog [commit : 04753278769f3], the changelog said that:
1) When the memmap of removing section is allocated on other
section by bootmem, it should/can be free.
2) When the memmap of removing section is allocated on the
same section, it shouldn't be freed. Because the section has to be
logical memory offlined already and all pages must be isolated against
page allocater. If it is freed, page allocator may use it which will
be removed physically soon.
but I don't see his patch guarantee 2), it means that his patch doesn't guarantee the memmap of removing section which is allocated on other section by bootmem doesn't be freed. Hopefully get your explaination in details, thanks in advance. :-)
In my understanding, the patch does not guarantee it.
Please see [commit : 0c0a4a517a31e]. free_map_bootmem() in the commit
guarantees it.
Thanks,
Yasuaki Ishimatsu
quoted
CC: David Rientjes <rientjes@google.com>
CC: Jiang Liu <redacted>
CC: Len Brown <redacted>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <redacted>
CC: Christoph Lameter <redacted>
Cc: Minchan Kim <redacted>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: KOSAKI Motohiro <redacted>
CC: Wen Congyang <redacted>
Signed-off-by: Yasuaki Ishimatsu <redacted>
---
mm/memory_hotplug.c | 15 +++++++++++----
1 files changed, 11 insertions(+), 4 deletions(-)
On 09/05/2012 05:25 PM, wency@cn.fujitsu.com wrote:
quoted
From: Wen Congyang <redacted>
This patch series aims to support physical memory hot-remove.
The patches can free/remove the following things:
- acpi_memory_info : [RFC PATCH 4/19]
- /sys/firmware/memmap/X/{end, start, type} : [RFC PATCH 8/19]
- iomem_resource : [RFC PATCH 9/19]
- mem_section and related sysfs files : [RFC PATCH 10-11, 13-16/19]
- page table of removed memory : [RFC PATCH 12/19]
- node and related sysfs files : [RFC PATCH 18-19/19]
If you find lack of function for physical memory hot-remove, please let me
know.
How to test this patchset?
1. apply this patchset and build the kernel. MEMORY_HOTPLUG, MEMORY_HOTREMOVE,
ACPI_HOTPLUG_MEMORY must be selected.
2. load the module acpi_memhotplug
Hi Yasuaki,
where is the acpi_memhotplug module?
If you build acpi_memhotplug as module, it is created under
/lib/modules/<kernel-version>/driver/acpi/ directory. It depends
on config ACPI_HOTPLUG_MEMORY. The confing is [*], it becomes built-in
function. So you don't need to care about it.
Thanks,
Yasuaki Ishimatsu
quoted
3. hotplug the memory device(it depends on your hardware)
You will see the memory device under the directory /sys/bus/acpi/devices/.
Its name is PNP0C80:XX.
4. online/offline pages provided by this memory device
You can write online/offline to /sys/devices/system/memory/memoryX/state to
online/offline pages provided by this memory device
5. hotremove the memory device
You can hotremove the memory device by the hardware, or writing 1 to
/sys/bus/acpi/devices/PNP0C80:XX/eject.
Note: if the memory provided by the memory device is used by the kernel, it
can't be offlined. It is not a bug.
Known problems:
1. memory can't be offlined when CONFIG_MEMCG is selected.
For example: there is a memory device on node 1. The address range
is [1G, 1.5G). You will find 4 new directories memory8, memory9, memory10,
and memory11 under the directory /sys/devices/system/memory/.
If CONFIG_MEMCG is selected, we will allocate memory to store page cgroup
when we online pages. When we online memory8, the memory stored page cgroup
is not provided by this memory device. But when we online memory9, the memory
stored page cgroup may be provided by memory8. So we can't offline memory8
now. We should offline the memory in the reversed order.
When the memory device is hotremoved, we will auto offline memory provided
by this memory device. But we don't know which memory is onlined first, so
offlining memory may fail. In such case, you should offline the memory by
hand before hotremoving the memory device.
2. hotremoving memory device may cause kernel panicked
This bug will be fixed by Liu Jiang's patch:
https://lkml.org/lkml/2012/7/3/1
change log of v9:
[RFC PATCH v9 8/21]
* add a lock to protect the list map_entries
* add an indicator to firmware_map_entry to remember whether the memory
is allocated from bootmem
[RFC PATCH v9 10/21]
* change the macro to inline function
[RFC PATCH v9 19/21]
* don't offline the node if the cpu on the node is onlined
[RFC PATCH v9 21/21]
* create new patch: auto offline page_cgroup when onlining memory block
failed
change log of v8:
[RFC PATCH v8 17/20]
* Fix problems when one node's range include the other nodes
[RFC PATCH v8 18/20]
* fix building error when CONFIG_MEMORY_HOTPLUG_SPARSE or CONFIG_HUGETLBFS
is not defined.
[RFC PATCH v8 19/20]
* don't offline node when some memory sections are not removed
[RFC PATCH v8 20/20]
* create new patch: clear hwpoisoned flag when onlining pages
change log of v7:
[RFC PATCH v7 4/19]
* do not continue if acpi_memory_device_remove_memory() fails.
[RFC PATCH v7 15/19]
* handle usemap in register_page_bootmem_info_section() too.
change log of v6:
[RFC PATCH v6 12/19]
* fix building error on other archtitectures than x86
[RFC PATCH v6 15-16/19]
* fix building error on other archtitectures than x86
change log of v5:
* merge the patchset to clear page table and the patchset to hot remove
memory(from ishimatsu) to one big patchset.
[RFC PATCH v5 1/19]
* rename remove_memory() to offline_memory()/offline_pages()
[RFC PATCH v5 2/19]
* new patch: implement offline_memory(). This function offlines pages,
update memory block's state, and notify the userspace that the memory
block's state is changed.
[RFC PATCH v5 4/19]
* offline and remove memory in acpi_memory_disable_device() too.
[RFC PATCH v5 17/19]
* new patch: add a new function __remove_zone() to revert the things done
in the function __add_zone().
[RFC PATCH v5 18/19]
* flush work befor reseting node device.
change log of v4:
* remove "memory-hotplug : unify argument of firmware_map_add_early/hotplug"
from the patch series, since the patch is a bugfix. It is being disccussed
on other thread. But for testing the patch series, the patch is needed.
So I added the patch as [PATCH 0/13].
[RFC PATCH v4 2/13]
* check memory is online or not at remove_memory()
* add memory_add_physaddr_to_nid() to acpi_memory_device_remove() for
getting node id
[RFC PATCH v4 3/13]
* create new patch : check memory is online or not at online_pages()
[RFC PATCH v4 4/13]
* add __ref section to remove_memory()
* call firmware_map_remove_entry() before remove_sysfs_fw_map_entry()
[RFC PATCH v4 11/13]
* rewrite register_page_bootmem_memmap() for removing page used as PT/PMD
change log of v3:
* rebase to 3.5.0-rc6
[RFC PATCH v2 2/13]
* remove extra kobject_put()
* The patch was commented by Wen. Wen's comment is
"acpi_memory_device_remove() should ignore a return value of
remove_memory() since caller does not care the return value".
But I did not change it since I think caller should care the
return value. And I am trying to fix it as follow:
https://lkml.org/lkml/2012/7/5/624
[RFC PATCH v2 4/13]
* remove a firmware_memmap_entry allocated by kzmalloc()
change log of v2:
[RFC PATCH v2 2/13]
* check whether memory block is offline or not before calling offline_memory()
* check whether section is valid or not in is_memblk_offline()
* call kobject_put() for each memory_block in is_memblk_offline()
[RFC PATCH v2 3/13]
* unify the end argument of firmware_map_add_early/hotplug
[RFC PATCH v2 4/13]
* add release_firmware_map_entry() for freeing firmware_map_entry
[RFC PATCH v2 6/13]
* add release_memory_block() for freeing memory_block
[RFC PATCH v2 11/13]
* fix wrong arguments of free_pages()
Wen Congyang (8):
memory-hotplug: implement offline_memory()
memory-hotplug: store the node id in acpi_memory_device
memory-hotplug: export the function acpi_bus_remove()
memory-hotplug: call acpi_bus_remove() to remove memory device
memory-hotplug: introduce new function arch_remove_memory()
memory-hotplug: remove sysfs file of node
memory-hotplug: clear hwpoisoned flag when onlining pages
memory-hotplug: auto offline page_cgroup when onlining memory block
failed
Yasuaki Ishimatsu (13):
memory-hotplug: rename remove_memory() to
offline_memory()/offline_pages()
memory-hotplug: offline and remove memory when removing the memory
device
memory-hotplug: check whether memory is present or not
memory-hotplug: remove /sys/firmware/memmap/X sysfs
memory-hotplug: does not release memory region in PAGES_PER_SECTION
chunks
memory-hotplug: add memory_block_release
memory-hotplug: remove_memory calls __remove_pages
memory-hotplug: check page type in get_page_bootmem
memory-hotplug: move register_page_bootmem_info_node and
put_page_bootmem for sparse-vmemmap
memory-hotplug: implement register_page_bootmem_info_section of
sparse-vmemmap
memory-hotplug: free memmap of sparse-vmemmap
memory_hotplug: clear zone when the memory is removed
memory-hotplug: add node_device_release
arch/ia64/mm/discontig.c | 14 +
arch/ia64/mm/init.c | 16 +
arch/powerpc/mm/init_64.c | 14 +
arch/powerpc/mm/mem.c | 14 +
arch/powerpc/platforms/pseries/hotplug-memory.c | 16 +-
arch/s390/mm/init.c | 12 +
arch/s390/mm/vmem.c | 14 +
arch/sh/mm/init.c | 15 +
arch/sparc/mm/init_64.c | 14 +
arch/tile/mm/init.c | 8 +
arch/x86/include/asm/pgtable_types.h | 1 +
arch/x86/mm/init_32.c | 10 +
arch/x86/mm/init_64.c | 331 ++++++++++++++++++
arch/x86/mm/pageattr.c | 47 ++--
drivers/acpi/acpi_memhotplug.c | 54 +++-
drivers/acpi/scan.c | 3 +-
drivers/base/memory.c | 88 ++++-
drivers/base/node.c | 11 +
drivers/firmware/memmap.c | 98 +++++-
include/acpi/acpi_bus.h | 1 +
include/linux/firmware-map.h | 6 +
include/linux/memory.h | 5 +
include/linux/memory_hotplug.h | 25 +-
include/linux/mm.h | 5 +-
include/linux/mmzone.h | 19 +
mm/memory_hotplug.c | 424 +++++++++++++++++++++--
mm/page_cgroup.c | 3 +
mm/sparse.c | 5 +-
28 files changed, 1181 insertions(+), 92 deletions(-)
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
On 09/05/2012 05:25 PM, wency@cn.fujitsu.com wrote:
quoted
From: Wen Congyang <redacted>
The memory device has only one node id. Store the node id when
enable the memory device, and we can reuse it when removing the
memory device.
one question:
if use numa emulation, memory device will associated to one node or ...?
Memory device has only one node, even if you use numa emulation.
Thanks,
Yasuaki Ishimatsu
quoted
CC: David Rientjes <rientjes@google.com>
CC: Jiang Liu <redacted>
CC: Len Brown <redacted>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <redacted>
CC: Christoph Lameter <redacted>
Cc: Minchan Kim <redacted>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: KOSAKI Motohiro <redacted>
CC: Yasuaki Ishimatsu <redacted>
Signed-off-by: Wen Congyang <redacted>
Reviewed-by: Yasuaki Ishimatsu <redacted>
---
drivers/acpi/acpi_memhotplug.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
@@ -83,6 +83,7 @@ struct acpi_memory_info {structacpi_memory_device{structacpi_device*device;unsignedintstate;/* State of the memory device */+intnid;structlist_headres_list;};
@@ -256,6 +257,9 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device)info->enabled=1;num_enabled++;}++mem_device->nid=node;+if(!num_enabled){printk(KERN_ERRPREFIX"add_memory failed\n");mem_device->state=MEMORY_INVALID_STATE;
From: Ni zhan Chen <hidden> Date: 2012-10-01 23:46:13
On 10/01/2012 12:44 PM, Yasuaki Ishimatsu wrote:
Hi Chen,
2012/09/29 17:19, Ni zhan Chen wrote:
quoted
On 09/05/2012 05:25 PM, wency@cn.fujitsu.com wrote:
quoted
From: Wen Congyang <redacted>
This patch series aims to support physical memory hot-remove.
The patches can free/remove the following things:
- acpi_memory_info : [RFC PATCH 4/19]
- /sys/firmware/memmap/X/{end, start, type} : [RFC PATCH 8/19]
- iomem_resource : [RFC PATCH 9/19]
- mem_section and related sysfs files : [RFC PATCH 10-11,
13-16/19]
- page table of removed memory : [RFC PATCH 12/19]
- node and related sysfs files : [RFC PATCH 18-19/19]
If you find lack of function for physical memory hot-remove, please
let me
know.
How to test this patchset?
1. apply this patchset and build the kernel. MEMORY_HOTPLUG,
MEMORY_HOTREMOVE,
ACPI_HOTPLUG_MEMORY must be selected.
2. load the module acpi_memhotplug
Hi Yasuaki,
where is the acpi_memhotplug module?
If you build acpi_memhotplug as module, it is created under
/lib/modules/<kernel-version>/driver/acpi/ directory. It depends
on config ACPI_HOTPLUG_MEMORY. The confing is [*], it becomes built-in
function. So you don't need to care about it.
Thanks,
Yasuaki Ishimatsu
Hi Yasuaki,
I build the kernel, MEMORY_HOTPLUG, MEMORY_HOTREMOVE,
ACPI_HOTPLUG_MEMORY are seleted as [*], but I can't find PNP0C80:XX
under the directory /sys/bus/acpi/devices/.
[root@localhost ~]# ls /sys/bus/acpi/devices/
device:00 device:07 device:0e device:15 device:1c device:23
device:2a LNXCPU:00 LNXCPU:07 PNP0501:00 PNP0C02:00 PNP0C0F:02
PNP0C14:01
device:01 device:08 device:0f device:16 device:1d device:24
device:2b LNXCPU:01 LNXPWRBN:00 PNP0800:00 PNP0C02:01 PNP0C0F:03
PNP0C31:00
device:02 device:09 device:10 device:17 device:1e device:25
device:2c LNXCPU:02 LNXSYSTM:00 PNP0A08:00 PNP0C02:02 PNP0C0F:04
device:03 device:0a device:11 device:18 device:1f device:26
device:2d LNXCPU:03 PNP0000:00 PNP0B00:00 PNP0C04:00 PNP0C0F:05
device:04 device:0b device:12 device:19 device:20 device:27
device:2e LNXCPU:04 PNP0100:00 PNP0C01:00 PNP0C0C:00 PNP0C0F:06
device:05 device:0c device:13 device:1a device:21 device:28
device:2f LNXCPU:05 PNP0103:00 PNP0C01:01 PNP0C0F:00 PNP0C0F:07
device:06 device:0d device:14 device:1b device:22 device:29
INT3F0D:00 LNXCPU:06 PNP0200:00 PNP0C01:02 PNP0C0F:01 PNP0C14:00
then what I miss ? thanks.
quoted
quoted
3. hotplug the memory device(it depends on your hardware)
You will see the memory device under the directory
/sys/bus/acpi/devices/.
Its name is PNP0C80:XX.
4. online/offline pages provided by this memory device
You can write online/offline to
/sys/devices/system/memory/memoryX/state to
online/offline pages provided by this memory device
5. hotremove the memory device
You can hotremove the memory device by the hardware, or writing
1 to
/sys/bus/acpi/devices/PNP0C80:XX/eject.
Note: if the memory provided by the memory device is used by the
kernel, it
can't be offlined. It is not a bug.
Known problems:
1. memory can't be offlined when CONFIG_MEMCG is selected.
For example: there is a memory device on node 1. The address range
is [1G, 1.5G). You will find 4 new directories memory8, memory9,
memory10,
and memory11 under the directory /sys/devices/system/memory/.
If CONFIG_MEMCG is selected, we will allocate memory to store
page cgroup
when we online pages. When we online memory8, the memory stored
page cgroup
is not provided by this memory device. But when we online
memory9, the memory
stored page cgroup may be provided by memory8. So we can't
offline memory8
now. We should offline the memory in the reversed order.
When the memory device is hotremoved, we will auto offline
memory provided
by this memory device. But we don't know which memory is onlined
first, so
offlining memory may fail. In such case, you should offline the
memory by
hand before hotremoving the memory device.
2. hotremoving memory device may cause kernel panicked
This bug will be fixed by Liu Jiang's patch:
https://lkml.org/lkml/2012/7/3/1
change log of v9:
[RFC PATCH v9 8/21]
* add a lock to protect the list map_entries
* add an indicator to firmware_map_entry to remember whether the
memory
is allocated from bootmem
[RFC PATCH v9 10/21]
* change the macro to inline function
[RFC PATCH v9 19/21]
* don't offline the node if the cpu on the node is onlined
[RFC PATCH v9 21/21]
* create new patch: auto offline page_cgroup when onlining
memory block
failed
change log of v8:
[RFC PATCH v8 17/20]
* Fix problems when one node's range include the other nodes
[RFC PATCH v8 18/20]
* fix building error when CONFIG_MEMORY_HOTPLUG_SPARSE or
CONFIG_HUGETLBFS
is not defined.
[RFC PATCH v8 19/20]
* don't offline node when some memory sections are not removed
[RFC PATCH v8 20/20]
* create new patch: clear hwpoisoned flag when onlining pages
change log of v7:
[RFC PATCH v7 4/19]
* do not continue if acpi_memory_device_remove_memory() fails.
[RFC PATCH v7 15/19]
* handle usemap in register_page_bootmem_info_section() too.
change log of v6:
[RFC PATCH v6 12/19]
* fix building error on other archtitectures than x86
[RFC PATCH v6 15-16/19]
* fix building error on other archtitectures than x86
change log of v5:
* merge the patchset to clear page table and the patchset to hot
remove
memory(from ishimatsu) to one big patchset.
[RFC PATCH v5 1/19]
* rename remove_memory() to offline_memory()/offline_pages()
[RFC PATCH v5 2/19]
* new patch: implement offline_memory(). This function offlines
pages,
update memory block's state, and notify the userspace that the
memory
block's state is changed.
[RFC PATCH v5 4/19]
* offline and remove memory in acpi_memory_disable_device() too.
[RFC PATCH v5 17/19]
* new patch: add a new function __remove_zone() to revert the
things done
in the function __add_zone().
[RFC PATCH v5 18/19]
* flush work befor reseting node device.
change log of v4:
* remove "memory-hotplug : unify argument of
firmware_map_add_early/hotplug"
from the patch series, since the patch is a bugfix. It is being
disccussed
on other thread. But for testing the patch series, the patch is
needed.
So I added the patch as [PATCH 0/13].
[RFC PATCH v4 2/13]
* check memory is online or not at remove_memory()
* add memory_add_physaddr_to_nid() to
acpi_memory_device_remove() for
getting node id
[RFC PATCH v4 3/13]
* create new patch : check memory is online or not at
online_pages()
[RFC PATCH v4 4/13]
* add __ref section to remove_memory()
* call firmware_map_remove_entry() before
remove_sysfs_fw_map_entry()
[RFC PATCH v4 11/13]
* rewrite register_page_bootmem_memmap() for removing page used
as PT/PMD
change log of v3:
* rebase to 3.5.0-rc6
[RFC PATCH v2 2/13]
* remove extra kobject_put()
* The patch was commented by Wen. Wen's comment is
"acpi_memory_device_remove() should ignore a return value of
remove_memory() since caller does not care the return value".
But I did not change it since I think caller should care the
return value. And I am trying to fix it as follow:
https://lkml.org/lkml/2012/7/5/624
[RFC PATCH v2 4/13]
* remove a firmware_memmap_entry allocated by kzmalloc()
change log of v2:
[RFC PATCH v2 2/13]
* check whether memory block is offline or not before calling
offline_memory()
* check whether section is valid or not in is_memblk_offline()
* call kobject_put() for each memory_block in is_memblk_offline()
[RFC PATCH v2 3/13]
* unify the end argument of firmware_map_add_early/hotplug
[RFC PATCH v2 4/13]
* add release_firmware_map_entry() for freeing firmware_map_entry
[RFC PATCH v2 6/13]
* add release_memory_block() for freeing memory_block
[RFC PATCH v2 11/13]
* fix wrong arguments of free_pages()
Wen Congyang (8):
memory-hotplug: implement offline_memory()
memory-hotplug: store the node id in acpi_memory_device
memory-hotplug: export the function acpi_bus_remove()
memory-hotplug: call acpi_bus_remove() to remove memory device
memory-hotplug: introduce new function arch_remove_memory()
memory-hotplug: remove sysfs file of node
memory-hotplug: clear hwpoisoned flag when onlining pages
memory-hotplug: auto offline page_cgroup when onlining memory block
failed
Yasuaki Ishimatsu (13):
memory-hotplug: rename remove_memory() to
offline_memory()/offline_pages()
memory-hotplug: offline and remove memory when removing the memory
device
memory-hotplug: check whether memory is present or not
memory-hotplug: remove /sys/firmware/memmap/X sysfs
memory-hotplug: does not release memory region in PAGES_PER_SECTION
chunks
memory-hotplug: add memory_block_release
memory-hotplug: remove_memory calls __remove_pages
memory-hotplug: check page type in get_page_bootmem
memory-hotplug: move register_page_bootmem_info_node and
put_page_bootmem for sparse-vmemmap
memory-hotplug: implement register_page_bootmem_info_section of
sparse-vmemmap
memory-hotplug: free memmap of sparse-vmemmap
memory_hotplug: clear zone when the memory is removed
memory-hotplug: add node_device_release
arch/ia64/mm/discontig.c | 14 +
arch/ia64/mm/init.c | 16 +
arch/powerpc/mm/init_64.c | 14 +
arch/powerpc/mm/mem.c | 14 +
arch/powerpc/platforms/pseries/hotplug-memory.c | 16 +-
arch/s390/mm/init.c | 12 +
arch/s390/mm/vmem.c | 14 +
arch/sh/mm/init.c | 15 +
arch/sparc/mm/init_64.c | 14 +
arch/tile/mm/init.c | 8 +
arch/x86/include/asm/pgtable_types.h | 1 +
arch/x86/mm/init_32.c | 10 +
arch/x86/mm/init_64.c | 331
++++++++++++++++++
arch/x86/mm/pageattr.c | 47 ++--
drivers/acpi/acpi_memhotplug.c | 54 +++-
drivers/acpi/scan.c | 3 +-
drivers/base/memory.c | 88 ++++-
drivers/base/node.c | 11 +
drivers/firmware/memmap.c | 98 +++++-
include/acpi/acpi_bus.h | 1 +
include/linux/firmware-map.h | 6 +
include/linux/memory.h | 5 +
include/linux/memory_hotplug.h | 25 +-
include/linux/mm.h | 5 +-
include/linux/mmzone.h | 19 +
mm/memory_hotplug.c | 424
+++++++++++++++++++++--
mm/page_cgroup.c | 3 +
mm/sparse.c | 5 +-
28 files changed, 1181 insertions(+), 92 deletions(-)
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
On 09/05/2012 05:25 PM, wency@cn.fujitsu.com wrote:
quoted
From: Wen Congyang <redacted>
This patch series aims to support physical memory hot-remove.
The patches can free/remove the following things:
- acpi_memory_info : [RFC PATCH 4/19]
- /sys/firmware/memmap/X/{end, start, type} : [RFC PATCH 8/19]
- iomem_resource : [RFC PATCH 9/19]
- mem_section and related sysfs files : [RFC PATCH 10-11, 13-16/19]
- page table of removed memory : [RFC PATCH 12/19]
- node and related sysfs files : [RFC PATCH 18-19/19]
If you find lack of function for physical memory hot-remove, please let me
know.
How to test this patchset?
1. apply this patchset and build the kernel. MEMORY_HOTPLUG, MEMORY_HOTREMOVE,
ACPI_HOTPLUG_MEMORY must be selected.
2. load the module acpi_memhotplug
Hi Yasuaki,
where is the acpi_memhotplug module?
If you build acpi_memhotplug as module, it is created under
/lib/modules/<kernel-version>/driver/acpi/ directory. It depends
on config ACPI_HOTPLUG_MEMORY. The confing is [*], it becomes built-in
function. So you don't need to care about it.
Thanks,
Yasuaki Ishimatsu
Hi Yasuaki,
I build the kernel, MEMORY_HOTPLUG, MEMORY_HOTREMOVE, ACPI_HOTPLUG_MEMORY are seleted as [*], but I can't find PNP0C80:XX under the directory /sys/bus/acpi/devices/.
[root@localhost ~]# ls /sys/bus/acpi/devices/
device:00 device:07 device:0e device:15 device:1c device:23 device:2a LNXCPU:00 LNXCPU:07 PNP0501:00 PNP0C02:00 PNP0C0F:02 PNP0C14:01
device:01 device:08 device:0f device:16 device:1d device:24 device:2b LNXCPU:01 LNXPWRBN:00 PNP0800:00 PNP0C02:01 PNP0C0F:03 PNP0C31:00
device:02 device:09 device:10 device:17 device:1e device:25 device:2c LNXCPU:02 LNXSYSTM:00 PNP0A08:00 PNP0C02:02 PNP0C0F:04
device:03 device:0a device:11 device:18 device:1f device:26 device:2d LNXCPU:03 PNP0000:00 PNP0B00:00 PNP0C04:00 PNP0C0F:05
device:04 device:0b device:12 device:19 device:20 device:27 device:2e LNXCPU:04 PNP0100:00 PNP0C01:00 PNP0C0C:00 PNP0C0F:06
device:05 device:0c device:13 device:1a device:21 device:28 device:2f LNXCPU:05 PNP0103:00 PNP0C01:01 PNP0C0F:00 PNP0C0F:07
device:06 device:0d device:14 device:1b device:22 device:29 INT3F0D:00 LNXCPU:06 PNP0200:00 PNP0C01:02 PNP0C0F:01 PNP0C14:00
then what I miss ? thanks.
3. hotplug the memory device(it depends on your hardware)
You will see the memory device under the directory /sys/bus/acpi/devices/.
Its name is PNP0C80:XX.
4. online/offline pages provided by this memory device
You can write online/offline to /sys/devices/system/memory/memoryX/state to
online/offline pages provided by this memory device
5. hotremove the memory device
You can hotremove the memory device by the hardware, or writing 1 to
/sys/bus/acpi/devices/PNP0C80:XX/eject.
Note: if the memory provided by the memory device is used by the kernel, it
can't be offlined. It is not a bug.
Known problems:
1. memory can't be offlined when CONFIG_MEMCG is selected.
For example: there is a memory device on node 1. The address range
is [1G, 1.5G). You will find 4 new directories memory8, memory9, memory10,
and memory11 under the directory /sys/devices/system/memory/.
If CONFIG_MEMCG is selected, we will allocate memory to store page cgroup
when we online pages. When we online memory8, the memory stored page cgroup
is not provided by this memory device. But when we online memory9, the memory
stored page cgroup may be provided by memory8. So we can't offline memory8
now. We should offline the memory in the reversed order.
When the memory device is hotremoved, we will auto offline memory provided
by this memory device. But we don't know which memory is onlined first, so
offlining memory may fail. In such case, you should offline the memory by
hand before hotremoving the memory device.
2. hotremoving memory device may cause kernel panicked
This bug will be fixed by Liu Jiang's patch:
https://lkml.org/lkml/2012/7/3/1
change log of v9:
[RFC PATCH v9 8/21]
* add a lock to protect the list map_entries
* add an indicator to firmware_map_entry to remember whether the memory
is allocated from bootmem
[RFC PATCH v9 10/21]
* change the macro to inline function
[RFC PATCH v9 19/21]
* don't offline the node if the cpu on the node is onlined
[RFC PATCH v9 21/21]
* create new patch: auto offline page_cgroup when onlining memory block
failed
change log of v8:
[RFC PATCH v8 17/20]
* Fix problems when one node's range include the other nodes
[RFC PATCH v8 18/20]
* fix building error when CONFIG_MEMORY_HOTPLUG_SPARSE or CONFIG_HUGETLBFS
is not defined.
[RFC PATCH v8 19/20]
* don't offline node when some memory sections are not removed
[RFC PATCH v8 20/20]
* create new patch: clear hwpoisoned flag when onlining pages
change log of v7:
[RFC PATCH v7 4/19]
* do not continue if acpi_memory_device_remove_memory() fails.
[RFC PATCH v7 15/19]
* handle usemap in register_page_bootmem_info_section() too.
change log of v6:
[RFC PATCH v6 12/19]
* fix building error on other archtitectures than x86
[RFC PATCH v6 15-16/19]
* fix building error on other archtitectures than x86
change log of v5:
* merge the patchset to clear page table and the patchset to hot remove
memory(from ishimatsu) to one big patchset.
[RFC PATCH v5 1/19]
* rename remove_memory() to offline_memory()/offline_pages()
[RFC PATCH v5 2/19]
* new patch: implement offline_memory(). This function offlines pages,
update memory block's state, and notify the userspace that the memory
block's state is changed.
[RFC PATCH v5 4/19]
* offline and remove memory in acpi_memory_disable_device() too.
[RFC PATCH v5 17/19]
* new patch: add a new function __remove_zone() to revert the things done
in the function __add_zone().
[RFC PATCH v5 18/19]
* flush work befor reseting node device.
change log of v4:
* remove "memory-hotplug : unify argument of firmware_map_add_early/hotplug"
from the patch series, since the patch is a bugfix. It is being disccussed
on other thread. But for testing the patch series, the patch is needed.
So I added the patch as [PATCH 0/13].
[RFC PATCH v4 2/13]
* check memory is online or not at remove_memory()
* add memory_add_physaddr_to_nid() to acpi_memory_device_remove() for
getting node id
[RFC PATCH v4 3/13]
* create new patch : check memory is online or not at online_pages()
[RFC PATCH v4 4/13]
* add __ref section to remove_memory()
* call firmware_map_remove_entry() before remove_sysfs_fw_map_entry()
[RFC PATCH v4 11/13]
* rewrite register_page_bootmem_memmap() for removing page used as PT/PMD
change log of v3:
* rebase to 3.5.0-rc6
[RFC PATCH v2 2/13]
* remove extra kobject_put()
* The patch was commented by Wen. Wen's comment is
"acpi_memory_device_remove() should ignore a return value of
remove_memory() since caller does not care the return value".
But I did not change it since I think caller should care the
return value. And I am trying to fix it as follow:
https://lkml.org/lkml/2012/7/5/624
[RFC PATCH v2 4/13]
* remove a firmware_memmap_entry allocated by kzmalloc()
change log of v2:
[RFC PATCH v2 2/13]
* check whether memory block is offline or not before calling offline_memory()
* check whether section is valid or not in is_memblk_offline()
* call kobject_put() for each memory_block in is_memblk_offline()
[RFC PATCH v2 3/13]
* unify the end argument of firmware_map_add_early/hotplug
[RFC PATCH v2 4/13]
* add release_firmware_map_entry() for freeing firmware_map_entry
[RFC PATCH v2 6/13]
* add release_memory_block() for freeing memory_block
[RFC PATCH v2 11/13]
* fix wrong arguments of free_pages()
Wen Congyang (8):
memory-hotplug: implement offline_memory()
memory-hotplug: store the node id in acpi_memory_device
memory-hotplug: export the function acpi_bus_remove()
memory-hotplug: call acpi_bus_remove() to remove memory device
memory-hotplug: introduce new function arch_remove_memory()
memory-hotplug: remove sysfs file of node
memory-hotplug: clear hwpoisoned flag when onlining pages
memory-hotplug: auto offline page_cgroup when onlining memory block
failed
Yasuaki Ishimatsu (13):
memory-hotplug: rename remove_memory() to
offline_memory()/offline_pages()
memory-hotplug: offline and remove memory when removing the memory
device
memory-hotplug: check whether memory is present or not
memory-hotplug: remove /sys/firmware/memmap/X sysfs
memory-hotplug: does not release memory region in PAGES_PER_SECTION
chunks
memory-hotplug: add memory_block_release
memory-hotplug: remove_memory calls __remove_pages
memory-hotplug: check page type in get_page_bootmem
memory-hotplug: move register_page_bootmem_info_node and
put_page_bootmem for sparse-vmemmap
memory-hotplug: implement register_page_bootmem_info_section of
sparse-vmemmap
memory-hotplug: free memmap of sparse-vmemmap
memory_hotplug: clear zone when the memory is removed
memory-hotplug: add node_device_release
arch/ia64/mm/discontig.c | 14 +
arch/ia64/mm/init.c | 16 +
arch/powerpc/mm/init_64.c | 14 +
arch/powerpc/mm/mem.c | 14 +
arch/powerpc/platforms/pseries/hotplug-memory.c | 16 +-
arch/s390/mm/init.c | 12 +
arch/s390/mm/vmem.c | 14 +
arch/sh/mm/init.c | 15 +
arch/sparc/mm/init_64.c | 14 +
arch/tile/mm/init.c | 8 +
arch/x86/include/asm/pgtable_types.h | 1 +
arch/x86/mm/init_32.c | 10 +
arch/x86/mm/init_64.c | 331 ++++++++++++++++++
arch/x86/mm/pageattr.c | 47 ++--
drivers/acpi/acpi_memhotplug.c | 54 +++-
drivers/acpi/scan.c | 3 +-
drivers/base/memory.c | 88 ++++-
drivers/base/node.c | 11 +
drivers/firmware/memmap.c | 98 +++++-
include/acpi/acpi_bus.h | 1 +
include/linux/firmware-map.h | 6 +
include/linux/memory.h | 5 +
include/linux/memory_hotplug.h | 25 +-
include/linux/mm.h | 5 +-
include/linux/mmzone.h | 19 +
mm/memory_hotplug.c | 424 +++++++++++++++++++++--
mm/page_cgroup.c | 3 +
mm/sparse.c | 5 +-
28 files changed, 1181 insertions(+), 92 deletions(-)
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
From: Ni zhan Chen <hidden> Date: 2012-10-02 00:34:55
On 09/05/2012 05:25 PM, wency@cn.fujitsu.com wrote:
From: Wen Congyang <redacted>
The function acpi_bus_remove() can remove a acpi device from acpi device.
IIUC, s/acpi device/acpi bus
quoted hunk
When a acpi device is removed, we need to call this function to remove
the acpi device from acpi bus. So export this function.
CC: David Rientjes <rientjes@google.com>
CC: Jiang Liu <redacted>
CC: Len Brown <redacted>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <redacted>
CC: Christoph Lameter <redacted>
Cc: Minchan Kim <redacted>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: KOSAKI Motohiro <redacted>
CC: Yasuaki Ishimatsu <redacted>
Signed-off-by: Wen Congyang <redacted>
---
drivers/acpi/scan.c | 3 ++-
include/acpi/acpi_bus.h | 1 +
2 files changed, 3 insertions(+), 1 deletions(-)
Hi Kosaki-san,
2012/09/29 7:15, KOSAKI Motohiro wrote:
On Thu, Sep 27, 2012 at 11:50 PM, Yasuaki Ishimatsu
[off-list ref] wrote:
quoted
Hi Chen,
2012/09/28 11:22, Ni zhan Chen wrote:
quoted
On 09/05/2012 05:25 PM, wency@cn.fujitsu.com wrote:
quoted
From: Yasuaki Ishimatsu <redacted>
remove_memory() only try to offline pages. It is called in two cases:
1. hot remove a memory device
2. echo offline >/sys/devices/system/memory/memoryXX/state
In the 1st case, we should also change memory block's state, and notify
the userspace that the memory block's state is changed after offlining
pages.
So rename remove_memory() to offline_memory()/offline_pages(). And in
the 1st case, offline_memory() will be used. The function
offline_memory()
is not implemented. In the 2nd case, offline_pages() will be used.
But this time there is not a function associated with add_memory.
To associate with add_memory() later, we renamed it.
Then, you introduced bisect breakage. It is definitely unacceptable.
What is "bisect breakage" meaning?
Thanks,
Yasuaki Ishimatsu
From: Ni zhan Chen <hidden> Date: 2012-10-02 04:22:12
On 09/05/2012 05:25 PM, wency@cn.fujitsu.com wrote:
quoted hunk
From: Yasuaki Ishimatsu <redacted>
All pages of virtual mapping in removed memory cannot be freed, since some pages
used as PGD/PUD includes not only removed memory but also other memory. So the
patch checks whether page can be freed or not.
How to check whether page can be freed or not?
1. When removing memory, the page structs of the revmoved memory are filled
with 0FD.
2. All page structs are filled with 0xFD on PT/PMD, PT/PMD can be cleared.
In this case, the page used as PT/PMD can be freed.
Applying patch, __remove_section() of CONFIG_SPARSEMEM_VMEMMAP is integrated
into one. So __remove_section() of CONFIG_SPARSEMEM_VMEMMAP is deleted.
Note: vmemmap_kfree() and vmemmap_free_bootmem() are not implemented for ia64,
ppc, s390, and sparc.
CC: David Rientjes <rientjes@google.com>
CC: Jiang Liu <redacted>
CC: Len Brown <redacted>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <redacted>
CC: Christoph Lameter <redacted>
Cc: Minchan Kim <redacted>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: KOSAKI Motohiro <redacted>
CC: Wen Congyang <redacted>
Signed-off-by: Yasuaki Ishimatsu <redacted>
---
arch/ia64/mm/discontig.c | 8 +++
arch/powerpc/mm/init_64.c | 8 +++
arch/s390/mm/vmem.c | 8 +++
arch/sparc/mm/init_64.c | 8 +++
arch/x86/mm/init_64.c | 119 +++++++++++++++++++++++++++++++++++++++++++++
include/linux/mm.h | 2 +
mm/memory_hotplug.c | 17 +------
mm/sparse.c | 5 +-
8 files changed, 158 insertions(+), 17 deletions(-)
@@ -1620,6 +1620,8 @@ int vmemmap_populate(struct page *start_page, unsigned long pages, int node);voidvmemmap_populate_print_last(void);voidregister_page_bootmem_memmap(unsignedlongsection_nr,structpage*map,unsignedlongsize);+voidvmemmap_kfree(structpage*memmpa,unsignedlongnr_pages);+voidvmemmap_free_bootmem(structpage*memmpa,unsignedlongnr_pages);enummf_flags{MF_COUNT_INCREASED=1<<0,
@@ -613,12 +613,13 @@ static inline struct page *kmalloc_section_memmap(unsigned long pnum, int nid,/* This will make the necessary allocations eventually. */returnsparse_mem_map_populate(pnum,nid);}-staticvoid__kfree_section_memmap(structpage*memmap,unsignedlongnr_pages)+staticvoid__kfree_section_memmap(structpage*page,unsignedlongnr_pages){-return;/* XXX: Not implemented yet */+vmemmap_kfree(page,nr_pages);}staticvoidfree_map_bootmem(structpage*page,unsignedlongnr_pages){+vmemmap_free_bootmem(page,nr_pages);}#elsestaticstructpage*__kmalloc_section_memmap(unsignedlongnr_pages)
From: Ni zhan Chen <hidden> Date: 2012-10-02 12:24:19
On 10/01/2012 11:03 AM, Yasuaki Ishimatsu wrote:
Hi Chen,
2012/09/29 11:15, Ni zhan Chen wrote:
quoted
On 09/05/2012 05:25 PM, wency@cn.fujitsu.com wrote:
quoted
From: Yasuaki Ishimatsu <redacted>
The function get_page_bootmem() may be called more than one time to
the same
page. There is no need to set page's type, private if the function
is not
the first time called to the page.
Note: the patch is just optimization and does not fix any problem.
Hi Yasuaki,
this patch is reasonable to me. I have another question associated to
get_page_bootmem(), the question is from another fujitsu guy's patch
changelog [commit : 04753278769f3], the changelog said that:
1) When the memmap of removing section is allocated on other
section by bootmem, it should/can be free.
2) When the memmap of removing section is allocated on the
same section, it shouldn't be freed. Because the section has to be
logical memory offlined already and all pages must be isolated
against
page allocater. If it is freed, page allocator may use it which
will
be removed physically soon.
but I don't see his patch guarantee 2), it means that his patch
doesn't guarantee the memmap of removing section which is allocated
on other section by bootmem doesn't be freed. Hopefully get your
explaination in details, thanks in advance. :-)
In my understanding, the patch does not guarantee it.
Please see [commit : 0c0a4a517a31e]. free_map_bootmem() in the commit
guarantees it.
Thanks Yasuaki, I have already seen the commit you mentioned. But the
changelog of the commit I point out 2), why it said that "If it is
freed, page allocator may use it which will be removed physically soon",
does it mean that use-after-free ? AFAK, the isolated pages will be free
if no users use it, so why not free the associated memmap?
Thanks,
Yasuaki Ishimatsu
quoted
quoted
CC: David Rientjes <rientjes@google.com>
CC: Jiang Liu <redacted>
CC: Len Brown <redacted>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <redacted>
CC: Christoph Lameter <redacted>
Cc: Minchan Kim <redacted>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: KOSAKI Motohiro <redacted>
CC: Wen Congyang <redacted>
Signed-off-by: Yasuaki Ishimatsu <redacted>
---
mm/memory_hotplug.c | 15 +++++++++++----
1 files changed, 11 insertions(+), 4 deletions(-)
Hi Chen,
Sorry for late reply.
2012/10/02 13:21, Ni zhan Chen wrote:
On 09/05/2012 05:25 PM, wency@cn.fujitsu.com wrote:
quoted
From: Yasuaki Ishimatsu <redacted>
All pages of virtual mapping in removed memory cannot be freed, since some pages
used as PGD/PUD includes not only removed memory but also other memory. So the
patch checks whether page can be freed or not.
How to check whether page can be freed or not?
1. When removing memory, the page structs of the revmoved memory are filled
with 0FD.
2. All page structs are filled with 0xFD on PT/PMD, PT/PMD can be cleared.
In this case, the page used as PT/PMD can be freed.
Applying patch, __remove_section() of CONFIG_SPARSEMEM_VMEMMAP is integrated
into one. So __remove_section() of CONFIG_SPARSEMEM_VMEMMAP is deleted.
Note: vmemmap_kfree() and vmemmap_free_bootmem() are not implemented for ia64,
ppc, s390, and sparc.
CC: David Rientjes <rientjes@google.com>
CC: Jiang Liu <redacted>
CC: Len Brown <redacted>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <redacted>
CC: Christoph Lameter <redacted>
Cc: Minchan Kim <redacted>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: KOSAKI Motohiro <redacted>
CC: Wen Congyang <redacted>
Signed-off-by: Yasuaki Ishimatsu <redacted>
---
arch/ia64/mm/discontig.c | 8 +++
arch/powerpc/mm/init_64.c | 8 +++
arch/s390/mm/vmem.c | 8 +++
arch/sparc/mm/init_64.c | 8 +++
arch/x86/mm/init_64.c | 119 +++++++++++++++++++++++++++++++++++++++++++++
include/linux/mm.h | 2 +
mm/memory_hotplug.c | 17 +------
mm/sparse.c | 5 +-
8 files changed, 158 insertions(+), 17 deletions(-)
@@ -1138,6 +1138,125 @@ vmemmap_populate(struct page *start_page, unsigned long size, int node)return0;}+#define PAGE_INUSE 0xFD++unsignedlongfind_and_clear_pte_page(unsignedlongaddr,unsignedlongend,+structpage**pp,int*page_size)+{+pgd_t*pgd;+pud_t*pud;+pmd_t*pmd;+pte_t*pte;+void*page_addr;+unsignedlongnext;++*pp=NULL;++pgd=pgd_offset_k(addr);+if(pgd_none(*pgd))+returnpgd_addr_end(addr,end);++pud=pud_offset(pgd,addr);+if(pud_none(*pud))+returnpud_addr_end(addr,end);++if(!cpu_has_pse){+next=(addr+PAGE_SIZE)&PAGE_MASK;+pmd=pmd_offset(pud,addr);+if(pmd_none(*pmd))+returnnext;++pte=pte_offset_kernel(pmd,addr);+if(pte_none(*pte))+returnnext;++*page_size=PAGE_SIZE;+*pp=pte_page(*pte);+}else{+next=pmd_addr_end(addr,end);++pmd=pmd_offset(pud,addr);+if(pmd_none(*pmd))+returnnext;++*page_size=PMD_SIZE;+*pp=pmd_page(*pmd);+}++/*+*Removedpagestructsarefilledwith0xFD.+*/+memset((void*)addr,PAGE_INUSE,next-addr);++page_addr=page_address(*pp);++/*+*Checkthepageisfilledwith0xFDornot.+*memchr_inv()returnstheaddress.Inthiscase,wecannot+*clearPTE/PUDentry,sincethepageisusedbyother.+*Sowecannotalsofreethepage.+*+*memchr_inv()returnsNULL.Inthiscase,wecanclear+*PTE/PUDentry,sincethepageisnotusedbyother.+*Sowecanalsofreethepage.+*/+if(memchr_inv(page_addr,PAGE_INUSE,*page_size)){+*pp=NULL;+returnnext;+}+
Hi Yasuaki,
why call memchr_inv check after memset, this time the page can always be filled with 0xFD.
The page is not always filled with 0xFD. find_and_clear_pte_page()
is calld in each section. So the function fills the page
section size/sizeof(page) byte with 0xFD one time. Thus if section size is
small, the page is filled with 0xFD.
Thanks,
Yasuaki Ishimatsu
quoted
+ if (!cpu_has_pse)
+ pte_clear(&init_mm, addr, pte);
+ else
+ pmd_clear(pmd);
+
+ return next;
+}
+
+void vmemmap_kfree(struct page *memmap, unsigned long nr_pages)
+{
+ unsigned long addr = (unsigned long)memmap;
+ unsigned long end = (unsigned long)(memmap + nr_pages);
+ unsigned long next;
+ struct page *page;
+ int page_size;
+
+ for (; addr < end; addr = next) {
+ page = NULL;
+ page_size = 0;
+ next = find_and_clear_pte_page(addr, end, &page, &page_size);
+ if (!page)
+ continue;
+
+ free_pages((unsigned long)page_address(page),
+ get_order(page_size));
+ __flush_tlb_one(addr);
+ }
+}
+
+void vmemmap_free_bootmem(struct page *memmap, unsigned long nr_pages)
+{
+ unsigned long addr = (unsigned long)memmap;
+ unsigned long end = (unsigned long)(memmap + nr_pages);
+ unsigned long next;
+ struct page *page;
+ int page_size;
+ unsigned long magic;
+
+ for (; addr < end; addr = next) {
+ page = NULL;
+ page_size = 0;
+ next = find_and_clear_pte_page(addr, end, &page, &page_size);
+ if (!page)
+ continue;
+
+ magic = (unsigned long) page->lru.next;
+ if (magic == SECTION_INFO)
+ put_page_bootmem(page);
+ flush_tlb_kernel_range(addr, end);
+ }
+}
+
void register_page_bootmem_memmap(unsigned long section_nr,
struct page *start_page, unsigned long size)
{
@@ -1620,6 +1620,8 @@ int vmemmap_populate(struct page *start_page, unsigned long pages, int node);voidvmemmap_populate_print_last(void);voidregister_page_bootmem_memmap(unsignedlongsection_nr,structpage*map,unsignedlongsize);+voidvmemmap_kfree(structpage*memmpa,unsignedlongnr_pages);+voidvmemmap_free_bootmem(structpage*memmpa,unsignedlongnr_pages);enummf_flags{MF_COUNT_INCREASED=1<<0,
@@ -613,12 +613,13 @@ static inline struct page *kmalloc_section_memmap(unsigned long pnum, int nid,/* This will make the necessary allocations eventually. */returnsparse_mem_map_populate(pnum,nid);}-staticvoid__kfree_section_memmap(structpage*memmap,unsignedlongnr_pages)+staticvoid__kfree_section_memmap(structpage*page,unsignedlongnr_pages){-return;/* XXX: Not implemented yet */+vmemmap_kfree(page,nr_pages);}staticvoidfree_map_bootmem(structpage*page,unsignedlongnr_pages){+vmemmap_free_bootmem(page,nr_pages);}#elsestaticstructpage*__kmalloc_section_memmap(unsignedlongnr_pages)
From: Ni zhan Chen <hidden> Date: 2012-10-06 14:18:44
On 10/04/2012 02:26 PM, Yasuaki Ishimatsu wrote:
Hi Chen,
Sorry for late reply.
2012/10/02 13:21, Ni zhan Chen wrote:
quoted
On 09/05/2012 05:25 PM, wency@cn.fujitsu.com wrote:
quoted
From: Yasuaki Ishimatsu <redacted>
All pages of virtual mapping in removed memory cannot be freed,
since some pages
used as PGD/PUD includes not only removed memory but also other
memory. So the
patch checks whether page can be freed or not.
How to check whether page can be freed or not?
1. When removing memory, the page structs of the revmoved memory
are filled
with 0FD.
2. All page structs are filled with 0xFD on PT/PMD, PT/PMD can be
cleared.
In this case, the page used as PT/PMD can be freed.
Applying patch, __remove_section() of CONFIG_SPARSEMEM_VMEMMAP is
integrated
into one. So __remove_section() of CONFIG_SPARSEMEM_VMEMMAP is deleted.
Note: vmemmap_kfree() and vmemmap_free_bootmem() are not
implemented for ia64,
ppc, s390, and sparc.
CC: David Rientjes <rientjes@google.com>
CC: Jiang Liu <redacted>
CC: Len Brown <redacted>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <redacted>
CC: Christoph Lameter <redacted>
Cc: Minchan Kim <redacted>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: KOSAKI Motohiro <redacted>
CC: Wen Congyang <redacted>
Signed-off-by: Yasuaki Ishimatsu <redacted>
---
arch/ia64/mm/discontig.c | 8 +++
arch/powerpc/mm/init_64.c | 8 +++
arch/s390/mm/vmem.c | 8 +++
arch/sparc/mm/init_64.c | 8 +++
arch/x86/mm/init_64.c | 119
+++++++++++++++++++++++++++++++++++++++++++++
include/linux/mm.h | 2 +
mm/memory_hotplug.c | 17 +------
mm/sparse.c | 5 +-
8 files changed, 158 insertions(+), 17 deletions(-)
unsigned long size, int node)
return 0;
}
+#define PAGE_INUSE 0xFD
+
+unsigned long find_and_clear_pte_page(unsigned long addr, unsigned
long end,
+ struct page **pp, int *page_size)
+{
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte;
+ void *page_addr;
+ unsigned long next;
+
+ *pp = NULL;
+
+ pgd = pgd_offset_k(addr);
+ if (pgd_none(*pgd))
+ return pgd_addr_end(addr, end);
+
+ pud = pud_offset(pgd, addr);
+ if (pud_none(*pud))
+ return pud_addr_end(addr, end);
+
+ if (!cpu_has_pse) {
+ next = (addr + PAGE_SIZE) & PAGE_MASK;
+ pmd = pmd_offset(pud, addr);
+ if (pmd_none(*pmd))
+ return next;
+
+ pte = pte_offset_kernel(pmd, addr);
+ if (pte_none(*pte))
+ return next;
+
+ *page_size = PAGE_SIZE;
+ *pp = pte_page(*pte);
+ } else {
+ next = pmd_addr_end(addr, end);
+
+ pmd = pmd_offset(pud, addr);
+ if (pmd_none(*pmd))
+ return next;
+
+ *page_size = PMD_SIZE;
+ *pp = pmd_page(*pmd);
+ }
+
+ /*
+ * Removed page structs are filled with 0xFD.
+ */
+ memset((void *)addr, PAGE_INUSE, next - addr);
+
+ page_addr = page_address(*pp);
+
+ /*
+ * Check the page is filled with 0xFD or not.
+ * memchr_inv() returns the address. In this case, we cannot
+ * clear PTE/PUD entry, since the page is used by other.
+ * So we cannot also free the page.
+ *
+ * memchr_inv() returns NULL. In this case, we can clear
+ * PTE/PUD entry, since the page is not used by other.
+ * So we can also free the page.
+ */
+ if (memchr_inv(page_addr, PAGE_INUSE, *page_size)) {
+ *pp = NULL;
+ return next;
+ }
+
Hi Yasuaki,
why call memchr_inv check after memset, this time the page can always
be filled with 0xFD.
The page is not always filled with 0xFD. find_and_clear_pte_page()
is calld in each section. So the function fills the page
section size/sizeof(page) byte with 0xFD one time. Thus if section
size is
small, the page is filled with 0xFD.
Hi Yasuaki,
But when section size will be small?
Regards,
Chen
Thanks,
Yasuaki Ishimatsu
quoted
quoted
+ if (!cpu_has_pse)
+ pte_clear(&init_mm, addr, pte);
+ else
+ pmd_clear(pmd);
+
+ return next;
+}
+
+void vmemmap_kfree(struct page *memmap, unsigned long nr_pages)
+{
+ unsigned long addr = (unsigned long)memmap;
+ unsigned long end = (unsigned long)(memmap + nr_pages);
+ unsigned long next;
+ struct page *page;
+ int page_size;
+
+ for (; addr < end; addr = next) {
+ page = NULL;
+ page_size = 0;
+ next = find_and_clear_pte_page(addr, end, &page, &page_size);
+ if (!page)
+ continue;
+
+ free_pages((unsigned long)page_address(page),
+ get_order(page_size));
+ __flush_tlb_one(addr);
+ }
+}
+
+void vmemmap_free_bootmem(struct page *memmap, unsigned long nr_pages)
+{
+ unsigned long addr = (unsigned long)memmap;
+ unsigned long end = (unsigned long)(memmap + nr_pages);
+ unsigned long next;
+ struct page *page;
+ int page_size;
+ unsigned long magic;
+
+ for (; addr < end; addr = next) {
+ page = NULL;
+ page_size = 0;
+ next = find_and_clear_pte_page(addr, end, &page, &page_size);
+ if (!page)
+ continue;
+
+ magic = (unsigned long) page->lru.next;
+ if (magic == SECTION_INFO)
+ put_page_bootmem(page);
+ flush_tlb_kernel_range(addr, end);
+ }
+}
+
void register_page_bootmem_memmap(unsigned long section_nr,
struct page *start_page, unsigned long size)
{
At 09/27/2012 12:46 AM, Vasilis Liaskovitis Wrote:
Hi,
I am testing 3.6.0-rc7 with this v9 patchset plus more recent fixes [1],[2],[3]
Running in a guest (qemu+seabios from [4]).
CONFIG_SLAB=y
CONFIG_DEBUG_SLAB=y
After succesfull hot-add and online, I am doing a hot-remove with "echo 1 > /sys/bus/acpi/devices/PNP/eject"
When I do the OSPM-eject, I often get slab corruption in "acpi-state" cache, or in other caches
I found the reason: when you do OSPM-eject, the kernel will auto offline and remove the memory.
But, offlining memory fails, and the memory is still used by the kernel. But device_release_driver()
doesn't tell this error to the caller acpi_bus_remove(). The kernel will poweroff and eject
the device by emulate _PS3 and _EJ0. The kernel uses some memory which doesn't exist. It's
very dangerous.
Thanks
Wen Conyang
At 09/27/2012 12:46 AM, Vasilis Liaskovitis Wrote:
Hi,
I am testing 3.6.0-rc7 with this v9 patchset plus more recent fixes [1],[2],[3]
Running in a guest (qemu+seabios from [4]).
CONFIG_SLAB=y
CONFIG_DEBUG_SLAB=y
After succesfull hot-add and online, I am doing a hot-remove with "echo 1 > /sys/bus/acpi/devices/PNP/eject"
When I do the OSPM-eject, I often get slab corruption in "acpi-state" cache, or in other caches