On Sat, 9 Nov 2002, David Brownell wrote:
> > One system seems to suffer from "khubd exit during startup"
> > more than others. I applied that patch to make it ignore
> > signals, and noticed that while khubd no longer exited, it
> > didn't exactly start either: stuck in D state like this:
> >
> > khubd D 00000000 0 72 1 243 11 (L-TLB)
> > Call Trace:
> > [<c012322e>] reparent_to_init+0x12e/0x170
>
> This is the call to security_ops->task_reparent_to_init() ...
Which sounds suspicious because this is called under spinlock. OTOH I'm
missing some synchronisation between the khubd and the forking thread.
Maybe the modprobing process exits before khubd gets scheduled for the
first time.
IMHO the attached patch should improve things. However, this needs some
review wrt. usb-storage issues - IIRC there was some issue with storage
devices hanging in umount during reboot/shutdown. I have no such device to
try with. And the whole shutdown seems to Oops for me anyway...
Finally, I can reproduce the khubd exit with 2.5.46. For me it happens
within a few device connect/disconnect events that khubd gets killed by
the kernel (i.e. despite all signals are blocked) due to sysfs running
into redzoned memory BUG in mm/slab.c:1615, see below.
Martin
--------------------------
drivers/usb/core/hub.c: hub 2 port 2 connection change
drivers/usb/core/hub.c: hub 2 port 2, portstatus 101, change 1, 12 Mb/s
drivers/usb/core/hub.c: port 2, portstatus 101, change 0, 12 Mb/s
drivers/usb/core/hub.c: port 2, portstatus 101, change 0, 12 Mb/s
drivers/usb/core/hub.c: port 2, portstatus 101, change 0, 12 Mb/s
drivers/usb/core/hub.c: port 2, portstatus 101, change 0, 12 Mb/s
drivers/usb/core/hub.c: port 2, portstatus 111, change 0, 12 Mb/s
drivers/usb/core/hub.c: port 2 of hub 2 not reset yet, waiting 10ms
drivers/usb/core/hub.c: port 2, portstatus 103, change 10, 12 Mb/s
drivers/usb/core/hub.c: new USB device 00:0c.0-2.2, assigned address 5
drivers/usb/core/usb.c: new device strings: Mfr=0, Product=0, SerialNumber=0
------------[ cut here ]------------
kernel BUG at mm/slab.c:1615!
invalid operand: 0000
parport_pc lp parport usblp ohci-hcd usbcore ne2k-pci 8390 crc32 rtc
CPU: 0
EIP: 0060:[<c013e7f6>] Not tainted
EFLAGS: 00010293
EIP is at kmalloc+0xd6/0x140
eax: 00000000 ebx: cbfff1d0 ecx: 00000000 edx: 00000400
esi: c7e249b8 edi: cbfff1d0 ebp: c7e249b8 esp: c8335df4
ds: 0068 es: 0068 ss: 0068
Process khubd (pid: 490, threadinfo=c8334000 task=cbd5e060)
Stack: 00000000 c01842af cbffaa00 00000000 c73595ac c7359f3c c01843c4 c73595ac
00000004 00000000 c8315d08 00000030 c0184aed 00000030 000001d0 00000000
c01849c9 c69e445c c73595ac c8674abc c8a410ec cd0639a4 cd0639a0 00000000
Call Trace:
[<c01842af>] sysfs_get_inode+0xf/0xf0
[<c01843c4>] sysfs_mknod+0x34/0x50
[<c0184aed>] sysfs_create_link+0x4d/0x130
[<c01849c9>] sysfs_create_file+0x69/0x90
[<cd0639a4>] usb_bus_type+0x4/0x160 [usbcore]
[<cd0639a0>] usb_bus_type+0x0/0x160 [usbcore]
[<c01bcf03>] attach+0x33/0x40
[<cd06393c>] usb_generic_driver+0x1c/0x80 [usbcore]
[<cd063ac4>] usb_bus_type+0x124/0x160 [usbcore]
[<c01bcfa3>] device_attach+0x23/0x90
[<cd063ac4>] usb_bus_type+0x124/0x160 [usbcore]
[<cd0639a4>] usb_bus_type+0x4/0x160 [usbcore]
[<cd0639a0>] usb_bus_type+0x0/0x160 [usbcore]
[<c01bd1c1>] bus_add_device+0x71/0xb0
[<c01bc24b>] device_add+0xfb/0x170
[<c01bc39b>] device_register+0x4b/0x70
[<cd05118d>] usb_new_device_Rsmp_66d3a372+0x2fd/0x460 [usbcore]
[<c0107f4b>] __down_failed_trylock+0x7/0xc
[<cd053372>] usb_hub_port_connect_change+0x222/0x2c0 [usbcore]
[<cd060a60>] .LC63+0xfc0/0x11e0 [usbcore]
[<cd0535cb>] usb_hub_events+0x1bb/0x3c0 [usbcore]
[<cd060b60>] .LC63+0x10c0/0x11e0 [usbcore]
[<cd0538e5>] usb_hub_thread+0x115/0x1a0 [usbcore]
[<c011bbe0>] default_wake_function+0x0/0x40
[<c01090e5>] ret_from_fork+0x5/0x10
[<c011bbe0>] default_wake_function+0x0/0x40
[<cd063b38>] khubd_wait+0x8/0x10 [usbcore]
[<cd063b38>] khubd_wait+0x8/0x10 [usbcore]
[<cd0537d0>] usb_hub_thread+0x0/0x1a0 [usbcore]
[<c010705d>] kernel_thread_helper+0x5/0x18
Code: 0f 0b 4f 06 09 35 26 c0 89 f2 b8 a5 c2 0f 17 03 53 34 87 42
--- linux-2.5.46/drivers/usb/core/hub.c Sat Nov 2 18:28:01 2002
+++ v2.5.46-md/drivers/usb/core/hub.c Sun Nov 10 13:05:28 2002
@@ -1051,8 +1051,10 @@
spin_unlock_irqrestore(&hub_event_lock, flags);
}
-static int usb_hub_thread(void *__hub)
+static int usb_hub_thread(void *startup)
{
+ DECLARE_WAITQUEUE(wait, current);
+
/*
* This thread doesn't need any user-level access,
* so get rid of all our resources
@@ -1063,13 +1065,27 @@
/* Setup a nice name */
strcpy(current->comm, "khubd");
- /* Send me a signal to get me die (for debugging) */
+ spin_lock_irq(¤t->sig->siglock);
+ sigfillset(¤t->blocked);
+ recalc_sigpending();
+ spin_unlock_irq(¤t->sig->siglock);
+
+ khubd_pid = current->pid;
+ complete((struct completion *)startup);
+
+ /* Set khubd_pid=0 to get me die */
do {
usb_hub_events();
- wait_event_interruptible(khubd_wait, !list_empty(&hub_event_list));
+ set_task_state(current, TASK_UNINTERRUPTIBLE);
+ add_wait_queue(&khubd_wait, &wait);
+ if (list_empty(&hub_event_list))
+ schedule();
+ else
+ set_task_state(current, TASK_RUNNING);
+ remove_wait_queue(&khubd_wait, &wait);
if (current->flags & PF_FREEZE)
refrigerator(PF_IOTHREAD);
- } while (!signal_pending(current));
+ } while (khubd_pid > 0);
dbg("usb_hub_thread exiting");
complete_and_exit(&khubd_exited, 0);
@@ -1098,6 +1114,7 @@
*/
int usb_hub_init(void)
{
+ struct completion startup;
int pid;
if (usb_register(&hub_driver) < 0) {
@@ -1105,11 +1122,10 @@
return -1;
}
- pid = kernel_thread(usb_hub_thread, NULL,
- CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
- if (pid >= 0) {
- khubd_pid = pid;
-
+ init_completion(&startup);
+ pid = kernel_thread(usb_hub_thread, &startup, CLONE_FS | CLONE_FILES);
+ if (pid > 0) {
+ wait_for_completion(&startup);
return 0;
}
@@ -1122,10 +1138,10 @@
void usb_hub_cleanup(void)
{
- int ret;
-
/* Kill the thread */
- ret = kill_proc(khubd_pid, SIGTERM, 1);
+ init_completion(&khubd_exited);
+ khubd_pid = 0;
+ wake_up(&khubd_wait);
wait_for_completion(&khubd_exited);