Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/m68k Use pool(9) for struct pv_entry allocations ra...
details: https://anonhg.NetBSD.org/src/rev/dcdf17cad8f8
branches: trunk
changeset: 770690:dcdf17cad8f8
user: tsutsui <tsutsui%NetBSD.org@localhost>
date: Sat Oct 29 18:26:19 2011 +0000
description:
Use pool(9) for struct pv_entry allocations rather than
uvm_km_alloc(9)/uvm_km_free(9) and ancient homegrown pv_page_info structures.
Calling uvm_km_free(9) during pmap_remove(9) could cause rw_lock error
in uvm_unmap1() as noted in PR port-m68k/45519.
NetBSD/x68k (both real X68030 and XM6i emulator) still gets weird panic
(corrupted kernel stack pointer?) on some heavy load:
---
panic: MMU fault
Stopped in pid 363.1 (X68k) at netbsd:cpu_Debugger+0x6: unlk a6
db> tr
cpu_Debugger(4012004,8,1cbb528,2a618e0,2a5b000) + 6
db>
---
but it also occurs without this change so there might be some more bugs
in m68k pmap...
diffstat:
sys/arch/m68k/include/pmap_motorola.h | 25 +-----
sys/arch/m68k/m68k/pmap_motorola.c | 157 ++-------------------------------
2 files changed, 13 insertions(+), 169 deletions(-)
diffs (246 lines):
diff -r aacba6963d8c -r dcdf17cad8f8 sys/arch/m68k/include/pmap_motorola.h
--- a/sys/arch/m68k/include/pmap_motorola.h Sat Oct 29 17:14:12 2011 +0000
+++ b/sys/arch/m68k/include/pmap_motorola.h Sat Oct 29 18:26:19 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap_motorola.h,v 1.33 2011/06/03 17:03:52 tsutsui Exp $ */
+/* $NetBSD: pmap_motorola.h,v 1.34 2011/10/29 18:26:19 tsutsui Exp $ */
/*
* Copyright (c) 1991, 1993
@@ -191,29 +191,6 @@
struct pmap *pv_ptpmap; /* if pv_ptste, pmap for PT page */
};
-struct pv_page;
-
-struct pv_page_info {
- TAILQ_ENTRY(pv_page) pgi_list;
- struct pv_entry *pgi_freelist;
- int pgi_nfree;
-};
-
-/*
- * This is basically:
- * ((PAGE_SIZE - sizeof(struct pv_page_info)) / sizeof(struct pv_entry))
- */
-#if PAGE_SIZE == 8192
-#define NPVPPG 340
-#else
-#define NPVPPG 170
-#endif
-
-struct pv_page {
- struct pv_page_info pvp_pgi;
- struct pv_entry pvp_pv[NPVPPG];
-};
-
#define active_pmap(pm) \
((pm) == pmap_kernel() || (pm) == curproc->p_vmspace->vm_map.pmap)
#define active_user_pmap(pm) \
diff -r aacba6963d8c -r dcdf17cad8f8 sys/arch/m68k/m68k/pmap_motorola.c
--- a/sys/arch/m68k/m68k/pmap_motorola.c Sat Oct 29 17:14:12 2011 +0000
+++ b/sys/arch/m68k/m68k/pmap_motorola.c Sat Oct 29 18:26:19 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap_motorola.c,v 1.62 2011/06/12 03:35:43 rmind Exp $ */
+/* $NetBSD: pmap_motorola.c,v 1.63 2011/10/29 18:26:19 tsutsui Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -119,7 +119,7 @@
#include "opt_m68k_arch.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap_motorola.c,v 1.62 2011/06/12 03:35:43 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap_motorola.c,v 1.63 2011/10/29 18:26:19 tsutsui Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -283,9 +283,10 @@
pt_entry_t *caddr2_pte; /* PTE for CADDR2 */
struct pool pmap_pmap_pool; /* memory pool for pmap structures */
+struct pool pmap_pv_pool; /* memory pool for pv entries */
-struct pv_entry *pmap_alloc_pv(void);
-void pmap_free_pv(struct pv_entry *);
+#define pmap_alloc_pv() pool_get(&pmap_pv_pool, PR_NOWAIT)
+#define pmap_free_pv(pv) pool_put(&pmap_pv_pool, (pv))
#define PAGE_IS_MANAGED(pa) (pmap_initialized && uvm_pageismanaged(pa))
@@ -543,6 +544,12 @@
&pool_allocator_nointr, IPL_NONE);
/*
+ * Initialize the pv_entry pools.
+ */
+ pool_init(&pmap_pv_pool, sizeof(struct pv_entry), 0, 0, 0, "pvpl",
+ &pool_allocator_nointr, IPL_NONE);
+
+ /*
* Now that this is done, mark the pages shared with the
* hardware page table search as non-CCB (actually, as CI).
*
@@ -579,142 +586,6 @@
}
/*
- * pmap_alloc_pv:
- *
- * Allocate a pv_entry.
- */
-struct pv_entry *
-pmap_alloc_pv(void)
-{
- struct pv_page *pvp;
- struct pv_entry *pv;
- int i;
-
- if (pv_nfree == 0) {
- pvp = (struct pv_page *)uvm_km_alloc(kernel_map, PAGE_SIZE, 0,
- UVM_KMF_WIRED | UVM_KMF_ZERO);
- if (pvp == NULL)
- panic("pmap_alloc_pv: uvm_km_alloc() failed");
- pvp->pvp_pgi.pgi_freelist = pv = &pvp->pvp_pv[1];
- for (i = NPVPPG - 2; i; i--, pv++)
- pv->pv_next = pv + 1;
- pv->pv_next = NULL;
- pv_nfree += pvp->pvp_pgi.pgi_nfree = NPVPPG - 1;
- TAILQ_INSERT_HEAD(&pv_page_freelist, pvp, pvp_pgi.pgi_list);
- pv = &pvp->pvp_pv[0];
- } else {
- --pv_nfree;
- pvp = TAILQ_FIRST(&pv_page_freelist);
- if (--pvp->pvp_pgi.pgi_nfree == 0) {
- TAILQ_REMOVE(&pv_page_freelist, pvp, pvp_pgi.pgi_list);
- }
- pv = pvp->pvp_pgi.pgi_freelist;
-#ifdef DIAGNOSTIC
- if (pv == NULL)
- panic("pmap_alloc_pv: pgi_nfree inconsistent");
-#endif
- pvp->pvp_pgi.pgi_freelist = pv->pv_next;
- }
- return pv;
-}
-
-/*
- * pmap_free_pv:
- *
- * Free a pv_entry.
- */
-void
-pmap_free_pv(struct pv_entry *pv)
-{
- struct pv_page *pvp;
-
- pvp = (struct pv_page *)trunc_page((vaddr_t)pv);
- switch (++pvp->pvp_pgi.pgi_nfree) {
- case 1:
- TAILQ_INSERT_TAIL(&pv_page_freelist, pvp, pvp_pgi.pgi_list);
- default:
- pv->pv_next = pvp->pvp_pgi.pgi_freelist;
- pvp->pvp_pgi.pgi_freelist = pv;
- ++pv_nfree;
- break;
- case NPVPPG:
- pv_nfree -= NPVPPG - 1;
- TAILQ_REMOVE(&pv_page_freelist, pvp, pvp_pgi.pgi_list);
- uvm_km_free(kernel_map, (vaddr_t)pvp, PAGE_SIZE, UVM_KMF_WIRED);
- break;
- }
-}
-
-/*
- * pmap_collect_pv:
- *
- * Perform compaction on the PV list, called via pmap_collect().
- */
-#ifdef notyet
-void
-pmap_collect_pv(void)
-{
- struct pv_page_list pv_page_collectlist;
- struct pv_page *pvp, *npvp;
- struct pv_entry *ph, *ppv, *pv, *npv;
- struct pv_header *pvh;
- int s;
-
- TAILQ_INIT(&pv_page_collectlist);
-
- for (pvp = TAILQ_FIRST(&pv_page_freelist); pvp != NULL; pvp = npvp) {
- if (pv_nfree < NPVPPG)
- break;
- npvp = TAILQ_NEXT(&pvp->pvp_pgi, pgi_list);
- if (pvp->pvp_pgi.pgi_nfree > NPVPPG / 3) {
- TAILQ_REMOVE(&pv_page_freelist, pvp, pvp_pgi.pgi_list);
- TAILQ_INSERT_TAIL(&pv_page_collectlist, pvp,
- pvp_pgi.pgi_list);
- pv_nfree -= NPVPPG;
- pvp->pvp_pgi.pgi_nfree = -1;
- }
- }
-
- if (TAILQ_FIRST(&pv_page_collectlist) == NULL)
- return;
-
- for (pvh = &pv_table[page_cnt - 1]; pvh >= &pv_table[0]; pvh--) {
- ph = &pvh->pvh_first;
- if (ph->pv_pmap == NULL)
- continue;
- s = splvm();
- for (ppv = ph; (pv = ppv->pv_next) != NULL; ) {
- pvp = (struct pv_page *) trunc_page((vaddr_t)pv);
- if (pvp->pvp_pgi.pgi_nfree == -1) {
- pvp = TAILQ_FIRST(&pv_page_freelist);
- if (--pvp->pvp_pgi.pgi_nfree == 0) {
- TAILQ_REMOVE(&pv_page_freelist, pvp,
- pvp_pgi.pgi_list);
- }
- npv = pvp->pvp_pgi.pgi_freelist;
-#ifdef DIAGNOSTIC
- if (npv == NULL)
- panic("pmap_collect_pv: "
- "pgi_nfree inconsistent");
-#endif
- pvp->pvp_pgi.pgi_freelist = npv->pv_next;
- *npv = *pv;
- ppv->pv_next = npv;
- ppv = npv;
- } else
- ppv = pv;
- }
- splx(s);
- }
-
- for (pvp = TAILQ_FIRST(&pv_page_collectlist); pvp != NULL; pvp = npvp) {
- npvp = TAILQ_NEXT(&pvp->pvp_pgi, pgi_list);
- uvm_km_free(kernel_map, (vaddr_t)pvp, PAGE_SIZE, UVM_KMF_WIRED);
- }
-}
-#endif
-
-/*
* pmap_map:
*
* Used to map a range of physical addresses into kernel
@@ -1301,6 +1172,7 @@
panic("pmap_enter: already in pv_tab");
#endif
npv = pmap_alloc_pv();
+ KASSERT(npv != NULL);
npv->pv_va = va;
npv->pv_pmap = pmap;
npv->pv_next = pv->pv_next;
@@ -1843,11 +1715,6 @@
ptoa(VM_PHYSMEM_PTR(bank)->end));
}
splx(s);
-
-#ifdef notyet
- /* Go compact and garbage-collect the pv_table. */
- pmap_collect_pv();
-#endif
}
/*
Home |
Main Index |
Thread Index |
Old Index