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(&current->sig->siglock);
+       sigfillset(&current->blocked);
+       recalc_sigpending();
+       spin_unlock_irq(&current->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);
 

Reply via email to