Anyone VM-y enough to be up to the task: please take a look at this
current vm_contig.c code and the crash that I have.

This crash is not common -- this is the first time I've seen it --
but the problem certainly doesn't seem unique.

What seems to happen is that vm_page_sleep_if_busy() is called from
a place that expects that a page may go away, but it does not really
realize this.  If it has to sleep because the page is busy, it will
afterward happily dereference m->object which may now be NULL or belong
to something else, and unlock its mutex (which may be locked).

It seems that this is a generic problem that needs to be solved by not
dicking around with vm_object inside vm_page_sleep_if_busy(): pass it
in locked all of the time, return it unlocked all of the time if the
page queue mutex was relinquished.  Also, assumptions should be removed
from other callers of vm_page_sleep_if_busy() such that they know the
object may not exist after return, so if the page queue lock is gone
then the object is gone and it must not reference it anymore.

Essentially every bit of code that calls vm_page_sleep_if_busy() without
explicit knowledge of the backing object is in violation of this.  As
such, I think callers need to either lock the vm_object in every case
before locking the page queues, or if they hold the page queues' mutex,
do a trylock before trying to call vm_page_sleep_if_busy(), and be able
to handle both of the locks being relinquished on a return of TRUE.

Comments?

-- 
Brian Fundakowski Feldman                           \'[ FreeBSD ]''''''''''\
  <> [EMAIL PROTECTED]                               \  The Power to Serve! \
 Opinions expressed are my own.                       \,,,,,,,,,,,,,,,,,,,,,,\
Script started on Fri Jul 16 19:22:54 2004
You have mail.
bfeldman# gdb53 -k kernel.debug vmcore.15[14`53 -k kernel.debug vmcore.15

GNU gdb 5.3 (FreeBSD)
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-portbld-freebsd5.2"...set
panic: lockmgr: locking against myself
panic messages:
---
 panic: lockmgr: locking against myself
Uptime: 6h11m56s
Dumping 510 MB
 16 32 48 64 80 96 112 128 144 160 176 192 208 224 240 256 272 288 304 320 336 352 368 
384 400 416 432 448 464 480 496
---
#0  doadump () at ../../../kern/kern_shutdown.c:236
236             dumping++;
(kgdb) set pagination off
(kgdb) bt
#0  doadump () at ../../../kern/kern_shutdown.c:236
#1  0xc04fb30b in boot (howto=260) at ../../../kern/kern_shutdown.c:370
#2  0xc04fb5c3 in panic (fmt=0xc06776a0 "lockmgr: locking against myself") at 
../../../kern/kern_shutdown.c:548
#3  0xc04f11b8 in lockmgr (lkp=0xc1982e0c, flags=2, interlkp=0x1000000, td=0xc219e2c0) 
at ../../../kern/kern_lock.c:437
#4  0xc05ffdd0 in _vm_map_lock_read (map=0x0, file=0xc068c92e "../../../vm/vm_map.c", 
line=2935) at machine/pcpu.h:156
#5  0xc0602e10 in vm_map_lookup (var_map=0xde778b24, vaddr=0, fault_typea=1 '\001', 
out_entry=0xde778b28, object=0x0, pindex=0x0, out_prot=0x0, wired=0xde778b00) at 
../../../vm/vm_map.c:2935
#6  0xc05fbed9 in vm_fault (map=0xc1982dd0, vaddr=0, fault_type=1 '\001', 
fault_flags=0) at ../../../vm/vm_fault.c:232
#7  0xc063c49b in trap_pfault (frame=0xde778bec, usermode=0, eva=0) at 
../../../i386/i386/trap.c:710
#8  0xc063c1b1 in trap (frame={tf_fs = -1038548968, tf_es = 16, tf_ds = -562626544, 
tf_edi = -1066871035, tf_esi = 431, tf_ebp = -562590664, tf_isp = -562590696, tf_ebx = 
0, tf_edx = -1038490944, tf_ecx = 2, tf_eax = -1038490944, tf_trapno = 12, tf_err = 0, 
tf_eip = -1068550176, tf_cs = 8, tf_eflags = 78470, tf_esp = -1048169872, tf_ss = 1}) 
at ../../../i386/i386/trap.c:420
#9  0xc04f37e0 in _mtx_lock_flags (m=0x0, opts=0, file=0xc068d705 
"../../../vm/vm_page.c", line=431) at ../../../kern/kern_mutex.c:246
#10 0xc0607638 in vm_page_sleep_if_busy (m=0xc1863270, also_m_busy=1, msg=0xc068d4a6 
"madvpo") at ../../../vm/vm_page.c:431
#11 0xc0605ceb in vm_object_madvise (object=0xc22097bc, pindex=6116, count=0, 
advise=5) at ../../../vm/vm_object.c:1130
#12 0xc060118d in vm_map_madvise (map=0xc1982dd0, start=169009152, end=172679168, 
behav=5) at ../../../vm/vm_map.c:1546
#13 0xc0603c5a in madvise (td=0xc1982dd0, uap=0x0) at ../../../vm/vm_mmap.c:676
#14 0xc063ca6b in syscall (frame={tf_fs = 47, tf_es = 22151215, tf_ds = -1078001617, 
tf_edi = 3670016, tf_esi = 896, tf_ebp = -1077942168, tf_isp = -562590348, tf_ebx = 
674006828, tf_edx = 811073536, tf_ecx = 7993, tf_eax = 75, tf_trapno = 12, tf_err = 2, 
tf_eip = 673541319, tf_cs = 31, tf_eflags = 12946, tf_esp = -1077942212, tf_ss = 47}) 
at ../../../i386/i386/trap.c:1004
(kgdb) p/x allproc.lh_first->p_threads->tqh_first->td_pcb->pcb_ebp
$1 = 0xdf6e8904
(kgdb) frame 0xdf6e8904
#0  0x00000000 in ?? ()
(kgdb) down
Bottom (i.e., innermost) frame selected; you cannot go down.
(kgdb) up
#1  0xc06e72cc in sysctl__kern_shutdown_children ()
(kgdb) 
#2  0xc050157e in mi_switch (flags=0) at ../../../kern/kern_synch.c:352
352             sched_switch(td);
(kgdb) 
#3  0xc0515992 in sleepq_switch (wchan=0x0) at ../../../kern/subr_sleepqueue.c:374
374             mi_switch(SW_VOL);
(kgdb) 
#4  0xc0515b43 in sleepq_wait (wchan=0xcbe2d488) at ../../../kern/subr_sleepqueue.c:478
478             sleepq_switch(wchan);
(kgdb) 
#5  0xc050125a in msleep (ident=0xcbe2d488, mtx=0xc070f980, priority=68, 
wmesg=0xc068c150 "swwrt", timo=0) at ../../../kern/kern_synch.c:243
243                     sleepq_wait(ident);
(kgdb) 
#6  0xc053c587 in bwait (bp=0xcbe2d488, pri=68 'D', wchan=0xc068c150 "swwrt") at 
../../../kern/vfs_bio.c:3766
3766                    msleep(bp, &bdonelock, pri, wchan, 0);
(kgdb) 
#7  0xc05fa3c2 in swap_pager_putpages (object=0xc22097bc, m=0xdf6e8a6c, count=1, 
sync=1, rtvals=0xdf6e8a20) at ../../../vm/swap_pager.c:1372
1372                    bwait(bp, PVM, "swwrt");
(kgdb) 
#8  0xc060a6f2 in vm_pageout_flush (mc=0xdf6e8a6c, count=1, flags=1) at 
../../../vm/vm_pager.h:139
139             (*pagertab[object->type]->pgo_putpages)
(kgdb) 
#9  0xc0609332 in vm_contig_launder_page (m=0xc18636f0) at ../../../vm/vm_contig.c:121
warning: Source file is more recent than executable.

121                             vm_pageout_flush(&m_tmp, 1, VM_PAGER_PUT_SYNC);
(kgdb) 
#10 0xc0609c6e in vm_page_alloc_contig (npages=44, low=0, high=4294967295, 
alignment=4, boundary=0) at ../../../vm/vm_contig.c:447
447                                             if (vm_contig_launder_page(m) != 0)
(kgdb) 
#11 0xc0609f6d in contigmalloc (size=180224, type=0xc06bbc80, flags=258, low=0, 
high=4294967295, alignment=4, boundary=0) at ../../../vm/vm_contig.c:546
546                     pages = vm_page_alloc_contig(npgs, low, high,
(kgdb) 
#12 0xc062d137 in bus_dmamem_alloc (dmat=0xc1cffc00, vaddr=0xc1d17554, flags=0, 
mapp=0x0) at ../../../i386/i386/busdma_machdep.c:430
430                     *vaddr = contigmalloc(dmat->maxsize, M_DEVBUF, mflags,
(kgdb) 
#13 0xc2251898 in ?? ()
(kgdb) 
#14 0xc2251634 in ?? ()
(kgdb) 
#15 0xc050d46c in device_attach (dev=0xc1d17550) at device_if.h:39
39              KOBJOPLOOKUP(((kobj_t)dev)->ops,device_attach);
(kgdb) 
#16 0xc050d40c in device_probe_and_attach (dev=0xc1bd8400) at 
../../../kern/subr_bus.c:1684
1684            error = device_attach(dev);
(kgdb) 
#17 0xc0464785 in cardbus_driver_added (cbdev=0xc1a49e00, driver=0xc226a3e8) at 
../../../dev/cardbus/cardbus.c:278
278                     if (device_probe_and_attach(dev) != 0)
(kgdb) 
#18 0xc050c403 in devclass_add_driver (dc=0xc19709c0, driver=0xc226a3e8) at bus_if.h:71
71              ((bus_driver_added_t *) _m)(_dev, _driver);
(kgdb) 
#19 0xc050ec92 in driver_module_handler (mod=0xc1cbc640, what=-1037655064, 
arg=0xc226a45c) at ../../../kern/subr_bus.c:2545
2545                    error = devclass_add_driver(bus_devclass, driver);
(kgdb) 
#20 0xc04f312e in module_register_init (arg=0xc226a470) at 
../../../kern/kern_module.c:108
108             error = MOD_EVENT(mod, MOD_LOAD);
(kgdb) 
#21 0xc04ee5e1 in linker_file_sysinit (lf=0xc1c8fe00) at 
../../../kern/kern_linker.c:193
193                     (*((*sipp)->func)) ((*sipp)->udata);
(kgdb) 
#22 0xc04ee895 in linker_load_file (filename=0xc1d30180 
"/home/green/prism54-driver/pff/if_pff.ko", result=0xdf6e8cb0) at 
../../../kern/kern_linker.c:358
358                             linker_file_sysinit(lf);
(kgdb) 
#23 0xc04f08e7 in linker_load_module (kldname=0xc1d30180 
"/home/green/prism54-driver/pff/if_pff.ko", modname=0x0, parent=0x0, verinfo=0x0, 
lfpp=0xdf6e8cdc) at ../../../kern/kern_linker.c:1673
1673                    error = linker_load_file(pathname, &lfdep);
(kgdb) 
#24 0xc04ef297 in kldload (td=0xc1cb59a0, uap=0x0) at ../../../kern/kern_linker.c:776
776             error = linker_load_module(kldname, modname, NULL, NULL, &lf);
(kgdb) 
#25 0xc063ca6b in syscall (frame={tf_fs = 47, tf_es = 47, tf_ds = 47, tf_edi = 1, 
tf_esi = -1077942056, tf_ebp = -1077942136, tf_isp = -546402956, tf_ebx = 0, tf_edx = 
-1, tf_ecx = -1077941787, tf_eax = 304, tf_trapno = 12, tf_err = 2, tf_eip = 
671870951, tf_cs = 31, tf_eflags = 658, tf_esp = -1077942180, tf_ss = 47}) at 
../../../i386/i386/trap.c:1004
1004                    error = (*callp->sy_call)(td, args);
(kgdb) 
Initial frame selected; you cannot go up.
(kgdb) 
Initial frame selected; you cannot go up.
(kgdb) 
Initial frame selected; you cannot go up.
(kgdb) 
Initial frame selected; you cannot go up.
(kgdb) bfeldman# ^Dexit

Script done on Fri Jul 16 19:23:44 2004
_______________________________________________
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to