Hi Paul,
Here are the hotplug memory remove updates for 2.6.25-rc2-mm1.
[PATCH 1/3] ppc64-specific remove htab bolted mapping support
[PATCH 2/3] generic __remove_pages() support
[PATCH 3/3] ppc64-specific memory notifier support
As you can see PATCH 1,3 are ppc64-specific. PATCH 1 was already
reviewed by you. Could you please review PATCH 3 and let me know,
if I missing something ?
I would like to submit these for -mm inclusion after your review.
Thanks,
Badari
For memory remove, we need to clean up htab mappings for the
section of the memory we are removing.
This patch implements support for removing htab bolted mappings
for ppc64 lpar. Other sub-archs, may need to implement similar
functionality for the hotplug memory remove to work.
Signed-off-by: Badari Pulavarty <redacted>
Acked-by: Paul Mackerras <redacted>
---
arch/powerpc/mm/hash_utils_64.c | 26 ++++++++++++++++++++++++++
arch/powerpc/platforms/pseries/lpar.c | 15 +++++++++++++++
include/asm-powerpc/machdep.h | 2 ++
include/asm-powerpc/sparsemem.h | 1 +
5 files changed, 44 insertions(+), 4 deletions(-)
Index: linux-2.6.25-rc2/arch/powerpc/mm/hash_utils_64.c
===================================================================
@@ -68,6 +68,8 @@ struct machdep_calls {unsignedlongvflags,intpsize,intssize);long(*hpte_remove)(unsignedlonghpte_group);+void(*hpte_removebolted)(unsignedlongea,+intpsize,intssize);void(*flush_hash_range)(unsignedlongnumber,intlocal);/* special for kexec, to be called in real mode, linar mapping is
Generic helper function to remove section mappings and sysfs entries
for the section of the memory we are removing. offline_pages() correctly
adjusted zone and marked the pages reserved.
Issue: If mem_map, usemap allocation could come from different places -
kmalloc, vmalloc, alloc_pages or bootmem. There is no easy way
to find and free up properly. Especially for bootmem, we need to
know which node the allocation came from.
Signed-off-by: Badari Pulavarty <redacted>
---
include/linux/memory_hotplug.h | 4 +++
mm/memory_hotplug.c | 44 +++++++++++++++++++++++++++++++++++++++++
mm/sparse.c | 43 +++++++++++++++++++++++++++++++++++++---
3 files changed, 88 insertions(+), 3 deletions(-)
Index: linux-2.6.25-rc2/mm/memory_hotplug.c
===================================================================
@@ -102,6 +102,21 @@ static int __add_section(struct zone *zoreturnregister_new_memory(__pfn_to_section(phys_start_pfn));}+staticint__remove_section(structzone*zone,structmem_section*ms)+{+intret=-EINVAL;++if(!valid_section(ms))+returnret;++ret=unregister_memory_section(ms);+if(ret)+returnret;++sparse_remove_one_section(zone,ms);+return0;+}+/**Reasonablygenericfunctionforaddingmemory.Itis*expectedthatarchsthatsupportmemoryhotplugwill
@@ -135,6 +150,35 @@ int __add_pages(struct zone *zone, unsig}EXPORT_SYMBOL_GPL(__add_pages);+int__remove_pages(structzone*zone,unsignedlongphys_start_pfn,+unsignedlongnr_pages)+{+unsignedlongi,ret=0;+intsections_to_remove;+unsignedlongflags;+structpglist_data*pgdat=zone->zone_pgdat;++/*+*Wecanonlyremoveentiresections+*/+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;+pgdat_resize_lock(pgdat,&flags);+ret=__remove_section(zone,__pfn_to_section(pfn));+pgdat_resize_unlock(pgdat,&flags);+if(ret)+break;+}+returnret;+}+EXPORT_SYMBOL_GPL(__remove_pages);+staticvoidgrow_zone_span(structzone*zone,unsignedlongstart_pfn,unsignedlongend_pfn){
@@ -198,12 +198,13 @@ static unsigned long sparse_encode_mem_m}/*-*Weneedthisifweeverfreethemem_maps.Whilenotimplementedyet,-*thisfunctionisincludedforparitywithitssibling.+*Decodemem_mapfromthecodedmemmap*/-static__attribute((unused))+staticstructpage*sparse_decode_mem_map(unsignedlongcoded_mem_map,unsignedlongpnum){+/* mask off the extra low bits of information */+coded_mem_map&=SECTION_MAP_MASK;return((structpage*)coded_mem_map)+section_nr_to_pfn(pnum);}
@@ -64,6 +65,8 @@ extern int offline_pages(unsigned long, /* reasonably generic interface to expand the physical pages in a zone */externint__add_pages(structzone*zone,unsignedlongstart_pfn,unsignedlongnr_pages);+externint__remove_pages(structzone*zone,unsignedlongstart_pfn,+unsignedlongnr_pages);/**Walkthorughallmemorywhichisregisteredasresource.
Hotplug memory notifier for ppc64. This gets invoked by writing
the device-node that needs to be removed to /proc/ppc64/ofdt.
We need to adjust the sections and remove sysfs entries by
calling __remove_pages(). Then call arch specific code to
get rid of htab mappings for the section of memory.
Signed-off-by: Badari Pulavarty <redacted>
---
arch/powerpc/platforms/pseries/Makefile | 1
arch/powerpc/platforms/pseries/hotplug-memory.c | 98 ++++++++++++++++++++++++
2 files changed, 99 insertions(+)
Index: linux-2.6.25-rc2/arch/powerpc/platforms/pseries/hotplug-memory.c
===================================================================
From: Michael Ellerman <hidden> Date: 2008-02-29 00:11:15
On Thu, 2008-02-28 at 08:46 -0800, Badari Pulavarty wrote:
quoted hunk
Hotplug memory notifier for ppc64. This gets invoked by writing
the device-node that needs to be removed to /proc/ppc64/ofdt.
We need to adjust the sections and remove sysfs entries by
calling __remove_pages(). Then call arch specific code to
get rid of htab mappings for the section of memory.
Signed-off-by: Badari Pulavarty <redacted>
---
arch/powerpc/platforms/pseries/Makefile | 1
arch/powerpc/platforms/pseries/hotplug-memory.c | 98 ++++++++++++++++++++++++
2 files changed, 99 insertions(+)
Index: linux-2.6.25-rc2/arch/powerpc/platforms/pseries/hotplug-memory.c
===================================================================
This is going to fire on non-pseries LPAR platforms, like iSeries and
PS3. Which is not what you want I think.
cheers
--
Michael Ellerman
OzLabs, IBM Australia Development Lab
wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)
We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person
From: Michael Ellerman <hidden> Date: 2008-02-29 01:03:22
On Thu, 2008-02-28 at 18:39 -0600, Nathan Lynch wrote:
Michael Ellerman wrote:
quoted
On Thu, 2008-02-28 at 08:46 -0800, Badari Pulavarty wrote:
quoted
Hotplug memory notifier for ppc64. This gets invoked by writing
the device-node that needs to be removed to /proc/ppc64/ofdt.
We need to adjust the sections and remove sysfs entries by
calling __remove_pages(). Then call arch specific code to
get rid of htab mappings for the section of memory.
Signed-off-by: Badari Pulavarty <redacted>
---
arch/powerpc/platforms/pseries/Makefile | 1
arch/powerpc/platforms/pseries/hotplug-memory.c | 98 ++++++++++++++++++++++++
2 files changed, 99 insertions(+)
Index: linux-2.6.25-rc2/arch/powerpc/platforms/pseries/hotplug-memory.c
===================================================================
This is going to fire on non-pseries LPAR platforms, like iSeries and
PS3. Which is not what you want I think.
Well, the notifier will be registered, yes, but it will never be
called because that path is reachable only from a write to
/proc/ppc64/ofdt, which is not created on non-pseries.
Sure. Still seems better not to register it in the first place.
Maybe it should be
machine_device_initcall(pseries, pseries_memory_hotplug_init);
I think so.
(and pseries_cpu_hotplug_init in hotplug-cpu.c should be changed to
machine_arch_initcall)
Yeah I noticed that was not guarded as well, and I think I'm culpable
for that :)
cheers
--
Michael Ellerman
OzLabs, IBM Australia Development Lab
wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)
We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person
Hi Paul,
Here are the hotplug memory remove updates for 2.6.25-rc2-mm1.
How have these been tested? Have you initiated a memory remove
operation from the HMC? That's the only way to catch some bugs...
I'm wondering how the memory hot un-plug is initiated on the pseries.
Could you tell me about this HMC? Is it an application running in
the lpar, or is it an external entity?
Is there a 'standard' interface from userspace that can be used to
trigger the hot-unplug sequence? I'm asking because PS3's lv1
hypervisor supports hot un-plug of memory, but it would need to be
triggered from some kind of management application running in in
userspace.
-Geoff
On Fri, 2008-02-29 at 12:03 +1100, Michael Ellerman wrote:
On Thu, 2008-02-28 at 18:39 -0600, Nathan Lynch wrote:
quoted
Michael Ellerman wrote:
quoted
On Thu, 2008-02-28 at 08:46 -0800, Badari Pulavarty wrote:
quoted
Hotplug memory notifier for ppc64. This gets invoked by writing
the device-node that needs to be removed to /proc/ppc64/ofdt.
We need to adjust the sections and remove sysfs entries by
calling __remove_pages(). Then call arch specific code to
get rid of htab mappings for the section of memory.
Signed-off-by: Badari Pulavarty <redacted>
---
arch/powerpc/platforms/pseries/Makefile | 1
arch/powerpc/platforms/pseries/hotplug-memory.c | 98 ++++++++++++++++++++++++
2 files changed, 99 insertions(+)
Index: linux-2.6.25-rc2/arch/powerpc/platforms/pseries/hotplug-memory.c
===================================================================
This is going to fire on non-pseries LPAR platforms, like iSeries and
PS3. Which is not what you want I think.
Well, the notifier will be registered, yes, but it will never be
called because that path is reachable only from a write to
/proc/ppc64/ofdt, which is not created on non-pseries.
Sure. Still seems better not to register it in the first place.
quoted
Maybe it should be
machine_device_initcall(pseries, pseries_memory_hotplug_init);
I think so.
Here is the latest for review. (just to make sure I didn't miss
anything).
Thanks,
Badari
Hotplug memory notifier for ppc64. This gets invoked by writing
the device-node that needs to be removed to /proc/ppc64/ofdt.
We need to adjust the sections and remove sysfs entries by
calling __remove_pages(). Then call arch specific code to
get rid of htab mappings for the section of memory.
Signed-off-by: Badari Pulavarty <redacted>
---
arch/powerpc/platforms/pseries/Makefile | 1
arch/powerpc/platforms/pseries/hotplug-memory.c | 98 ++++++++++++++++++++++++
2 files changed, 99 insertions(+)
Index: linux-2.6.25-rc2/arch/powerpc/platforms/pseries/hotplug-memory.c
===================================================================
Hi,
I am wondering if you could give me your opinion on how to proceed
(before I code too much).
eHEA driver writers wants to know what the memory layout is - where the
holes are and where the reserved memory is. They can get this from
parsing through the device-tree every time, but it would be too
expensive. And also, they would like to get information for contiguous
ranges (instead of 16MB chunks).
Since we already have this information at boot time in lmb.memory,
lmb.reserve - would it be okay to update those for hotplug mem
add/remove ? Of course, all the routines which handles updates
(lmb_add() etc..) are available only at boot (__init). I could
change that. Is it acceptable ?
Other way to handle the issue is to come up with arch-neutral
way of representing the memory layout. x86-64 and ia64 shows
this information in /proc/iomem (even there is in chunks not
combined).
Ideas ? Would it be acceptable if I update lmb.memory for add/remove
memory ? Am I missing something ?
Thanks,
Badari
I'm wondering how the memory hot un-plug is initiated on the pseries.
Could you tell me about this HMC? Is it an application running in
the lpar, or is it an external entity?
The HMC (Hardware Management Console) is a system separate from the
pseries box. It's used to provision and, um, manage, one or more
systems and their partitions. It communicates with both the POWER
hypervisor and some optional userspace daemons and utilities running
on the lpars.
Is there a 'standard' interface from userspace that can be used to
trigger the hot-unplug sequence? I'm asking because PS3's lv1
hypervisor supports hot un-plug of memory, but it would need to be
triggered from some kind of management application running in in
userspace.
I think sysfs is the conventional interface for "offlining" a
resource, that is, getting Linux to stop using it. That's what is
used for cpu online/offline (and memory as well, I think). Releasing
a resource to the hypervisor's control is necessarily a
platform-specific operation; on pseries a userspace utility calls a
set of RTAS methods to accomplish this.
On Fri, 2008-02-29 at 09:56 -0800, Badari Pulavarty wrote:
Hi,
I am wondering if you could give me your opinion on how to proceed
(before I code too much).
eHEA driver writers wants to know what the memory layout is - where the
holes are and where the reserved memory is. They can get this from
parsing through the device-tree every time, but it would be too
expensive. And also, they would like to get information for contiguous
ranges (instead of 16MB chunks).
Since we already have this information at boot time in lmb.memory,
lmb.reserve - would it be okay to update those for hotplug mem
add/remove ? Of course, all the routines which handles updates
(lmb_add() etc..) are available only at boot (__init). I could
change that. Is it acceptable ?
Other way to handle the issue is to come up with arch-neutral
way of representing the memory layout. x86-64 and ia64 shows
this information in /proc/iomem (even there is in chunks not
combined).
Ideas ? Would it be acceptable if I update lmb.memory for add/remove
memory ? Am I missing something ?
Here is what I cooked up and it seems to work fine.
It may be easier to review the code (against my earlier patches).
Thanks,
Badari
ppc kernel maintains information about logical memory blocks in
lmb.memory structure at the boot time. Its not updated for
hotplug memory add/remove. hotplug memory notifier for memory
add/remove now updates lmb.memory.
This information is useful for eHEA driver to find out the memory
layout and holes.
TODO: locking ?
---
arch/powerpc/mm/lmb.c | 61 +++++++++++++++++++++---
arch/powerpc/platforms/pseries/hotplug-memory.c | 42 ++++++++++++++++
include/asm-powerpc/lmb.h | 3 -
3 files changed, 98 insertions(+), 8 deletions(-)
Index: linux-2.6.25-rc2/arch/powerpc/mm/lmb.c
===================================================================
@@ -77,7 +77,7 @@ static long __init lmb_addrs_adjacent(unreturn0;}-staticlong__initlmb_regions_adjacent(structlmb_region*rgn,+staticlonglmb_regions_adjacent(structlmb_region*rgn,unsignedlongr1,unsignedlongr2){unsignedlongbase1=rgn->region[r1].base;
@@ -88,7 +88,7 @@ static long __init lmb_regions_adjacent(returnlmb_addrs_adjacent(base1,size1,base2,size2);}-staticvoid__initlmb_remove_region(structlmb_region*rgn,unsignedlongr)+staticvoidlmb_remove_region(structlmb_region*rgn,unsignedlongr){unsignedlongi;
@@ -100,7 +100,7 @@ static void __init lmb_remove_region(str}/* Assumption: base addr of region 1 < base addr of region 2 */-staticvoid__initlmb_coalesce_regions(structlmb_region*rgn,+staticvoidlmb_coalesce_regions(structlmb_region*rgn,unsignedlongr1,unsignedlongr2){rgn->region[r1].size+=rgn->region[r2].size;
@@ -135,7 +135,7 @@ void __init lmb_analyze(void)}/* This routine called with relocation disabled. */-staticlong__initlmb_add_region(structlmb_region*rgn,unsignedlongbase,+staticlonglmb_add_region(structlmb_region*rgn,unsignedlongbase,unsignedlongsize){unsignedlongcoalesced=0;
@@ -191,7 +191,7 @@ static long __init lmb_add_region(struct}/* This routine may be called with relocation disabled. */-long__initlmb_add(unsignedlongbase,unsignedlongsize)+longlmb_add(unsignedlongbase,unsignedlongsize){structlmb_region*_rgn=&(lmb.memory);
@@ -203,6 +203,53 @@ long __init lmb_add(unsigned long base, }+longlmb_remove(unsignedlongbase,unsignedlongsize)+{+structlmb_region*rgn=&(lmb.memory);+unsignedlongend=base+size;+unsignedlongrgnbegin,rgnend;+inti;++/* Find the region where (base, size) belongs to */+for(i=0;i<rgn->cnt;i++){+rgnbegin=rgn->region[i].base;+rgnend=rgnbegin+rgn->region[i].size;++if((rgnbegin<=base)&&(end<=rgnend))+break;+}++/* Didn't find the region */+if(i==rgn->cnt)+return-1;++/* Check to see if we are removing entire region */+if((rgnbegin==base)&&(rgnend==end)){+lmb_remove_region(rgn,i);+return0;+}++/* Check to see if region is matching at the front */+if(rgnbegin==base){+rgn->region[i].base=end;+rgn->region[i].size-=size;+return0;+}++/* Check to see if the region is matching at the end */+if(rgnend==end){+rgn->region[i].size-=size;+return0;+}++/*+*Weneedtosplittheentry-adjustthecurrentonetothe+*begingingoftheholeandaddtheregionafterhole.+*/+rgn->region[i].size=base-rgn->region[i].base;+returnlmb_add_region(rgn,end,rgnend-end);+}+long__initlmb_reserve(unsignedlongbase,unsignedlongsize){structlmb_region*_rgn=&(lmb.reserved);
From: Stephen Rothwell <hidden> Date: 2008-03-01 02:51:25
On Fri, 29 Feb 2008 09:47:16 -0800 Badari Pulavarty [off-list ref] wrote:
Here is the latest for review. (just to make sure I didn't miss
anything).
Sorry I didn't review the previous ones ... just a small thing.
+ type = of_get_property(np, "device_type", NULL);
To use the of_ accessors, you need to include linux/of.h (currently
asm/prom.h include linux/of.h, but that may not always be true). In
fact, I think you don't even need asm/prom.h.
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
On Fri, 29 Feb 2008 09:47:16 -0800 Badari Pulavarty [off-list ref] wrote:
quoted
Here is the latest for review. (just to make sure I didn't miss
anything).
Sorry I didn't review the previous ones ... just a small thing.
quoted
+ type = of_get_property(np, "device_type", NULL);
To use the of_ accessors, you need to include linux/of.h (currently
asm/prom.h include linux/of.h, but that may not always be true). In
fact, I think you don't even need asm/prom.h.
Yes. linux/of.h is enough. Thank you for pointing it out.
Thanks,
Badari
Here is what I cooked up and it seems to work fine.
It may be easier to review the code (against my earlier patches).
BTW, the lmb code now lives under lib/ (sparc64 will be using it too)
and has several bug fixes applied to it in Paulus's current upstream
tree.
Yes. I noticed that earlier. But it was easy for me to test against
mainline/-mm.
I can easily update it against Paul's tree, if every one is okay with
the changes
I am proposing.
Thanks,
Badari
Yep that looks good.
cheers
--
Michael Ellerman
OzLabs, IBM Australia Development Lab
wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)
We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person
On Thu, 2008-02-28 at 08:46 -0800, Badari Pulavarty wrote:
quoted
Hotplug memory notifier for ppc64. This gets invoked by writing
the device-node that needs to be removed to /proc/ppc64/ofdt.
We need to adjust the sections and remove sysfs entries by
calling __remove_pages(). Then call arch specific code to
get rid of htab mappings for the section of memory.
Signed-off-by: Badari Pulavarty <redacted>
---
arch/powerpc/platforms/pseries/Makefile | 1
arch/powerpc/platforms/pseries/hotplug-memory.c | 98 ++++++++++++++++++++++++
2 files changed, 99 insertions(+)
Index: linux-2.6.25-rc2/arch/powerpc/platforms/pseries/hotplug-memory.c
===================================================================
This is going to fire on non-pseries LPAR platforms, like iSeries and
PS3. Which is not what you want I think.
Well, the notifier will be registered, yes, but it will never be
called because that path is reachable only from a write to
/proc/ppc64/ofdt, which is not created on non-pseries.
Maybe it should be
machine_device_initcall(pseries, pseries_memory_hotplug_init);
(and pseries_cpu_hotplug_init in hotplug-cpu.c should be changed to
machine_arch_initcall)