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

staging: usbip: usbip_common: kill rx thread on tx thread creation error.

Signed-off-by: Himanshu Chauhan <hschauhan@nulltrace.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

authored by

Himanshu Chauhan and committed by
Greg Kroah-Hartman
f2102d31 93416253

+33 -13
+33 -13
drivers/staging/usbip/usbip_common.c
··· 378 378 complete_and_exit(&ut->thread_done, 0); 379 379 } 380 380 381 + static void stop_rx_thread(struct usbip_device *ud) 382 + { 383 + if (ud->tcp_rx.thread != NULL) { 384 + send_sig(SIGKILL, ud->tcp_rx.thread, 1); 385 + wait_for_completion(&ud->tcp_rx.thread_done); 386 + usbip_udbg("rx_thread for ud %p has finished\n", ud); 387 + } 388 + } 389 + 390 + static void stop_tx_thread(struct usbip_device *ud) 391 + { 392 + if (ud->tcp_tx.thread != NULL) { 393 + send_sig(SIGKILL, ud->tcp_tx.thread, 1); 394 + wait_for_completion(&ud->tcp_tx.thread_done); 395 + usbip_udbg("tx_thread for ud %p has finished\n", ud); 396 + } 397 + } 398 + 381 399 int usbip_start_threads(struct usbip_device *ud) 382 400 { 383 401 /* 384 402 * threads are invoked per one device (per one connection). 385 403 */ 386 404 struct task_struct *th; 405 + int err = 0; 387 406 388 407 th = kthread_run(usbip_thread, (void *)&ud->tcp_rx, "usbip"); 389 408 if (IS_ERR(th)) { 390 409 printk(KERN_WARNING 391 410 "Unable to start control thread\n"); 392 - return PTR_ERR(th); 411 + err = PTR_ERR(th); 412 + goto ust_exit; 393 413 } 414 + 394 415 th = kthread_run(usbip_thread, (void *)&ud->tcp_tx, "usbip"); 395 416 if (IS_ERR(th)) { 396 417 printk(KERN_WARNING 397 418 "Unable to start control thread\n"); 398 - return PTR_ERR(th); 419 + err = PTR_ERR(th); 420 + goto tx_thread_err; 399 421 } 400 422 401 423 /* confirm threads are starting */ 402 424 wait_for_completion(&ud->tcp_rx.thread_done); 403 425 wait_for_completion(&ud->tcp_tx.thread_done); 426 + 404 427 return 0; 428 + 429 + tx_thread_err: 430 + stop_rx_thread(ud); 431 + 432 + ust_exit: 433 + return err; 405 434 } 406 435 EXPORT_SYMBOL_GPL(usbip_start_threads); 407 436 408 437 void usbip_stop_threads(struct usbip_device *ud) 409 438 { 410 439 /* kill threads related to this sdev, if v.c. exists */ 411 - if (ud->tcp_rx.thread != NULL) { 412 - send_sig(SIGKILL, ud->tcp_rx.thread, 1); 413 - wait_for_completion(&ud->tcp_rx.thread_done); 414 - usbip_udbg("rx_thread for ud %p has finished\n", ud); 415 - } 416 - 417 - if (ud->tcp_tx.thread != NULL) { 418 - send_sig(SIGKILL, ud->tcp_tx.thread, 1); 419 - wait_for_completion(&ud->tcp_tx.thread_done); 420 - usbip_udbg("tx_thread for ud %p has finished\n", ud); 421 - } 440 + stop_rx_thread(ud); 441 + stop_tx_thread(ud); 422 442 } 423 443 EXPORT_SYMBOL_GPL(usbip_stop_threads); 424 444