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