[PATCH] htab code cleanup
Stephen Rothwell
sfr at canb.auug.org.au
Wed Jan 19 15:48:57 EST 2005
On Sun, 16 Jan 2005 09:36:37 +1100 Benjamin Herrenschmidt <benh at kernel.crashing.org> wrote:
>
> On Thu, 2005-01-06 at 14:51 +1100, Stephen Rothwell wrote:
> > Hi all,
> >
> > This patch just does some small clean ups on the hash page table code
> > - make htab_address static with in htab_native.c
> > - move some code that depended on CONFIG_PPC_MULTIPLATFORM
> > from htab_utils.c to htab_native.c (on less CONFIG check).
> > - clean up includes in htab_utils.c
>
> I don't see the point of moving create_pte_mapping() and
> htab_initialize() to htab_native.c since it contains code for both
> native and non-native...
>
> If you want to get rid of the htab_address, then maybe split
> htab_initialize in bits... like htab_native_init() and htab_plpar_init()
> for the early ptr setup, that sort of thing ...
OK, how about this one, then? This has been built and booted on
iSeries, pSeries (bare metal and lpar) and a G5 (with and without iommu).
--
Cheers,
Stephen Rothwell sfr at canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
diff -ruN linus-bk.new/arch/ppc64/kernel/iSeries_setup.c linus-bk-sfr.14.new/arch/ppc64/kernel/iSeries_setup.c
--- linus-bk.new/arch/ppc64/kernel/iSeries_setup.c 2005-01-09 10:05:39.000000000 +1100
+++ linus-bk-sfr.14.new/arch/ppc64/kernel/iSeries_setup.c 2005-01-18 16:46:06.000000000 +1100
@@ -477,12 +477,6 @@
htab_hash_mask = num_ptegs - 1;
/*
- * The actual hashed page table is in the hypervisor,
- * we have no direct access
- */
- htab_address = NULL;
-
- /*
* Determine if absolute memory has any
* holes so that we can interpret the
* access map we get back from the hypervisor
diff -ruN linus-bk.new/arch/ppc64/kernel/setup.c linus-bk-sfr.14.new/arch/ppc64/kernel/setup.c
--- linus-bk.new/arch/ppc64/kernel/setup.c 2005-01-09 10:05:39.000000000 +1100
+++ linus-bk-sfr.14.new/arch/ppc64/kernel/setup.c 2005-01-18 16:46:23.000000000 +1100
@@ -674,7 +674,6 @@
ppc64_caches.dline_size);
printk("ppc64_caches.icache_line_size = 0x%x\n",
ppc64_caches.iline_size);
- printk("htab_address = 0x%p\n", htab_address);
printk("htab_hash_mask = 0x%lx\n", htab_hash_mask);
printk("-----------------------------------------------------\n");
diff -ruN linus-bk.new/arch/ppc64/mm/Makefile linus-bk-sfr.14.new/arch/ppc64/mm/Makefile
--- linus-bk.new/arch/ppc64/mm/Makefile 2004-09-24 15:23:06.000000000 +1000
+++ linus-bk-sfr.14.new/arch/ppc64/mm/Makefile 2005-01-18 18:28:57.000000000 +1100
@@ -8,4 +8,4 @@
slb_low.o slb.o stab.o mmap.o
obj-$(CONFIG_DISCONTIGMEM) += numa.o
obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
-obj-$(CONFIG_PPC_MULTIPLATFORM) += hash_native.o
+obj-$(CONFIG_PPC_MULTIPLATFORM) += hash_multi.o hash_native.o
diff -ruN linus-bk.new/arch/ppc64/mm/hash_multi.c linus-bk-sfr.14.new/arch/ppc64/mm/hash_multi.c
--- linus-bk.new/arch/ppc64/mm/hash_multi.c 1970-01-01 10:00:00.000000000 +1000
+++ linus-bk-sfr.14.new/arch/ppc64/mm/hash_multi.c 2005-01-18 18:27:48.000000000 +1100
@@ -0,0 +1,177 @@
+/*
+ * multiplatform hashtable management.
+ *
+ * SMP scalability work:
+ * Copyright (C) 2001 Anton Blanchard <anton at au.ibm.com>, IBM
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <linux/config.h>
+
+#include <asm/abs_addr.h>
+#include <asm/machdep.h>
+#include <asm/mmu.h>
+#include <asm/mmu_context.h>
+#include <asm/pgtable.h>
+#include <asm/cputable.h>
+#include <asm/ppcdebug.h>
+#include <asm/page.h>
+#include <asm/systemcfg.h>
+#include <asm/processor.h>
+#include <asm/lmb.h>
+#include <asm/segment.h>
+
+#ifdef DEBUG
+#define DBG(fmt...) udbg_printf(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+/*
+ * Note: pte --> Linux PTE
+ * HPTE --> PowerPC Hashed Page Table Entry
+ *
+ * Execution context:
+ * htab_initialize is called with the MMU off (of course), but
+ * the kernel has been copied down to zero so it can directly
+ * reference global data. At this point it is very difficult
+ * to print debug info.
+ *
+ */
+
+#ifdef CONFIG_U3_DART
+extern unsigned long dart_tablebase;
+#endif /* CONFIG_U3_DART */
+
+#define KB (1024)
+#define MB (1024*KB)
+
+static inline void loop_forever(void)
+{
+ volatile unsigned long x = 1;
+ for(;x;x|=1)
+ ;
+}
+
+static inline void create_pte_mapping(unsigned long start, unsigned long end,
+ unsigned long mode, int large)
+{
+ unsigned long addr;
+ unsigned int step;
+
+ if (large)
+ step = 16*MB;
+ else
+ step = 4*KB;
+
+ for (addr = start; addr < end; addr += step) {
+ unsigned long vpn, hash, hpteg;
+ unsigned long vsid = get_kernel_vsid(addr);
+ unsigned long va = (vsid << 28) | (addr & 0xfffffff);
+ int ret;
+
+ if (large)
+ vpn = va >> HPAGE_SHIFT;
+ else
+ vpn = va >> PAGE_SHIFT;
+
+ hash = hpt_hash(vpn, large);
+
+ hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP);
+
+#ifdef CONFIG_PPC_PSERIES
+ if (systemcfg->platform & PLATFORM_LPAR)
+ ret = pSeries_lpar_hpte_insert(hpteg, va,
+ virt_to_abs(addr) >> PAGE_SHIFT,
+ 0, mode, 1, large);
+ else
+#endif /* CONFIG_PPC_PSERIES */
+ ret = native_hpte_insert(hpteg, va,
+ virt_to_abs(addr) >> PAGE_SHIFT,
+ 0, mode, 1, large);
+
+ if (ret == -1) {
+ ppc64_terminate_msg(0x20, "create_pte_mapping");
+ loop_forever();
+ }
+ }
+}
+
+void __init htab_initialize(void)
+{
+ unsigned long htab_size_bytes;
+ unsigned long pteg_count;
+ unsigned long mode_rw;
+ int i, use_largepages = 0;
+
+ DBG(" -> htab_initialize()\n");
+
+ /*
+ * Calculate the required size of the htab. We want the number of
+ * PTEGs to equal one half the number of real pages.
+ */
+ htab_size_bytes = 1UL << ppc64_pft_size;
+ pteg_count = htab_size_bytes >> 7;
+
+ /* For debug, make the HTAB 1/8 as big as it normally would be. */
+ ifppcdebug(PPCDBG_HTABSIZE) {
+ pteg_count >>= 3;
+ htab_size_bytes = pteg_count << 7;
+ }
+
+ htab_hash_mask = pteg_count - 1;
+
+#ifdef CONFIG_PPC_PSERIES
+ if (!(systemcfg->platform & PLATFORM_LPAR))
+#endif
+ if (native_htab_initialize(htab_size_bytes, pteg_count))
+ loop_forever();
+
+ mode_rw = _PAGE_ACCESSED | _PAGE_COHERENT | PP_RWXX;
+
+ /* On U3 based machines, we need to reserve the DART area and
+ * _NOT_ map it to avoid cache paradoxes as it's remapped non
+ * cacheable later on
+ */
+ if (cur_cpu_spec->cpu_features & CPU_FTR_16M_PAGE)
+ use_largepages = 1;
+
+ /* create bolted the linear mapping in the hash table */
+ for (i = 0; i < lmb.memory.cnt; i++) {
+ unsigned long base, size;
+
+ base = lmb.memory.region[i].physbase + KERNELBASE;
+ size = lmb.memory.region[i].size;
+
+ DBG("creating mapping for region: %lx : %lx\n", base, size);
+
+#ifdef CONFIG_U3_DART
+ /* Do not map the DART space. Fortunately, it will be aligned
+ * in such a way that it will not cross two lmb regions and will
+ * fit within a single 16Mb page.
+ * The DART space is assumed to be a full 16Mb region even if we
+ * only use 2Mb of that space. We will use more of it later for
+ * AGP GART. We have to use a full 16Mb large page.
+ */
+ DBG("DART base: %lx\n", dart_tablebase);
+
+ if (dart_tablebase != 0 && dart_tablebase >= base
+ && dart_tablebase < (base + size)) {
+ if (base != dart_tablebase)
+ create_pte_mapping(base, dart_tablebase, mode_rw,
+ use_largepages);
+ if ((base + size) > (dart_tablebase + 16*MB))
+ create_pte_mapping(dart_tablebase + 16*MB, base + size,
+ mode_rw, use_largepages);
+ continue;
+ }
+#endif /* CONFIG_U3_DART */
+ create_pte_mapping(base, base + size, mode_rw, use_largepages);
+ }
+ DBG(" <- htab_initialize()\n");
+}
+#undef KB
+#undef MB
diff -ruN linus-bk.new/arch/ppc64/mm/hash_native.c linus-bk-sfr.14.new/arch/ppc64/mm/hash_native.c
--- linus-bk.new/arch/ppc64/mm/hash_native.c 2005-01-05 17:06:07.000000000 +1100
+++ linus-bk-sfr.14.new/arch/ppc64/mm/hash_native.c 2005-01-18 18:28:13.000000000 +1100
@@ -22,10 +22,21 @@
#include <asm/tlbflush.h>
#include <asm/tlb.h>
#include <asm/cputable.h>
+#include <asm/lmb.h>
+#include <asm/ppcdebug.h>
+
+#ifdef DEBUG
+#define DBG(fmt...) udbg_printf(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+extern unsigned long _SDR1;
#define HPTE_LOCK_BIT 3
static spinlock_t native_tlbie_lock = SPIN_LOCK_UNLOCKED;
+static HPTE *htab_address;
static inline void native_lock_hpte(HPTE *hptep)
{
@@ -410,6 +421,33 @@
}
#endif
+int native_htab_initialize(unsigned long htab_size_bytes,
+ unsigned long pteg_count)
+{
+ unsigned long table;
+
+ /* Find storage for the HPT. Must be contiguous in
+ * the absolute address space.
+ */
+ table = lmb_alloc(htab_size_bytes, htab_size_bytes);
+
+ DBG("Hash table allocated at %lx, size: %lx\n", table, htab_size_bytes);
+
+ if (!table) {
+ ppc64_terminate_msg(0x20, "hpt space");
+ return 1;
+ }
+ htab_address = abs_to_virt(table);
+
+ /* htab absolute addr + encoded htabsize */
+ _SDR1 = table + __ilog2(pteg_count) - 11;
+
+ /* Initialize the HPT with no entries */
+ memset((void *)table, 0, htab_size_bytes);
+
+ return 0;
+}
+
void hpte_init_native(void)
{
ppc_md.hpte_invalidate = native_hpte_invalidate;
diff -ruN linus-bk.new/arch/ppc64/mm/hash_utils.c linus-bk-sfr.14.new/arch/ppc64/mm/hash_utils.c
--- linus-bk.new/arch/ppc64/mm/hash_utils.c 2005-01-05 17:06:07.000000000 +1100
+++ linus-bk-sfr.14.new/arch/ppc64/mm/hash_utils.c 2005-01-06 14:37:27.000000000 +1100
@@ -17,220 +17,29 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
-
-#undef DEBUG
-
-#include <linux/config.h>
-#include <linux/spinlock.h>
-#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/bitops.h>
+#include <linux/page-flags.h>
#include <linux/sched.h>
-#include <linux/proc_fs.h>
-#include <linux/stat.h>
-#include <linux/sysctl.h>
-#include <linux/ctype.h>
-#include <linux/cache.h>
-#include <linux/init.h>
+#include <linux/cpumask.h>
+#include <linux/smp.h>
+#include <linux/compiler.h>
+#include <linux/percpu.h>
#include <linux/signal.h>
-#include <asm/ppcdebug.h>
#include <asm/processor.h>
#include <asm/pgtable.h>
#include <asm/mmu.h>
#include <asm/mmu_context.h>
#include <asm/page.h>
-#include <asm/types.h>
#include <asm/system.h>
-#include <asm/uaccess.h>
#include <asm/machdep.h>
-#include <asm/lmb.h>
-#include <asm/abs_addr.h>
#include <asm/tlbflush.h>
-#include <asm/io.h>
-#include <asm/eeh.h>
-#include <asm/tlb.h>
#include <asm/cacheflush.h>
-#include <asm/cputable.h>
-#include <asm/abs_addr.h>
-
-#ifdef DEBUG
-#define DBG(fmt...) udbg_printf(fmt)
-#else
-#define DBG(fmt...)
-#endif
-
-/*
- * Note: pte --> Linux PTE
- * HPTE --> PowerPC Hashed Page Table Entry
- *
- * Execution context:
- * htab_initialize is called with the MMU off (of course), but
- * the kernel has been copied down to zero so it can directly
- * reference global data. At this point it is very difficult
- * to print debug info.
- *
- */
-
-#ifdef CONFIG_U3_DART
-extern unsigned long dart_tablebase;
-#endif /* CONFIG_U3_DART */
+#include <asm/ptrace.h>
-HPTE *htab_address;
unsigned long htab_hash_mask;
-extern unsigned long _SDR1;
-
-#define KB (1024)
-#define MB (1024*KB)
-
-static inline void loop_forever(void)
-{
- volatile unsigned long x = 1;
- for(;x;x|=1)
- ;
-}
-
-#ifdef CONFIG_PPC_MULTIPLATFORM
-static inline void create_pte_mapping(unsigned long start, unsigned long end,
- unsigned long mode, int large)
-{
- unsigned long addr;
- unsigned int step;
-
- if (large)
- step = 16*MB;
- else
- step = 4*KB;
-
- for (addr = start; addr < end; addr += step) {
- unsigned long vpn, hash, hpteg;
- unsigned long vsid = get_kernel_vsid(addr);
- unsigned long va = (vsid << 28) | (addr & 0xfffffff);
- int ret;
-
- if (large)
- vpn = va >> HPAGE_SHIFT;
- else
- vpn = va >> PAGE_SHIFT;
-
- hash = hpt_hash(vpn, large);
-
- hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP);
-
-#ifdef CONFIG_PPC_PSERIES
- if (systemcfg->platform & PLATFORM_LPAR)
- ret = pSeries_lpar_hpte_insert(hpteg, va,
- virt_to_abs(addr) >> PAGE_SHIFT,
- 0, mode, 1, large);
- else
-#endif /* CONFIG_PPC_PSERIES */
- ret = native_hpte_insert(hpteg, va,
- virt_to_abs(addr) >> PAGE_SHIFT,
- 0, mode, 1, large);
-
- if (ret == -1) {
- ppc64_terminate_msg(0x20, "create_pte_mapping");
- loop_forever();
- }
- }
-}
-
-void __init htab_initialize(void)
-{
- unsigned long table, htab_size_bytes;
- unsigned long pteg_count;
- unsigned long mode_rw;
- int i, use_largepages = 0;
-
- DBG(" -> htab_initialize()\n");
-
- /*
- * Calculate the required size of the htab. We want the number of
- * PTEGs to equal one half the number of real pages.
- */
- htab_size_bytes = 1UL << ppc64_pft_size;
- pteg_count = htab_size_bytes >> 7;
-
- /* For debug, make the HTAB 1/8 as big as it normally would be. */
- ifppcdebug(PPCDBG_HTABSIZE) {
- pteg_count >>= 3;
- htab_size_bytes = pteg_count << 7;
- }
-
- htab_hash_mask = pteg_count - 1;
-
- if (systemcfg->platform & PLATFORM_LPAR) {
- /* Using a hypervisor which owns the htab */
- htab_address = NULL;
- _SDR1 = 0;
- } else {
- /* Find storage for the HPT. Must be contiguous in
- * the absolute address space.
- */
- table = lmb_alloc(htab_size_bytes, htab_size_bytes);
-
- DBG("Hash table allocated at %lx, size: %lx\n", table,
- htab_size_bytes);
-
- if ( !table ) {
- ppc64_terminate_msg(0x20, "hpt space");
- loop_forever();
- }
- htab_address = abs_to_virt(table);
-
- /* htab absolute addr + encoded htabsize */
- _SDR1 = table + __ilog2(pteg_count) - 11;
-
- /* Initialize the HPT with no entries */
- memset((void *)table, 0, htab_size_bytes);
- }
-
- mode_rw = _PAGE_ACCESSED | _PAGE_COHERENT | PP_RWXX;
-
- /* On U3 based machines, we need to reserve the DART area and
- * _NOT_ map it to avoid cache paradoxes as it's remapped non
- * cacheable later on
- */
- if (cur_cpu_spec->cpu_features & CPU_FTR_16M_PAGE)
- use_largepages = 1;
-
- /* create bolted the linear mapping in the hash table */
- for (i=0; i < lmb.memory.cnt; i++) {
- unsigned long base, size;
-
- base = lmb.memory.region[i].physbase + KERNELBASE;
- size = lmb.memory.region[i].size;
-
- DBG("creating mapping for region: %lx : %lx\n", base, size);
-
-#ifdef CONFIG_U3_DART
- /* Do not map the DART space. Fortunately, it will be aligned
- * in such a way that it will not cross two lmb regions and will
- * fit within a single 16Mb page.
- * The DART space is assumed to be a full 16Mb region even if we
- * only use 2Mb of that space. We will use more of it later for
- * AGP GART. We have to use a full 16Mb large page.
- */
- DBG("DART base: %lx\n", dart_tablebase);
-
- if (dart_tablebase != 0 && dart_tablebase >= base
- && dart_tablebase < (base + size)) {
- if (base != dart_tablebase)
- create_pte_mapping(base, dart_tablebase, mode_rw,
- use_largepages);
- if ((base + size) > (dart_tablebase + 16*MB))
- create_pte_mapping(dart_tablebase + 16*MB, base + size,
- mode_rw, use_largepages);
- continue;
- }
-#endif /* CONFIG_U3_DART */
- create_pte_mapping(base, base + size, mode_rw, use_largepages);
- }
- DBG(" <- htab_initialize()\n");
-}
-#undef KB
-#undef MB
-#endif /* CONFIG_PPC_MULTIPLATFORM */
-
/*
* Called by asm hashtable.S for doing lazy icache flush
*/
diff -ruN linus-bk.new/include/asm-ppc64/mmu.h linus-bk-sfr.14.new/include/asm-ppc64/mmu.h
--- linus-bk.new/include/asm-ppc64/mmu.h 2005-01-05 17:06:08.000000000 +1100
+++ linus-bk-sfr.14.new/include/asm-ppc64/mmu.h 2005-01-06 14:36:16.000000000 +1100
@@ -98,7 +98,6 @@
#define PP_RXRX 3 /* Supervisor read, User read */
-extern HPTE * htab_address;
extern unsigned long htab_hash_mask;
static inline unsigned long hpt_hash(unsigned long vpn, int large)
diff -ruN linus-bk.new/include/asm-ppc64/pgtable.h linus-bk-sfr.14.new/include/asm-ppc64/pgtable.h
--- linus-bk.new/include/asm-ppc64/pgtable.h 2005-01-02 12:05:23.000000000 +1100
+++ linus-bk-sfr.14.new/include/asm-ppc64/pgtable.h 2005-01-18 17:37:43.000000000 +1100
@@ -523,6 +523,9 @@
extern long native_hpte_insert(unsigned long hpte_group, unsigned long va,
unsigned long prpn, int secondary,
unsigned long hpteflags, int bolted, int large);
+extern int native_htab_initialize(unsigned long htab_size_bytes,
+ unsigned long pteg_count);
+
/*
* find_linux_pte returns the address of a linux pte for a given
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050119/49581523/attachment.pgp
More information about the Linuxppc64-dev
mailing list