From: David Gibson <hidden> Date: 2016-02-09 03:31:45
The cleanups to the (guest side) memory hotplug paths came up in the
context of allowing hash page table resizing for PAPR guests.
However, they stand on their own and can improve reporting of several
error conditions that could already happen.
Please apply.
David Gibson (4):
powerpc/mm: Clean up error handling for htab_remove_mapping
powerpc/mm: Handle removing maybe-present bolted HPTEs
powerpc/mm: Clean up memory hotplug failure paths
powerpc/mm: Split hash page table sizing heuristic into a helper
arch/powerpc/include/asm/machdep.h | 2 +-
arch/powerpc/include/asm/mmu-hash64.h | 3 ++
arch/powerpc/mm/hash_utils_64.c | 73 ++++++++++++++++++++++-------------
arch/powerpc/mm/init_64.c | 47 ++++++++++++++--------
arch/powerpc/mm/mem.c | 10 ++++-
arch/powerpc/platforms/pseries/lpar.c | 9 +++--
6 files changed, 96 insertions(+), 48 deletions(-)
--
2.5.0
From: David Gibson <hidden> Date: 2016-02-09 03:31:46
Currently, the only error that htab_remove_mapping() can report is -EINVAL,
if removal of bolted HPTEs isn't implemeted for this platform. We make
a few clean ups to the handling of this:
* EINVAL isn't really the right code - there's nothing wrong with the
function's arguments - use ENODEV instead
* We were also printing a warning message, but that's a decision better
left up to the callers, so remove it
* One caller is vmemmap_remove_mapping(), which will just BUG_ON() on
error, making the warning message redundant, so no change is needed
there.
* The other caller is remove_section_mapping(). This is called in the
memory hot remove path at a point after vmemmap_remove_mapping() so
if hpte_removebolted isn't implemented, we'd expect to have already
BUG()ed anyway. Put a WARN_ON() here, in lieu of a printk() since this
really shouldn't be happening.
Signed-off-by: David Gibson <redacted>
---
arch/powerpc/mm/hash_utils_64.c | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
@@ -273,11 +273,8 @@ int htab_remove_mapping(unsigned long vstart, unsigned long vend,shift=mmu_psize_defs[psize].shift;step=1<<shift;-if(!ppc_md.hpte_removebolted){-printk(KERN_WARNING"Platform doesn't implement "-"hpte_removebolted\n");-return-EINVAL;-}+if(!ppc_md.hpte_removebolted)+return-ENODEV;for(vaddr=vstart;vaddr<vend;vaddr+=step)ppc_md.hpte_removebolted(vaddr,psize,ssize);
@@ -641,8 +638,10 @@ int create_section_mapping(unsigned long start, unsigned long end)intremove_section_mapping(unsignedlongstart,unsignedlongend){-returnhtab_remove_mapping(start,end,mmu_linear_psize,-mmu_kernel_ssize);+intrc=htab_remove_mapping(start,end,mmu_linear_psize,+mmu_kernel_ssize);+WARN_ON(rc<0);+returnrc;}#endif /* CONFIG_MEMORY_HOTPLUG */
From: David Gibson <hidden> Date: 2016-02-09 03:34:48
htab_get_table_size() either retrieve the size of the hash page table (HPT)
from the device tree - if the HPT size is determined by firmware - or
uses a heuristic to determine a good size based on RAM size if the kernel
is responsible for allocating the HPT.
To support a PAPR extension allowing resizing of the HPT, we're going to
want the memory size -> HPT size logic elsewhere, so split it out into a
helper function.
Signed-off-by: David Gibson <redacted>
---
arch/powerpc/include/asm/mmu-hash64.h | 3 +++
arch/powerpc/mm/hash_utils_64.c | 32 +++++++++++++++++++-------------
2 files changed, 22 insertions(+), 13 deletions(-)
@@ -611,10 +611,26 @@ static int __init htab_dt_scan_pftsize(unsigned long node,return0;}-staticunsignedlong__inithtab_get_table_size(void)+unsignedhtab_shift_for_mem_size(unsignedlongmem_size){-unsignedlongmem_size,rnd_mem_size,pteg_count,psize;+unsignedmemshift=__ilog2(mem_size);+unsignedpshift=mmu_psize_defs[mmu_virtual_psize].shift;+unsignedpteg_shift;++/* round mem_size up to next power of 2 */+if((1UL<<memshift)<mem_size)+memshift+=1;++/* aim for 2 pages / pteg */+pteg_shift=memshift-(pshift+1);++/* 2^11 PTEGS / 2^18 bytes is the minimum htab size permitted+*bythearchitecture*/+returnmax(pteg_shift+7,18U);+}+staticunsignedlong__inithtab_get_table_size(void)+{/* If hash size isn't already provided by the platform, we try to*retrieveitfromthedevice-tree.Ifit'snotthereneither,we*calculateitnowbasedonthetotalRAMsize
@@ -624,17 +640,7 @@ static unsigned long __init htab_get_table_size(void)if(ppc64_pft_size)return1UL<<ppc64_pft_size;-/* round mem_size up to next power of 2 */-mem_size=memblock_phys_mem_size();-rnd_mem_size=1UL<<__ilog2(mem_size);-if(rnd_mem_size<mem_size)-rnd_mem_size<<=1;--/* # pages / 2 */-psize=mmu_psize_defs[mmu_virtual_psize].shift;-pteg_count=max(rnd_mem_size>>(psize+1),1UL<<11);--returnpteg_count<<7;+return1UL<<htab_shift_for_mem_size(memblock_phys_mem_size());}#ifdef CONFIG_MEMORY_HOTPLUG
From: David Gibson <hidden> Date: 2016-02-09 03:34:49
This makes a number of cleanups to handling of mapping failures during
memory hotplug on Power:
For errors creating the linear mapping for the hot-added region:
* This is now reported with EFAULT which is more appropriate than the
previous EINVAL (the failure is unlikely to be related to the
function's parameters)
* An error in this path now prints a warning message, rather than just
silently failing to add the extra memory.
* Previously a failure here could result in the region being partially
mapped. We now clean up any partial mapping before failing.
For errors creating the vmemmap for the hot-added region:
* This is now reported with EFAULT instead of causing a BUG() - this
could happen for external reason (e.g. full hash table) so it's better
to handle this non-fatally
* An error message is also printed, so the failure won't be silent
* As above a failure could cause a partially mapped region, we now
clean this up.
Signed-off-by: David Gibson <redacted>
Reviewed-by: Paul Mackerras <redacted>
---
arch/powerpc/mm/hash_utils_64.c | 13 ++++++++++---
arch/powerpc/mm/init_64.c | 38 ++++++++++++++++++++++++++------------
arch/powerpc/mm/mem.c | 10 ++++++++--
3 files changed, 44 insertions(+), 17 deletions(-)
@@ -188,9 +188,9 @@ static int __meminit vmemmap_populated(unsigned long start, int page_size)*/#ifdef CONFIG_PPC_BOOK3E-staticvoid__meminitvmemmap_create_mapping(unsignedlongstart,-unsignedlongpage_size,-unsignedlongphys)+staticint__meminitvmemmap_create_mapping(unsignedlongstart,+unsignedlongpage_size,+unsignedlongphys){/* Create a PTE encoding without page size */unsignedlongi,flags=_PAGE_PRESENT|_PAGE_ACCESSED|
@@ -304,6 +311,7 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node)for(;start<end;start+=page_size){void*p;+intrc;if(vmemmap_populated(start,page_size))continue;
@@ -317,7 +325,13 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node)pr_debug(" * %016lx..%016lx allocated at %p\n",start,start+page_size,p);-vmemmap_create_mapping(start,page_size,__pa(p));+rc=vmemmap_create_mapping(start,page_size,__pa(p));+if(rc<0){+pr_warning(+"vmemmap_populate: Unable to create vmemmap mapping: %d\n",+rc);+return-EFAULT;+}}return0;
@@ -119,12 +119,18 @@ int arch_add_memory(int nid, u64 start, u64 size, bool for_device)structzone*zone;unsignedlongstart_pfn=start>>PAGE_SHIFT;unsignedlongnr_pages=size>>PAGE_SHIFT;+intrc;pgdata=NODE_DATA(nid);start=(unsignedlong)__va(start);-if(create_section_mapping(start,start+size))-return-EINVAL;+rc=create_section_mapping(start,start+size);+if(rc){+pr_warning(+"Unable to create mapping for hot added memory 0x%llx..0x%llx: %d\n",+start,start+size,rc);+return-EFAULT;+}/* this should work for most non-highmem platforms */zone=pgdata->node_zones+
From: David Gibson <hidden> Date: 2016-02-09 03:34:51
At the moment the hpte_removebolted callback in ppc_md returns void and
will BUG_ON() if the hpte it's asked to remove doesn't exist in the first
place. This is awkward for the case of cleaning up a mapping which was
partially made before failing.
So, we add a return value to hpte_removebolted, and have it return ENOENT
in the case that the HPTE to remove didn't exist in the first place.
In the (sole) caller, we propagate errors in hpte_removebolted to its
caller to handle. However, we handle ENOENT specially, continuing to
complete the unmapping over the specified range before returning the error
to the caller.
This means that htab_remove_mapping() will work sanely on a partially
present mapping, removing any HPTEs which are present, while also returning
ENOENT to its caller in case it's important there.
There are two callers of htab_remove_mapping():
- In remove_section_mapping() we already WARN_ON() any error return,
which is reasonable - in this case the mapping should be fully
present
- In vmemmap_remove_mapping() we BUG_ON() any error. We change that to
just a WARN_ON() in the case of ENOENT, since failing to remove a
mapping that wasn't there in the first place probably shouldn't be
fatal.
Signed-off-by: David Gibson <redacted>
---
arch/powerpc/include/asm/machdep.h | 2 +-
arch/powerpc/mm/hash_utils_64.c | 15 ++++++++++++---
arch/powerpc/mm/init_64.c | 9 +++++----
arch/powerpc/platforms/pseries/lpar.c | 9 ++++++---
4 files changed, 24 insertions(+), 11 deletions(-)
@@ -269,6 +269,8 @@ int htab_remove_mapping(unsigned long vstart, unsigned long vend,{unsignedlongvaddr;unsignedintstep,shift;+intrc;+intret=0;shift=mmu_psize_defs[psize].shift;step=1<<shift;
@@ -276,10 +278,17 @@ int htab_remove_mapping(unsigned long vstart, unsigned long vend,if(!ppc_md.hpte_removebolted)return-ENODEV;-for(vaddr=vstart;vaddr<vend;vaddr+=step)-ppc_md.hpte_removebolted(vaddr,psize,ssize);+for(vaddr=vstart;vaddr<vend;vaddr+=step){+rc=ppc_md.hpte_removebolted(vaddr,psize,ssize);+if(rc==-ENOENT){+ret=-ENOENT;+continue;+}+if(rc<0)+returnrc;+}-return0;+returnret;}#endif /* CONFIG_MEMORY_HOTPLUG */
Currently, the only error that htab_remove_mapping() can report is -EINVAL,
if removal of bolted HPTEs isn't implemeted for this platform. We make
a few clean ups to the handling of this:
* EINVAL isn't really the right code - there's nothing wrong with the
function's arguments - use ENODEV instead
* We were also printing a warning message, but that's a decision better
left up to the callers, so remove it
* One caller is vmemmap_remove_mapping(), which will just BUG_ON() on
error, making the warning message redundant, so no change is needed
there.
* The other caller is remove_section_mapping(). This is called in the
memory hot remove path at a point after vmemmap_remove_mapping() so
if hpte_removebolted isn't implemented, we'd expect to have already
BUG()ed anyway. Put a WARN_ON() here, in lieu of a printk() since this
really shouldn't be happening.
@@ -273,11 +273,8 @@ int htab_remove_mapping(unsigned long vstart, unsigned long vend,shift=mmu_psize_defs[psize].shift;step=1<<shift;-if(!ppc_md.hpte_removebolted){-printk(KERN_WARNING"Platform doesn't implement "-"hpte_removebolted\n");-return-EINVAL;-}+if(!ppc_md.hpte_removebolted)+return-ENODEV;for(vaddr=vstart;vaddr<vend;vaddr+=step)ppc_md.hpte_removebolted(vaddr,psize,ssize);
@@ -641,8 +638,10 @@ int create_section_mapping(unsigned long start, unsigned long end)intremove_section_mapping(unsignedlongstart,unsignedlongend){-returnhtab_remove_mapping(start,end,mmu_linear_psize,-mmu_kernel_ssize);+intrc=htab_remove_mapping(start,end,mmu_linear_psize,+mmu_kernel_ssize);+WARN_ON(rc<0);+returnrc;}#endif /* CONFIG_MEMORY_HOTPLUG */
At the moment the hpte_removebolted callback in ppc_md returns void and
will BUG_ON() if the hpte it's asked to remove doesn't exist in the first
place. This is awkward for the case of cleaning up a mapping which was
partially made before failing.
So, we add a return value to hpte_removebolted, and have it return ENOENT
in the case that the HPTE to remove didn't exist in the first place.
In the (sole) caller, we propagate errors in hpte_removebolted to its
caller to handle. However, we handle ENOENT specially, continuing to
complete the unmapping over the specified range before returning the error
to the caller.
This means that htab_remove_mapping() will work sanely on a partially
present mapping, removing any HPTEs which are present, while also returning
ENOENT to its caller in case it's important there.
There are two callers of htab_remove_mapping():
- In remove_section_mapping() we already WARN_ON() any error return,
which is reasonable - in this case the mapping should be fully
present
- In vmemmap_remove_mapping() we BUG_ON() any error. We change that to
just a WARN_ON() in the case of ENOENT, since failing to remove a
mapping that wasn't there in the first place probably shouldn't be
fatal.
@@ -269,6 +269,8 @@ int htab_remove_mapping(unsigned long vstart, unsigned long vend,{unsignedlongvaddr;unsignedintstep,shift;+intrc;+intret=0;shift=mmu_psize_defs[psize].shift;step=1<<shift;
@@ -276,10 +278,17 @@ int htab_remove_mapping(unsigned long vstart, unsigned long vend,if(!ppc_md.hpte_removebolted)return-ENODEV;-for(vaddr=vstart;vaddr<vend;vaddr+=step)-ppc_md.hpte_removebolted(vaddr,psize,ssize);+for(vaddr=vstart;vaddr<vend;vaddr+=step){+rc=ppc_md.hpte_removebolted(vaddr,psize,ssize);+if(rc==-ENOENT){+ret=-ENOENT;+continue;+}+if(rc<0)+returnrc;+}-return0;+returnret;}#endif /* CONFIG_MEMORY_HOTPLUG */
This makes a number of cleanups to handling of mapping failures during
memory hotplug on Power:
For errors creating the linear mapping for the hot-added region:
* This is now reported with EFAULT which is more appropriate than the
previous EINVAL (the failure is unlikely to be related to the
function's parameters)
* An error in this path now prints a warning message, rather than just
silently failing to add the extra memory.
* Previously a failure here could result in the region being partially
mapped. We now clean up any partial mapping before failing.
For errors creating the vmemmap for the hot-added region:
* This is now reported with EFAULT instead of causing a BUG() - this
could happen for external reason (e.g. full hash table) so it's better
to handle this non-fatally
* An error message is also printed, so the failure won't be silent
* As above a failure could cause a partially mapped region, we now
clean this up.
@@ -188,9 +188,9 @@ static int __meminit vmemmap_populated(unsigned long start, int page_size)*/#ifdef CONFIG_PPC_BOOK3E-staticvoid__meminitvmemmap_create_mapping(unsignedlongstart,-unsignedlongpage_size,-unsignedlongphys)+staticint__meminitvmemmap_create_mapping(unsignedlongstart,+unsignedlongpage_size,+unsignedlongphys){/* Create a PTE encoding without page size */unsignedlongi,flags=_PAGE_PRESENT|_PAGE_ACCESSED|
@@ -304,6 +311,7 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node)for(;start<end;start+=page_size){void*p;+intrc;if(vmemmap_populated(start,page_size))continue;
@@ -317,7 +325,13 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node)pr_debug(" * %016lx..%016lx allocated at %p\n",start,start+page_size,p);-vmemmap_create_mapping(start,page_size,__pa(p));+rc=vmemmap_create_mapping(start,page_size,__pa(p));+if(rc<0){+pr_warning(+"vmemmap_populate: Unable to create vmemmap mapping: %d\n",+rc);+return-EFAULT;+}}return0;
@@ -119,12 +119,18 @@ int arch_add_memory(int nid, u64 start, u64 size, bool for_device)structzone*zone;unsignedlongstart_pfn=start>>PAGE_SHIFT;unsignedlongnr_pages=size>>PAGE_SHIFT;+intrc;pgdata=NODE_DATA(nid);start=(unsignedlong)__va(start);-if(create_section_mapping(start,start+size))-return-EINVAL;+rc=create_section_mapping(start,start+size);+if(rc){+pr_warning(+"Unable to create mapping for hot added memory 0x%llx..0x%llx: %d\n",+start,start+size,rc);+return-EFAULT;+}/* this should work for most non-highmem platforms */zone=pgdata->node_zones+
--
2.5.0
_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev
htab_get_table_size() either retrieve the size of the hash page table (HPT)
from the device tree - if the HPT size is determined by firmware - or
uses a heuristic to determine a good size based on RAM size if the kernel
is responsible for allocating the HPT.
To support a PAPR extension allowing resizing of the HPT, we're going to
want the memory size -> HPT size logic elsewhere, so split it out into a
helper function.
@@ -611,10 +611,26 @@ static int __init htab_dt_scan_pftsize(unsigned long node,return0;}-staticunsignedlong__inithtab_get_table_size(void)+unsignedhtab_shift_for_mem_size(unsignedlongmem_size){-unsignedlongmem_size,rnd_mem_size,pteg_count,psize;+unsignedmemshift=__ilog2(mem_size);+unsignedpshift=mmu_psize_defs[mmu_virtual_psize].shift;+unsignedpteg_shift;++/* round mem_size up to next power of 2 */+if((1UL<<memshift)<mem_size)+memshift+=1;++/* aim for 2 pages / pteg */+pteg_shift=memshift-(pshift+1);++/* 2^11 PTEGS / 2^18 bytes is the minimum htab size permitted+*bythearchitecture*/+returnmax(pteg_shift+7,18U);+}+staticunsignedlong__inithtab_get_table_size(void)+{/* If hash size isn't already provided by the platform, we try to*retrieveitfromthedevice-tree.Ifit'snotthereneither,we*calculateitnowbasedonthetotalRAMsize
@@ -624,17 +640,7 @@ static unsigned long __init htab_get_table_size(void)if(ppc64_pft_size)return1UL<<ppc64_pft_size;-/* round mem_size up to next power of 2 */-mem_size=memblock_phys_mem_size();-rnd_mem_size=1UL<<__ilog2(mem_size);-if(rnd_mem_size<mem_size)-rnd_mem_size<<=1;--/* # pages / 2 */-psize=mmu_psize_defs[mmu_virtual_psize].shift;-pteg_count=max(rnd_mem_size>>(psize+1),1UL<<11);--returnpteg_count<<7;+return1UL<<htab_shift_for_mem_size(memblock_phys_mem_size());}#ifdef CONFIG_MEMORY_HOTPLUG
From: Michael Ellerman <mpe@ellerman.id.au> Date: 2016-03-01 01:59:11
On Tue, 2016-09-02 at 03:32:42 UTC, David Gibson wrote:
This makes a number of cleanups to handling of mapping failures during
memory hotplug on Power:
For errors creating the linear mapping for the hot-added region:
* This is now reported with EFAULT which is more appropriate than the
previous EINVAL (the failure is unlikely to be related to the
function's parameters)
* An error in this path now prints a warning message, rather than just
silently failing to add the extra memory.
* Previously a failure here could result in the region being partially
mapped. We now clean up any partial mapping before failing.
For errors creating the vmemmap for the hot-added region:
* This is now reported with EFAULT instead of causing a BUG() - this
could happen for external reason (e.g. full hash table) so it's better
to handle this non-fatally
* An error message is also printed, so the failure won't be silent
* As above a failure could cause a partially mapped region, we now
clean this up.
This breaks the build when CONFIG_MEMORY_HOTPLUG=n, because
htab_remove_mapping() is not defined.
The obvious fix of moving htab_remove_mapping() out of CONFIG_MEMORY_HOTPLUG
works, so I'll do that unless anyone objects.
cheers
From: David Gibson <hidden> Date: 2016-03-01 02:28:16
On Tue, Mar 01, 2016 at 12:59:07PM +1100, Michael Ellerman wrote:
On Tue, 2016-09-02 at 03:32:42 UTC, David Gibson wrote:
quoted
This makes a number of cleanups to handling of mapping failures during
memory hotplug on Power:
For errors creating the linear mapping for the hot-added region:
* This is now reported with EFAULT which is more appropriate than the
previous EINVAL (the failure is unlikely to be related to the
function's parameters)
* An error in this path now prints a warning message, rather than just
silently failing to add the extra memory.
* Previously a failure here could result in the region being partially
mapped. We now clean up any partial mapping before failing.
For errors creating the vmemmap for the hot-added region:
* This is now reported with EFAULT instead of causing a BUG() - this
could happen for external reason (e.g. full hash table) so it's better
to handle this non-fatally
* An error message is also printed, so the failure won't be silent
* As above a failure could cause a partially mapped region, we now
clean this up.
This breaks the build when CONFIG_MEMORY_HOTPLUG=n, because
htab_remove_mapping() is not defined.
The obvious fix of moving htab_remove_mapping() out of CONFIG_MEMORY_HOTPLUG
works, so I'll do that unless anyone objects.
Sounds good, thanks for the catch.
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
From: Michael Ellerman <mpe@ellerman.id.au> Date: 2016-03-01 22:21:21
On Tue, 2016-09-02 at 03:32:40 UTC, David Gibson wrote:
Currently, the only error that htab_remove_mapping() can report is -EINVAL,
if removal of bolted HPTEs isn't implemeted for this platform. We make
a few clean ups to the handling of this:
* EINVAL isn't really the right code - there's nothing wrong with the
function's arguments - use ENODEV instead
* We were also printing a warning message, but that's a decision better
left up to the callers, so remove it
* One caller is vmemmap_remove_mapping(), which will just BUG_ON() on
error, making the warning message redundant, so no change is needed
there.
* The other caller is remove_section_mapping(). This is called in the
memory hot remove path at a point after vmemmap_remove_mapping() so
if hpte_removebolted isn't implemented, we'd expect to have already
BUG()ed anyway. Put a WARN_ON() here, in lieu of a printk() since this
really shouldn't be happening.
Signed-off-by: David Gibson <redacted>
Reviewed-by: Aneesh Kumar K.V <redacted>
From: Michael Ellerman <mpe@ellerman.id.au> Date: 2016-03-01 22:21:43
On Tue, 2016-09-02 at 03:32:43 UTC, David Gibson wrote:
htab_get_table_size() either retrieve the size of the hash page table (HPT)
from the device tree - if the HPT size is determined by firmware - or
uses a heuristic to determine a good size based on RAM size if the kernel
is responsible for allocating the HPT.
To support a PAPR extension allowing resizing of the HPT, we're going to
want the memory size -> HPT size logic elsewhere, so split it out into a
helper function.
Signed-off-by: David Gibson <redacted>
Reviewed-by: Aneesh Kumar K.V <redacted>
Applied to powerpc next, thanks.
https://git.kernel.org/powerpc/c/5c3c7ede2bdcb85fa2fd51c814
I reworded one comment a little, from:
/* 2^11 PTEGS / 2^18 bytes is the minimum htab size permitted
* by the architecture */
to:
/*
* 2^11 PTEGS of 128 bytes each, ie. 2^18 bytes is the minimum htab
* size permitted by the architecture.
*/
To avoid any confusion about the "/" referring to division.
cheers
From: Michael Ellerman <mpe@ellerman.id.au> Date: 2016-03-01 22:21:56
On Tue, 2016-09-02 at 03:32:41 UTC, David Gibson wrote:
At the moment the hpte_removebolted callback in ppc_md returns void and
will BUG_ON() if the hpte it's asked to remove doesn't exist in the first
place. This is awkward for the case of cleaning up a mapping which was
partially made before failing.
So, we add a return value to hpte_removebolted, and have it return ENOENT
in the case that the HPTE to remove didn't exist in the first place.
In the (sole) caller, we propagate errors in hpte_removebolted to its
caller to handle. However, we handle ENOENT specially, continuing to
complete the unmapping over the specified range before returning the error
to the caller.
This means that htab_remove_mapping() will work sanely on a partially
present mapping, removing any HPTEs which are present, while also returning
ENOENT to its caller in case it's important there.
There are two callers of htab_remove_mapping():
- In remove_section_mapping() we already WARN_ON() any error return,
which is reasonable - in this case the mapping should be fully
present
- In vmemmap_remove_mapping() we BUG_ON() any error. We change that to
just a WARN_ON() in the case of ENOENT, since failing to remove a
mapping that wasn't there in the first place probably shouldn't be
fatal.
Signed-off-by: David Gibson <redacted>
Reviewed-by: Aneesh Kumar K.V <redacted>
From: Michael Ellerman <mpe@ellerman.id.au> Date: 2016-03-01 22:23:09
On Tue, 2016-09-02 at 03:32:42 UTC, David Gibson wrote:
This makes a number of cleanups to handling of mapping failures during
memory hotplug on Power:
For errors creating the linear mapping for the hot-added region:
* This is now reported with EFAULT which is more appropriate than the
previous EINVAL (the failure is unlikely to be related to the
function's parameters)
* An error in this path now prints a warning message, rather than just
silently failing to add the extra memory.
* Previously a failure here could result in the region being partially
mapped. We now clean up any partial mapping before failing.
For errors creating the vmemmap for the hot-added region:
* This is now reported with EFAULT instead of causing a BUG() - this
could happen for external reason (e.g. full hash table) so it's better
to handle this non-fatally
* An error message is also printed, so the failure won't be silent
* As above a failure could cause a partially mapped region, we now
clean this up.
Signed-off-by: David Gibson <redacted>
Reviewed-by: Paul Mackerras <redacted>
Reviewed-by: Aneesh Kumar K.V <redacted>
From: David Gibson <hidden> Date: 2016-03-01 23:25:38
On Wed, Mar 02, 2016 at 09:21:19AM +1100, Michael Ellerman wrote:
On Tue, 2016-09-02 at 03:32:43 UTC, David Gibson wrote:
quoted
htab_get_table_size() either retrieve the size of the hash page table (HPT)
from the device tree - if the HPT size is determined by firmware - or
uses a heuristic to determine a good size based on RAM size if the kernel
is responsible for allocating the HPT.
To support a PAPR extension allowing resizing of the HPT, we're going to
want the memory size -> HPT size logic elsewhere, so split it out into a
helper function.
Signed-off-by: David Gibson <redacted>
Reviewed-by: Aneesh Kumar K.V <redacted>
Applied to powerpc next, thanks.
https://git.kernel.org/powerpc/c/5c3c7ede2bdcb85fa2fd51c814
I reworded one comment a little, from:
/* 2^11 PTEGS / 2^18 bytes is the minimum htab size permitted
* by the architecture */
to:
/*
* 2^11 PTEGS of 128 bytes each, ie. 2^18 bytes is the minimum htab
* size permitted by the architecture.
*/
To avoid any confusion about the "/" referring to division.
Good call, thanks.
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson