Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

USB: usb-storage: use kthread_stop() for the control thread

This patch (as923) makes usb-storage's control thread use
kthread_should_stop()/kthread_stop(). The scanning thread can't be
similarly converted until the core kthread implementation allows
threads to call do_exit().

The advantage of this change is that we can now be certain the control
thread has terminated before storage_disconnect() returns. This will
simplify the locking requirements when autosuspend support is added.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Matthew Dharm <mdharm-usb@one-eyed-alien.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

authored by

Alan Stern and committed by
Greg Kroah-Hartman
ed76cacb 3fc154b6

+14 -25
+13 -25
drivers/usb/storage/usb.c
··· 425 425 mutex_unlock(&us->dev_mutex); 426 426 } /* for (;;) */ 427 427 428 - scsi_host_put(host); 429 - 430 - /* notify the exit routine that we're actually exiting now 431 - * 432 - * complete()/wait_for_completion() is similar to up()/down(), 433 - * except that complete() is safe in the case where the structure 434 - * is getting deleted in a parallel mode of execution (i.e. just 435 - * after the down() -- that's necessary for the thread-shutdown 436 - * case. 437 - * 438 - * complete_and_exit() goes even further than this -- it is safe in 439 - * the case that the thread of the caller is going away (not just 440 - * the structure) -- this is necessary for the module-remove case. 441 - * This is important in preemption kernels, which transfer the flow 442 - * of execution immediately upon a complete(). 443 - */ 444 - complete_and_exit(&threads_gone, 0); 428 + /* Wait until we are told to stop */ 429 + for (;;) { 430 + set_current_state(TASK_INTERRUPTIBLE); 431 + if (kthread_should_stop()) 432 + break; 433 + schedule(); 434 + } 435 + __set_current_state(TASK_RUNNING); 436 + return 0; 445 437 } 446 438 447 439 /*********************************************************************** ··· 801 809 } 802 810 803 811 /* Start up our control thread */ 804 - th = kthread_create(usb_stor_control_thread, us, "usb-storage"); 812 + th = kthread_run(usb_stor_control_thread, us, "usb-storage"); 805 813 if (IS_ERR(th)) { 806 814 printk(KERN_WARNING USB_STORAGE 807 815 "Unable to start control thread\n"); 808 816 return PTR_ERR(th); 809 817 } 810 - 811 - /* Take a reference to the host for the control thread and 812 - * count it among all the threads we have launched. Then 813 - * start it up. */ 814 - scsi_host_get(us_to_host(us)); 815 - atomic_inc(&total_threads); 816 - wake_up_process(th); 818 + us->ctl_thread = th; 817 819 818 820 return 0; 819 821 } ··· 824 838 US_DEBUGP("-- sending exit command to thread\n"); 825 839 set_bit(US_FLIDX_DISCONNECTING, &us->flags); 826 840 up(&us->sema); 841 + if (us->ctl_thread) 842 + kthread_stop(us->ctl_thread); 827 843 828 844 /* Call the destructor routine, if it exists */ 829 845 if (us->extra_destructor) {
+1
drivers/usb/storage/usb.h
··· 144 144 unsigned char *sensebuf; /* sense data buffer */ 145 145 dma_addr_t cr_dma; /* buffer DMA addresses */ 146 146 dma_addr_t iobuf_dma; 147 + struct task_struct *ctl_thread; /* the control thread */ 147 148 148 149 /* mutual exclusion and synchronization structures */ 149 150 struct semaphore sema; /* to sleep thread on */