[RFC][PATCH] remove section mappinng
Badari Pulavarty
pbadari at us.ibm.com
Sat Jan 26 03:05:05 EST 2008
Hi Paul/Ben/Anton,
As part of making memory remove working on ppc64, I need the code to
remove htab mappings for the section of the memory.
Here is the code I cooked up, it seems to be working fine.
But I have concerns where I need your help.
In order to invalidate htab entries, we need to find the "slot".
But I can only find the hpte group. Is it okay to invalidate the
first entry in the group ? Do I need to invalidate the entire group ?
Please help, as I would like to push this for 2.6.25/2.6.26.
Thanks,
Badari
For memory remove, we need to remove htab mapping.
Signed-off-by: Badari Pulavarty <pbadari at us.ibm.com>
---
arch/powerpc/mm/hash_utils_64.c | 32 ++++++++++++++++++++++++++++++++
include/asm-powerpc/sparsemem.h | 1 +
2 files changed, 33 insertions(+)
Index: linux-2.6.24-rc8/arch/powerpc/mm/hash_utils_64.c
===================================================================
--- linux-2.6.24-rc8.orig/arch/powerpc/mm/hash_utils_64.c 2008-01-17 09:47:37.000000000 -0800
+++ linux-2.6.24-rc8/arch/powerpc/mm/hash_utils_64.c 2008-01-25 07:57:48.000000000 -0800
@@ -191,6 +191,33 @@ int htab_bolt_mapping(unsigned long vsta
return ret < 0 ? ret : 0;
}
+static void htab_remove_mapping(unsigned long vstart, unsigned long vend,
+ int psize, int ssize)
+{
+ unsigned long vaddr;
+ unsigned int step, shift;
+
+ shift = mmu_psize_defs[psize].shift;
+ step = 1 << shift;
+
+ for (vaddr = vstart; vaddr < vend; vaddr += step) {
+ unsigned long hash, hpteg;
+ unsigned long vsid = get_kernel_vsid(vaddr, ssize);
+ unsigned long va = hpt_va(vaddr, vsid, ssize);
+
+ hash = hpt_hash(va, shift, ssize);
+ hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP);
+
+ /*
+ * HELP - how do I find the slot ? Is it okay to
+ * invalidates only first entry ? Do I need to
+ * remove entire group instead ?
+ */
+ BUG_ON(!ppc_md.hpte_invalidate);
+ ppc_md.hpte_invalidate(hpteg, va, psize, ssize, 0);
+ }
+}
+
static int __init htab_dt_scan_seg_sizes(unsigned long node,
const char *uname, int depth,
void *data)
@@ -436,6 +463,11 @@ void create_section_mapping(unsigned lon
_PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | PP_RWXX,
mmu_linear_psize, mmu_kernel_ssize));
}
+
+void remove_section_mapping(unsigned long start, unsigned long end)
+{
+ htab_remove_mapping(start, end, mmu_linear_psize, mmu_kernel_ssize);
+}
#endif /* CONFIG_MEMORY_HOTPLUG */
static inline void make_bl(unsigned int *insn_addr, void *func)
Index: linux-2.6.24-rc8/include/asm-powerpc/sparsemem.h
===================================================================
--- linux-2.6.24-rc8.orig/include/asm-powerpc/sparsemem.h 2008-01-15 20:22:48.000000000 -0800
+++ linux-2.6.24-rc8/include/asm-powerpc/sparsemem.h 2008-01-24 16:20:17.000000000 -0800
@@ -20,6 +20,7 @@
#ifdef CONFIG_MEMORY_HOTPLUG
extern void create_section_mapping(unsigned long start, unsigned long end);
+extern void remove_section_mapping(unsigned long start, unsigned long end);
#ifdef CONFIG_NUMA
extern int hot_add_scn_to_nid(unsigned long scn_addr);
#else
More information about the Linuxppc-dev
mailing list