arm pmap locking

Ian Lepore freebsd at damnhippie.dyndns.org
Sun Sep 23 19:35:43 UTC 2012


On Sun, 2012-09-23 at 12:10 -0500, Alan Cox wrote:
> On 09/23/2012 09:30, Ian Lepore wrote:
> > On Sat, 2012-09-22 at 19:55 -0500, Alan Cox wrote:
> >> On 09/22/2012 15:45, Ian Lepore wrote:
> >>> Yep.  Looks like the first one (reversed) is very very early in the
> >>> init.  After this one, there were no other LORs during the boot until
> >>> the one that you said is fixed now in -current.
> >>>
> >>> lock order reversal:
> >>>    1st 0xc055bd08 4096 (UMA zone) @ /usr/src/sys/vm/uma_core.c:2011
> >>>    2nd 0xc043c198 pmap (pmap) @ /usr/src/sys/arm/arm/pmap.c:3734
> >> Ah.  Notice that this is an "UMA zone" lock, but nonetheless a different
> >> zone and lock from before, i.e., "4096" versus "PV ENTRY".  By default,
> >> witness treats all uma zone locks as having the same lock ordering.
> >> This helps to keep the distinct lock types that witness must deal with
> >> and consequently its run-time overhead down.  However, sometimes uma
> >> zone locks on zones that are used within the VM system need to be
> >> handled specially.  There is an argument to uma_zcreate() for doing
> >> this: UMA_ZONE_MTXCLASS
> >>
> >> Try this now.  Remove whatever change that you made to witness and apply
> >> a change like this:
> >>
> >> Index: arm/arm/pmap.c
> >> ===================================================================
> >> --- arm/arm/pmap.c      (revision 240803)
> >> +++ arm/arm/pmap.c      (working copy)
> >> @@ -1821,7 +1821,7 @@ pmap_init(void)
> >>            * Initialize the PV entry allocator.
> >>            */
> >>           pvzone = uma_zcreate("PV ENTRY", sizeof (struct pv_entry),
> >> NULL, NULL,
> >> -           NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_VM | UMA_ZONE_NOFREE);
> >> +           NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_MTXCLASS | UMA_ZONE_VM);
> >>           TUNABLE_INT_FETCH("vm.pmap.shpgperproc",&shpgperproc);
> >>           pv_entry_max = shpgperproc * maxproc + cnt.v_page_count;
> >>           uma_zone_set_obj(pvzone,&pvzone_obj, pv_entry_max);
> >>
> >> I've also removed UMA_ZONE_NOFREE from the arguments because it's
> >> redundant.  uma_zone_set_obj() itself sets that flag.
> >>
> >> Alan
> >>
> > Did that, now the original LOR that happens at start_init() time
> > involves pmap and the malloc 4096 uma zone rather than the PV ENTRY
> > zone.  Putting back in the preset order, it looks like a malloc() in
> > mtx_pool_create() is now the first call with the wrong order, the bottom
> > of the call stack looks like this:
> >
> > malloc() at malloc+0x10
> > scp=0xc00afe98 rlv=0xc00b28c8 (mtx_pool_create+0x54)
> >          rsp=0xc04ddeb4 rfp=0xc04dded0
> >          r10=0x204fe888 r9=0x00000019
> >          r8=0x20479a10 r7=0x00000000 r6=0xc0254a10 r5=0x00000080
> >          r4=0xc0276a40
> > mtx_pool_create() at mtx_pool_create+0x10
> > scp=0xc00b2884 rlv=0xc00b290c (mtx_pool_setup_dynamic+0x1c)
> >          rsp=0xc04dded4 rfp=0xc04ddee0
> >          r7=0x20000124 r6=0x00000004
> >          r5=0x20000130 r4=0xc0276a40
> > mtx_pool_setup_dynamic() at mtx_pool_setup_dynamic+0x10
> > scp=0xc00b2900 rlv=0xc0082654 (mi_startup+0xf8)
> >          rsp=0xc04ddee4 rfp=0xc04ddef4
> > mi_startup() at mi_startup+0x10
> > scp=0xc008256c rlv=0xc00001cc (virt_done+0x18)
> >          rsp=0xc04ddef8 rfp=0x00000000
> >          r4=0x2000020c
> >
> > If you need complete backtraces or other details let me know.
> >
> 
> Thanks.  I'd like to see the stack trace without any preset lock order.
> 
> Unless I explicitly say otherwise, assume that I want UMA_ZONE_MTXCLASS 
> specified to the pvzone creation.
> 
> In general, uma zone locks should come before the pmap lock in the 
> expected lock order.  However, any of the zones used by the pmap are 
> likely to be exceptions to this rule.  After you added UMA_ZONE_MTXCLASS 
> to the PV zone, I was expecting the next reported LOR to be on the l2 
> zone or l2table zone.  Does that make sense?
> 
> Alan
> 

Without presetting the order...

warning: no time-of-day clock registered, system time will not be set
accurately
lock order reversal:
 1st 0xc0a8a0b0 pmap (pmap) @ /usr/src/sys/arm/arm/pmap.c:971
 2nd 0xc055b388 128 Bucket (UMA zone) @ /usr/src/sys/vm/uma_core.c:2485
KDB: stack backtrace:
db_trace_thread() at db_trace_thread+0x10
scp=0xc0215d7c rlv=0xc0215f80 (db_trace_self+0x1c)
        rsp=0xc2e9d90c rfp=0xc2e9d918
        r10=0x00000000 r9=0xc0a4c4b8
        r8=0xc040aec4 r7=0xffffffff r6=0xc0a4c6c0 r5=0xc023a21c
        r4=0xc2e9d924
