panic in destroy_devl: null si_devsw

Andriy Gapon avg at icyb.net.ua
Sat Jan 24 07:22:35 PST 2009


System: FreeBSD 7.1-PRERELEASE amd64 somewhere from the beginning of
Decemeber

I am not sure how I managed to get to this panic - I believe my code is
correct - but I got a panic in destroy_devl on NULL si_devsw.

Backtrace:
--- trap 0xc, rip = 0xffffffff80271c3f, rsp = 0xffffffffdb3e8510, rbp =
0xffffffffdb3e8550 ---
destroy_devl() at 0xffffffff80271c3f = destroy_devl+0x316
destroy_dev() at 0xffffffff80271e2c = destroy_dev+0x19
heci_deallocate_resources() at 0xffffffffdb63e0e6 =
heci_deallocate_resources+0x20
heci_detach() at 0xffffffffdb63e183 = heci_detach+0x11
heci_pci_attach() at 0xffffffffdb63f921 = heci_pci_attach+0x123
device_attach() at 0xffffffff802caa21 = device_attach+0x327
device_probe_and_attach() at 0xffffffff802cb8ef =
device_probe_and_attach+0xe2
pci_driver_added() at 0xffffffff80212e82 = pci_driver_added+0xf9
devclass_add_driver() at 0xffffffff802c98fa = devclass_add_driver+0xd7
driver_module_handler() at 0xffffffff802ca641 = driver_module_handler+0x74
module_register_init() at 0xffffffff8029901d = module_register_init+0xf7
linker_load_module() at 0xffffffff80292582 = linker_load_module+0xa01
kern_kldload() at 0xffffffff80292aa2 = kern_kldload+0xd4
kldload() at 0xffffffff80292b66 = kldload+0x61
syscall() at 0xffffffff8043d58d = syscall+0x347
Xfast_syscall() at 0xffffffff80423a5b = Xfast_syscall+0xab
--- syscall (304, FreeBSD ELF64, kldload), rip = 0x80067ff3c, rsp =
0x7fffffffe5b8, rbp = 0 ---

Debug:
(kgdb) fr 7
#7  0xffffffff80271c3f in destroy_devl (dev=0xffffff0075d45800) at
/usr/src/sys/kern/kern_conf.c:906
906                     if (LIST_EMPTY(&csw->d_devs)) {
(kgdb) list
901             if (!(dev->si_flags & SI_ALIAS)) {
902                     /* Remove from cdevsw list */
903                     LIST_REMOVE(dev, si_list);
904
905                     /* If cdevsw has no more struct cdev *'s, clean
it */
906                     if (LIST_EMPTY(&csw->d_devs)) {
907                             fini_cdevsw(csw);
908                             wakeup(&csw->d_devs);
909                     }
910             }
(kgdb) p csw
$1 = (struct cdevsw *) 0x0

Perhaps I screwed up something myself, but here is a question - why do
we have a check for NULL csw here:
 873         csw = dev->si_devsw;
 874         dev->si_devsw = NULL;   /* already NULL for SI_ALIAS */
 875         while (csw != NULL && csw->d_purge != NULL &&
dev->si_threadcount) {

and don't have any check where the panic occurred?

About the code that called destroy_dev(): it created cdev probably too
early, failed to allocate some system resource, so it went to destroy
the newly created cdev. Non-null cdevsw was definitely provided to make_dev.

-- 
Andriy Gapon


More information about the freebsd-stable mailing list