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