Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1320244 > unrolled thread
| Started by | David Gibson <david@gibson.dropbear.id.au> |
|---|---|
| First post | 2016-01-28 03:50 +0100 |
| Last post | 2016-01-28 03:50 +0100 |
| Articles | 2 — 1 participant |
Back to article view | Back to linux.kernel
[PATCH 0/4] powerpc: Memory hotplug cleanups David Gibson <david@gibson.dropbear.id.au> - 2016-01-28 03:50 +0100
[PATCH 2/4] arch/powerpc: Handle removing maybe-present bolted HPTEs David Gibson <david@gibson.dropbear.id.au> - 2016-01-28 03:50 +0100
| From | David Gibson <david@gibson.dropbear.id.au> |
|---|---|
| Date | 2016-01-28 03:50 +0100 |
| Subject | [PATCH 0/4] powerpc: Memory hotplug cleanups |
| Message-ID | <qVKOK-4TF-9@gated-at.bofh.it> |
These are some fairly straightforward cleanups to the memory hotplug paths on powerpc. Mostly it deals with more graceful handling of failure cases. This series is a soft prerequisite for my patches for HPT resizing on pseries. David Gibson (4): arch/powerpc: Clean up error handling for htab_remove_mapping arch/powerpc: Handle removing maybe-present bolted HPTEs arch/powerpc: Clean up memory hotplug failure paths arch/powerpc: 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 | 66 +++++++++++++++++++++-------------- arch/powerpc/mm/init_64.c | 47 ++++++++++++++++--------- arch/powerpc/mm/mem.c | 10 ++++-- arch/powerpc/platforms/pseries/lpar.c | 7 ++-- 6 files changed, 88 insertions(+), 47 deletions(-) -- 2.5.0
[toc] | [next] | [standalone]
| From | David Gibson <david@gibson.dropbear.id.au> |
|---|---|
| Date | 2016-01-28 03:50 +0100 |
| Subject | [PATCH 2/4] arch/powerpc: Handle removing maybe-present bolted HPTEs |
| Message-ID | <qVKOK-4TF-19@gated-at.bofh.it> |
| In reply to | #1320244 |
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 reutrn 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 <david@gibson.dropbear.id.au>
---
arch/powerpc/include/asm/machdep.h | 2 +-
arch/powerpc/mm/hash_utils_64.c | 10 +++++++---
arch/powerpc/mm/init_64.c | 9 +++++----
arch/powerpc/platforms/pseries/lpar.c | 7 +++++--
4 files changed, 18 insertions(+), 10 deletions(-)
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
index 3f191f5..a7d3f66 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -54,7 +54,7 @@ struct machdep_calls {
int psize, int apsize,
int ssize);
long (*hpte_remove)(unsigned long hpte_group);
- void (*hpte_removebolted)(unsigned long ea,
+ long (*hpte_removebolted)(unsigned long ea,
int psize, int ssize);
void (*flush_hash_range)(unsigned long number, int local);
void (*hugepage_invalidate)(unsigned long vsid,
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index 9f7d727..0737eae 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -269,6 +269,7 @@ int htab_remove_mapping(unsigned long vstart, unsigned long vend,
{
unsigned long vaddr;
unsigned int step, shift;
+ int rc = 0;
shift = mmu_psize_defs[psize].shift;
step = 1 << shift;
@@ -276,10 +277,13 @@ 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 < 0) && (rc != -ENOENT))
+ return rc;
+ }
- return 0;
+ return rc;
}
#endif /* CONFIG_MEMORY_HOTPLUG */
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
index 379a6a9..baa1a23 100644
--- a/arch/powerpc/mm/init_64.c
+++ b/arch/powerpc/mm/init_64.c
@@ -232,10 +232,11 @@ static void __meminit vmemmap_create_mapping(unsigned long start,
static void vmemmap_remove_mapping(unsigned long start,
unsigned long page_size)
{
- int mapped = htab_remove_mapping(start, start + page_size,
- mmu_vmemmap_psize,
- mmu_kernel_ssize);
- BUG_ON(mapped < 0);
+ int rc = htab_remove_mapping(start, start + page_size,
+ mmu_vmemmap_psize,
+ mmu_kernel_ssize);
+ BUG_ON((rc < 0) && (rc != -ENOENT));
+ WARN_ON(rc == -ENOENT);
}
#endif
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index 477290a..92d472d 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -505,7 +505,7 @@ static void pSeries_lpar_hugepage_invalidate(unsigned long vsid,
}
#endif
-static void pSeries_lpar_hpte_removebolted(unsigned long ea,
+static long pSeries_lpar_hpte_removebolted(unsigned long ea,
int psize, int ssize)
{
unsigned long vpn;
@@ -515,11 +515,14 @@ static void pSeries_lpar_hpte_removebolted(unsigned long ea,
vpn = hpt_vpn(ea, vsid, ssize);
slot = pSeries_lpar_hpte_find(vpn, psize, ssize);
- BUG_ON(slot == -1);
+ if (slot == -1)
+ return -ENOENT;
+
/*
* lpar doesn't use the passed actual page size
*/
pSeries_lpar_hpte_invalidate(slot, vpn, psize, 0, ssize, 0);
+ return 0;
}
/*
--
2.5.0
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web