panic after kldunload - stale device descriptions

From: Frank Behrens <frank_at_pinky.sax.de>
Date: Tue, 23 Aug 2005 19:43:44 +0200
I'm writing a device driver and got a panic during my tests. OK, this 
was not the 1st one ;-) , but I believe this one shows a problem in 
the base system. I use FreeBSD 6.0-BETA3-200508221325 #4: Tue Aug 23 
17:40:22 CEST 2005 i386

I loaded my driver (kldload) and the device was probed and found in 
ISA_PNP_PROBE. Then the driver was unloaded (kldunload) and I tried 
to read the current device configuration. This gave me a

Fatal trap 12: page fault while in kernel mode
cpuid = 1; apic id = 01
fault virtual address   = 0xc2bbbe01
fault code              = supervisor read, page not present
instruction pointer     = 0x20:0xc057aa28
stack pointer           = 0x28:0xecf21a00
frame pointer           = 0x28:0xecf21a0c
code segment            = base 0x0, limit 0xfffff, type 0x1b
                        = DPL 0, pres 1, def32 1, gran 1
processor eflags        = interrupt enabled, resume, IOPL = 0
current process         = 1001 (devinfo)
trap number             = 12
panic: page fault
cpuid = 1

#6  0xc06ac24a in calltrap () at /usr/src/sys/i386/i386/exception.s:139
#7  0xc0840008 in EcWaitEvent (sc=0x20, Event=0x1) at /usr/src/sys/modules/acpi/acpi/../../../dev/acpica/acpi_ec.c:879
#8  0xc051d38e in sysctl_devices (oidp=0xc071fd80, arg1=0xc23a3400, arg2=0x2, req=0xecf21bf0)
    at /usr/src/sys/kern/subr_bus.c:3963
#9  0xc050babf in sysctl_root (oidp=0x0, arg1=0xecf21c6c, arg2=0x2, req=0xecf21bf0)
    at /usr/src/sys/kern/kern_sysctl.c:1248
#10 0xc050be40 in userland_sysctl (td=0x0, name=0xecf21c60, namelen=0x5, old=0xbfbfeb20, oldlenp=0xbfbfe970,
    inkernel=0x0, new=0x0, newlen=0x0, retval=0xecf21c5c, flags=0x0) at /usr/src/sys/kern/kern_sysctl.c:1347
#11 0xc050bfaf in __sysctl (td=0x0, uap=0xecf21d04) at /usr/src/sys/kern/kern_sysctl.c:1282

(kgdb) frame 8
#8  0xc051d38e in sysctl_devices (oidp=0xc071fd80, arg1=0xc23a3400, arg2=0x2, req=0xecf21bf0)
    at /usr/src/sys/kern/subr_bus.c:3963
3963                    strlcpy(udev.dv_desc, dev->desc, sizeof(udev.dv_desc));
(kgdb) p dev
$1 = (struct device *) 0xc23a3400
(kgdb) p *dev
$2 = {
  ops = 0xc22be800,
  link = {
    tqe_next = 0xc23a3800,
    tqe_prev = 0xc238ce84
  },
  devlink = {
    tqe_next = 0xc23a3800,
    tqe_prev = 0xc238ce8c
  },
  parent = 0xc238bd80,
  children = {
    tqh_first = 0x0,
    tqh_last = 0xc23a3418
  },
  driver = 0x0,
  devclass = 0xc28fee00,
  unit = 0x0,
  nameunit = 0xc281b3b0 "eib0",
  desc = 0xc2bbbe01 <Address 0xc2bbbe01 out of bounds>,
  busy = 0x0,
  state = DS_NOTPRESENT,
  devflags = 0x40,
  flags = 0x65,
  order = 0x32,
  pad = 0x0,
  ivars = 0xc23965c0,
  softc = 0xc25b0c00,
  sysctl_ctx = {
    tqh_first = 0xc25bc010,
    tqh_last = 0xc281b2a4
  },
  sysctl_tree = 0x0
}

So it seems the device description points to a nonexisting page.

My explanation:
ISA_PNP_PROBE can call "acpi_isa_pnp_probe" and "isa_pnp_probe". Both 
compare device ids with values defined in driver and set on success 
the device description with "device_set_desc". There is now a 
reference in the device to a string in the loaded driver module. When 
I unload the driver we know what happens.

IMHO the probe functions should use "device_set_desc_copy" to be able 
to unload driver modules. When I see the big number of 
"device_set_desc" in the source tree I get the feeling, that a lot of 
drivers will lead to a panic if used as loadable module and then 
unloaded.

I will discuss this shortly on the mailing list. If I get no answer 
or no objections I will create a PR, but I'm not sure if the majority 
of drivers should be changed, too.

Regards,
   Frank
-- 
Frank Behrens, Osterwieck, Germany
PGP-key 0x5B7C47ED on public servers available.
Received on Tue Aug 23 2005 - 15:43:48 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:38:42 UTC