namei (via firmware_get(9)) from taskq in 7.x
Andrew Gallatin
gallatin at cs.duke.edu
Thu Oct 15 21:16:30 UTC 2009
Hi,
I'm trying to re-initialize a NIC which uses firmware(9)
after a hardware fault. As part of the process, I need
to re-load the firmware using firmware_get(). If the
firmware kld is not resident, then the machine will panic
like this:
Fatal trap 12: page fault while in kernel mode
cpuid = 0; apic id = 00
fault virtual address = 0x20
fault code = supervisor read data, page not present
instruction pointer = 0x8:0xffffffff805b05d4
stack pointer = 0x10:0xffffff8000080460
frame pointer = 0x10:0xffffff8000080510
code segment = base 0x0, limit 0xfffff, type 0x1b
= DPL 0, pres 1, long 1, def32 0, gran 1
processor eflags = interrupt enabled, resume, IOPL = 0
current process = 21 (swi5: +)
[thread pid 21 tid 100021 ]
Stopped at namei+0x174: movq 0x20(%rbx),%rax
db> bt
Tracing pid 21 tid 100021 td 0xffffff00013c3ae0
namei() at namei+0x174
vn_open_cred() at vn_open_cred+0x3a4
linker_load_module() at linker_load_module+0x1f2
linker_reference_module() at linker_reference_module+0xae
firmware_get() at firmware_get+0x136
mxge_load_firmware() at mxge_load_firmware+0x2d
mxge_watchdog_task() at mxge_watchdog_task+0x2f6
taskqueue_run() at taskqueue_run+0x9d
ithread_loop() at ithread_loop+0x17d
fork_exit() at fork_exit+0x11f
fork_trampoline() at fork_trampoline+0xe
Looking at it in gdb, it seems like the problem is that namei
is trying to use ndp->ni_cnd.cn_thread->td_proc->p_fd->fd_cdir
which is null in this context.
Can somebody tell me what kernel context it is safe to
call firmware_get() (and hence namei) from? Is there
a safe way to do it from a taskq?
FWIW, this seems to work fine (even from a callout context)
in 8 and higher. It is only 7 and earlier where I'm having
this problem.
Thanks,
Drew
More information about the freebsd-hackers
mailing list