db_trace_self() at db_trace_self+0x10
scp=0xc0215f74 rlv=0xc001ee0c (db_trace_self_wrapper+0x30)
        rsp=0xc2e9d91c rfp=0xc2e9da38
db_trace_self_wrapper() at db_trace_self_wrapper+0x10
scp=0xc001edec rlv=0xc00ef4f8 (kdb_backtrace+0x3c)
        rsp=0xc2e9da3c rfp=0xc2e9da4c
        r4=0xc02dbf44
kdb_backtrace() at kdb_backtrace+0x10
scp=0xc00ef4cc rlv=0xc0102c48 (_witness_debugger+0x2c)
        rsp=0xc2e9da50 rfp=0xc2e9da64
        r4=0x00000001
_witness_debugger() at _witness_debugger+0x10
scp=0xc0102c2c rlv=0xc0103468 (witness_checkorder+0x7e8)
        rsp=0xc2e9da68 rfp=0xc2e9dab4
        r5=0x00000000 r4=0xc055b388
witness_checkorder() at witness_checkorder+0x10
scp=0xc0102c90 rlv=0xc00b37fc (_mtx_lock_flags+0xa4)
        rsp=0xc2e9dab8 rfp=0xc2e9dadc
        r10=0x00000000 r9=0xc043c5ac
        r8=0x00000000 r7=0x000009b5 r6=0xc026e6b4 r5=0x00000000
        r4=0xc055b388
_mtx_lock_flags() at _mtx_lock_flags+0x10
scp=0xc00b3768 rlv=0xc01f2e20 (zone_alloc_item+0x34)
        rsp=0xc2e9dae0 rfp=0xc2e9db08
        r8=0xc026e6b4 r7=0x00000201
        r6=0x00000000 r5=0xc055a3c0 r4=0x00000201
zone_alloc_item() at zone_alloc_item+0x10
scp=0xc01f2dfc rlv=0xc01f46a4 (bucket_alloc+0x3c)
        rsp=0xc2e9db0c rfp=0xc2e9db20
        r10=0x00000000 r8=0xc055a6e0
        r7=0xc055a740 r6=0x00000000 r5=0xc02cd428 r4=0x00000201
bucket_alloc() at bucket_alloc+0x10
scp=0xc01f4678 rlv=0xc01f4f8c (uma_zalloc_arg+0x450)
        rsp=0xc2e9db24 rfp=0xc2e9db60
        r5=0x00000201 r4=0xc026e6b4
uma_zalloc_arg() at uma_zalloc_arg+0x10
scp=0xc01f4b4c rlv=0xc021b4d0 (pmap_get_pv_entry+0x40)
        rsp=0xc2e9db64 rfp=0xc2e9db70
        r10=0x00000000 r9=0xc043c5ac
        r8=0x2078e55e r7=0xc0a8a0b0 r6=0xc0272f84 r5=0xc05370b8
        r4=0x00000000
pmap_get_pv_entry() at pmap_get_pv_entry+0x10
scp=0xc021b4a0 rlv=0xc02201a0 (pmap_enter_locked+0xcfc)
        rsp=0xc2e9db74 rfp=0xc2e9dbf0
pmap_enter_locked() at pmap_enter_locked+0x10
scp=0xc021f4b4 rlv=0xc0220704 (pmap_enter+0x74)
        rsp=0xc2e9dbf4 rfp=0xc2e9dc20
        r10=0x00000007 r9=0xc2e9dde4
        r8=0xc056dea0 r7=0xbffff000 r6=0xc043a07c r5=0xc0a8a0b0
        r4=0xc0272f84
pmap_enter() at pmap_enter+0x10
scp=0xc02206a0 rlv=0xc01f80e0 (vm_fault+0x1688)
        rsp=0xc2e9dc24 rfp=0xc2e9dd3c
        r10=0x00000002 r8=0xbffff000
        r7=0xc0a88000 r6=0x00000000 r5=0xc0273420 r4=0xc056dea0
vm_fault() at vm_fault+0x10
scp=0xc01f6a68 rlv=0xc0224078 (data_abort_handler+0x360)
        rsp=0xc2e9dd40 rfp=0xc2e9dde0
        r10=0x00000002 r9=0xc2e9dde4
        r8=0xbffff000 r7=0xc0a88000 r6=0x00000000 r5=0xc0273420
        r4=0xc0a86088
data_abort_handler() at data_abort_handler+0x10
scp=0xc0223d28 rlv=0xc0217784 (exception_exit)
        rsp=0xc2e9dde4 rfp=0xc2e9de84
        r10=0xc02b7d0a r9=0xc0a86000
        r8=0xc2e9deac r7=0xc02b7d0a r6=0xc02b7d00 r5=0xffff1004
        r4=0xffffffff
start_init() at start_init+0x10
scp=0xc0082244 rlv=0xc009c460 (fork_exit+0x84)
        rsp=0xc2e9de88 rfp=0xc2e9dea8
        r10=0x00000000 r9=0x00000000
        r8=0xc2e9deac r7=0x00000000 r6=0xc0082234 r5=0xc0a86000
        r4=0xc0a88000
fork_exit() at fork_exit+0x10
scp=0xc009c3ec rlv=0xc022354c (fork_trampoline+0x14)
        rsp=0xc2e9deac rfp=0x00000000
        r8=0x00000000 r7=0x6c6c6568
        r6=0x735f6365 r5=0x00000000 r4=0xc0082234

-- Ian




More information about the freebsd-arm mailing list