NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

port-m68k/45519: rw_lock error panic in m68k pmap



>Number:         45519
>Category:       port-m68k
>Synopsis:       rw_lock error panic in m68k pmap
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    port-m68k-maintainer
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Oct 24 15:05:00 +0000 2011
>Originator:     Izumi Tsutsui
>Release:        NetBSD 5.99.56
>Organization:
>Environment:
System: NetBSD 5.99.56 on XM6i (X68030 emulator)
Architecture: m68k
Machine: x68k
>Description:
I got the following panic during running Xserver:
(typed from captured screen by hand)
---
[out of screen]
lock error
Stopped in pid 318.1 (ruby18) at        netbsd:cpu_Debugger+0x6:        unlk    
a
6
db> tr
cpu_Debugger(25b084,2b1d0c4,179e20,24c6a8,2b4069c) + 6
vpanic(2354a9,2b406a8,2b406a8,2b406b4,174e8c) + 1ba
panic(2354a9,2bad0c4,25b090,25b080,2b406cc) + 12
lockdebug_abort(25b084,24c6a8,227a6b,226c09) + 70
rw_abort(25b084,227a6b,226c09) + 1e
rw_enter(25b084,1,2b40758,0,719100) + 18e
vm_map_lock(25b080,25b080,2b40758,2,2800000) + 28
uvm_unmap1(25b080,29af000,29b0000,2800000) + 26
uvm_km_free(25b080,29af000,1000,1) + 70
pmap_free_pv(29af9c0) + ac
pmap_remove_mapping(2574b8,1c91000,ffc07244,1) +380
pmap_remove(2574b8,1c91000,1c92000,2116c78,25b080) + f8
uvm_unmap_remove(25b080,1c91000,1c92000,2b408a4,2b40898,0,25b080,25b080,2b40898,2)
 + 1e8
uvm_unmap1(25b080,1c91000,1c92000,0,2b40938) + 3e
lwp_ctl_exit(0,4,84,40b4b10,ffe8149a) + 46
exit1(2b1d0c0,84,e,ffe8100c,2b6089c) + a8
sigexit(2b1d0c0,4) +1d2
sendsig_siginfo(2b40f18,2b1d254) + 13e
sendsig(2b40f18,2b1d254) + 74
kpsendsig(2b1d0c0,2b40f18,2b1d254,1ca6fb4,80) + bc
trapsignal(2b1d0c0,2b40f18) + c2
trap(2b40f60,8,4010111,ffe8149a) + 97a
faltstksdj() + 4
db>
---

In this trace, uvm_map1() calls m68k pmap_remove(),
but it calls uvm_map1() via uvm_km_free() in pmap_free_pv()
(which frees a page for struct pv_entry), so that lock panic
is caused by the design of m68k pmap pv_entry allocation.

>How-To-Repeat:
Run heavy applications (like ruby) on Hibler's hp300 derived pmap m68k ports?

>Fix:
Probably it would be better to simply use pool(9) for pv_entry like mips,
instead of uvm_km_alloc() and homegrown pv_page_info structure:

Index: arch/m68k/include/pmap_motorola.h
===================================================================
RCS file: /cvsroot/src/sys/arch/m68k/include/pmap_motorola.h,v
retrieving revision 1.33
diff -u -p -r1.33 pmap_motorola.h
--- arch/m68k/include/pmap_motorola.h   3 Jun 2011 17:03:52 -0000       1.33
+++ arch/m68k/include/pmap_motorola.h   24 Oct 2011 13:36:57 -0000
@@ -191,6 +191,7 @@ struct pv_entry {
        struct pmap     *pv_ptpmap;     /* if pv_ptste, pmap for PT page */
 };
 
+#if 0
 struct pv_page;
 
 struct pv_page_info {
@@ -213,6 +214,7 @@ struct pv_page {
        struct pv_page_info pvp_pgi;
        struct pv_entry pvp_pv[NPVPPG];
 };
+#endif
 
 #define        active_pmap(pm) \
        ((pm) == pmap_kernel() || (pm) == curproc->p_vmspace->vm_map.pmap)
Index: arch/m68k/m68k/pmap_motorola.c
===================================================================
RCS file: /cvsroot/src/sys/arch/m68k/m68k/pmap_motorola.c,v
retrieving revision 1.62
diff -u -p -r1.62 pmap_motorola.c
--- arch/m68k/m68k/pmap_motorola.c      12 Jun 2011 03:35:43 -0000      1.62
+++ arch/m68k/m68k/pmap_motorola.c      24 Oct 2011 13:36:58 -0000
@@ -283,9 +283,17 @@ pt_entry_t *caddr1_pte;    /* PTE for CADDR
 pt_entry_t     *caddr2_pte;    /* PTE for CADDR2 */
 
 struct pool    pmap_pmap_pool; /* memory pool for pmap structures */
+#if 1
+struct pool    pmap_pv_pool;   /* memory pool for pv entries */
+#endif
 
+#if 0
 struct pv_entry *pmap_alloc_pv(void);
 void   pmap_free_pv(struct pv_entry *);
+#else
+#define pmap_alloc_pv()                pool_get(&pmap_pv_pool, PR_NOWAIT)
+#define pmap_free_pv(pv)       pool_put(&pmap_pv_pool, (pv))
+#endif
 
 #define        PAGE_IS_MANAGED(pa)     (pmap_initialized && 
uvm_pageismanaged(pa))
 
@@ -542,6 +550,14 @@ pmap_init(void)
        pool_init(&pmap_pmap_pool, sizeof(struct pmap), 0, 0, 0, "pmappl",
            &pool_allocator_nointr, IPL_NONE);
 
+#if 1
+       /*
+        * Initialize the pv_entry pools.
+        */
+       pool_init(&pmap_pv_pool, sizeof(struct pv_entry), 0, 0, 0, "pvpl",
+           &pool_allocator_nointr, IPL_NONE);
+#endif
+
        /*
         * Now that this is done, mark the pages shared with the
         * hardware page table search as non-CCB (actually, as CI).
@@ -578,6 +594,7 @@ pmap_init(void)
        pmap_initialized = true;
 }
 
+#if 0
 /*
  * pmap_alloc_pv:
  *
@@ -713,6 +730,7 @@ pmap_collect_pv(void)
        }
 }
 #endif
+#endif
 
 /*
  * pmap_map:
@@ -1301,6 +1319,9 @@ pmap_enter(pmap_t pmap, vaddr_t va, padd
                                        panic("pmap_enter: already in pv_tab");
 #endif
                        npv = pmap_alloc_pv();
+#if 1
+                       KASSERT(npv != NULL);
+#endif
                        npv->pv_va = va;
                        npv->pv_pmap = pmap;
                        npv->pv_next = pv->pv_next;
@@ -1844,10 +1865,12 @@ pmap_collect(void)
        }
        splx(s);
 
+#if 0
 #ifdef notyet
        /* Go compact and garbage-collect the pv_table. */
        pmap_collect_pv();
 #endif
+#endif
 }
 
 /*

---
Izumi Tsutsui



Home | Main Index | Thread Index | Old Index