Kernel panic when unloading libertas_sdio driver.

Yifei Liang dinuxlyf at gmail.com
Sat Jun 5 03:59:49 EDT 2010


Hi Marek
I am sorry for the last mail, it was the first time I send mail to the
mailing list, and I don’t know exactly why the format was wrong, so I
changed my mail server and hope this time it will work.

Right now I am porting wifi support on Android to the s3c6410 development
board which use WM-G-MR-09 as wireless LAN module. My kernel version is
2.6.32.
The problem I am dealing with is that sometimes when user process unload the
libertas_sdio module ,the kernel may panic at lbs_stop_card when trying to
wake up
the pending processes waiting for the command to complete.

lbs_deb_main("clearing pending commands\n");
list_for_each_entry(cmdnode, &priv->cmdpendingq, list) {
         cmdnode->result = -ENOENT;
         cmdnode->cmdwaitqwoken = 1;
         wake_up_interruptble(&cmdnode->cmdwait_q);
}

so I dump the cmd_ctrl_node structure before the wake up. The kernel dump
log is as follows:

libertas enter: lbs_stop_card()
libertas main: clearing pending commands
lbs_stop_card:has pending command node.
Dump command node:address of command node =c7ef00d8,list->prev
=c7f38d98,list->next=c7f38d90,
result = 0, address of callback=0, callback_arg = 0,address of cmdbuf =
c1d8d000,
cmdwaitqwoken = 1, address of cmdwait_q = c7ef00f4.
task state= 0, PID= 0.
Dump command node:address of command node =c7f38d90,list->prev
=c7ef00d8,list->next=c7ef0000,
result = -940637992, address of callback=c7ef0120, callback_arg =
c7f38da0,address of cmdbuf = c7f38da0,
cmdwaitqwoken = 8449, address of cmdwait_q = c7f38dac.
task state= 4001b508, PID= 65686361.
Unable to handle kernel NULL pointer dereference at virtual address 00000000
pgd = c7eb4000
[00000000] *pgd=57ead031, *pte=00000000, *ppte=00000000
Internal error: Oops: 80000007 [#1]
last sysfs file: /sys/android_power/request_state
Modules linked in: wlan(-) [last unloaded: wlan]
CPU: 0    Tainted: G        W   (2.6.32-00003-g930aecc-dirty #46)
PC is at 0x0
LR is at __wake_up_common+0x34/0x78
pc : [<00000000>]    lr : [<c0043d28>]    psr: a00000b3
sp : c7fbbdc8  ip : 00015000  fp : c7fbbdf4
r10: 00000000  r9 : 00000001  r8 : c7f38dac
r7 : 00000001  r6 : 00000001  r5 : 001027fc  r4 : 00014ff4
r3 : 00000000  r2 : 00000000  r1 : 00000001  r0 : 00014ff4
Flags: NzCv  IRQs off  FIQs on  Mode SVC_32  ISA Thumb  Segment user
Control: 00c5387d  Table: 57eb4008  DAC: 00000015
Process WifiService (pid: 1731, stack limit = 0xc7fba268)
Stack: (0xc7fbbdc8 to 0xc7fbc000)
bdc0:                   00000000 60000093 c7f38d90 c7f382c0 c7f38d98
c7f38000
bde0: c7fba000 00000013 c7fbbe14 c7fbbdf8 c0043d94 c0043d00 00000000
c7fbbe18
be00: c020239c c7f38dac c7fbbe54 c7fbbe18 c02023b0 c0043d78 c7ef00d8
c7ef0120
be20: c7f38da0 c7f38da0 00002101 c7f38dac c7cef3e0 c7fe0000 c7cef3e0
00000880
be40: c002c028 00000000 c7fbbe84 c7fbbe58 bf03015c c02021fc 00000000
c7cef3f0
be60: bf032a30 c7cef3e8 bf032a30 c7cef3e0 bf032a30 bf032a30 c7fbbe9c
c7fbbe88
be80: c024bbac bf03000c c7cef3e8 bf032a30 c7fbbeb4 c7fbbea0 c01d11f4
c024bb98
bea0: c7cef3e8 c7cef41c c7fbbed4 c7fbbeb8 c01d129c c01d1194 bf032a30
bf032a30
bec0: c041d93c 00000880 c7fbbef4 c7fbbed8 c01d04a4 c01d1240 00000000
bf032a30
bee0: 00000000 00000880 c7fbbf14 c7fbbef8 c01d1800 c01d0418 00000000
bf032a64
bf00: c7fbbf3c 00000880 c7fbbf24 c7fbbf18 c024bd9c c01d17a4 c7fbbf34
c7fbbf28
bf20: bf03208c c024bd88 c7fbbfa4 c7fbbf38 c006ccbc bf032024 c1c4f1e0
6e616c77
bf40: c7892200 00000006 c002c028 00000000 c7fbbf6c c7fbbf60 c009d3c0
c009d1d4
bf60: c7fbbf8c c7fbbf70 c009a00c c009d39c c7892240 00c4f1e0 bf032a64
00000880
bf80: c7fbbf84 00000000 a9c07658 ffffffff 00000009 00000081 00000000
c7fbbfa8
bfa0: c002be80 c006caf4 a9c07658 ffffffff a9c062e4 00000880 42747f3c
425f327c
bfc0: a9c07658 ffffffff 00000009 00000081 46364d88 42747ee4 42747ed0
002d90c8
bfe0: a9c07680 46364d50 a9c05c69 afe0d8ac 00000010 a9c062e4 00000000
00000000
Backtrace: 
[<c0043cf4>] (__wake_up_common+0x0/0x78) from [<c0043d94>]
(__wake_up+0x28/0x34)
[<c0043d6c>] (__wake_up+0x0/0x34) from [<c02023b0>]
(lbs_stop_card+0x1c0/0x338)

I track this problem, and found out it is cause by kill system call. My
analysis is as follows:

In android, when user wants to disable wifi, the java service will ask the
init process to stop the wpa_supplicant process, and then unload the wifi
driver.
The init process will use kill system call to stop wpa_supplicant. This may
cause a problem, because when kernel send a kill signal to a process, it
will has
to wake up the target process. The wpa_suppcliant may sleeping in __lbs_cmd
while waiting for a command to complete, and at the mean time the command
node may still in the priv->cmdpendingq, not submitted yet.
So after kernel wake up the process from wait_event_interruptible and clean
up the node and add it to the priv->cmdfreeq, the pending list node or head
is 
still keep link to it. 
When user unload the driver, the kernel will crash at __wake_up_common in
lbs_stop_card, because the command node still be linked by the
priv->cmdpendingq, 
when itself still link to the priv->cmdfreeq. The list_for_each_entry will
step to the list head of priv->cmdfreeq, which does not have a command node
structure
,and this will cause kernel panic when doing wake_up to it.

The command node at the address 0xc7ef00d8 is the node we discussed, it link
to the priv->cmdfreeq. 




More information about the libertas-dev mailing list