On 01/28/2016 11:23 PM, 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 <da...@gibson.dropbear.id.au> > --- > 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(-) > > diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c > index 0737eae..e88a86e 100644 > --- a/arch/powerpc/mm/hash_utils_64.c > +++ b/arch/powerpc/mm/hash_utils_64.c > @@ -635,9 +635,16 @@ static unsigned long __init htab_get_table_size(void) > #ifdef CONFIG_MEMORY_HOTPLUG > int create_section_mapping(unsigned long start, unsigned long end) > { > - return htab_bolt_mapping(start, end, __pa(start), > - pgprot_val(PAGE_KERNEL), mmu_linear_psize, > - mmu_kernel_ssize); > + int rc = htab_bolt_mapping(start, end, __pa(start), > + pgprot_val(PAGE_KERNEL), mmu_linear_psize, > + mmu_kernel_ssize); > + > + if (rc < 0) { > + int rc2 = htab_remove_mapping(start, end, mmu_linear_psize, > + mmu_kernel_ssize); > + BUG_ON(rc2 && (rc2 != -ENOENT)); > + } > + return rc; > } >
<-- snip --> > #ifdef CONFIG_MEMORY_HOTPLUG > @@ -217,15 +219,20 @@ static void vmemmap_remove_mapping(unsigned long start, > } > #endif > #else /* CONFIG_PPC_BOOK3E */ > -static void __meminit vmemmap_create_mapping(unsigned long start, > - unsigned long page_size, > - unsigned long phys) > +static int __meminit vmemmap_create_mapping(unsigned long start, > + unsigned long page_size, > + unsigned long phys) > { > - int mapped = htab_bolt_mapping(start, start + page_size, phys, > - pgprot_val(PAGE_KERNEL), > - mmu_vmemmap_psize, > - mmu_kernel_ssize); > - BUG_ON(mapped < 0); > + int rc = htab_bolt_mapping(start, start + page_size, phys, > + pgprot_val(PAGE_KERNEL), > + mmu_vmemmap_psize, mmu_kernel_ssize); > + if (rc < 0) { > + int rc2 = htab_remove_mapping(start, start + page_size, > + mmu_vmemmap_psize, > + mmu_kernel_ssize); > + BUG_ON(rc2 && (rc2 != -ENOENT)); > + } > + return rc; > } > If I'm reading this correctly it appears that create_section_mapping() and vmemmap_create_mapping() for !PPC_BOOK3E are identical. Any reason to not have one routine, perhaps just have vmemmap_create_mapping() just call create_section_mapping()? -Nathan _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev