[PATCH 01/16] staging: usbip: usbip_common: kill rx thread on tx thread creation error.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Himanshu Chauhan <hschauhan@xxxxxxxxxxxxx>

Signed-off-by: Himanshu Chauhan <hschauhan@xxxxxxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxx>
---
 drivers/staging/usbip/usbip_common.c |   46 ++++++++++++++++++++++++---------
 1 files changed, 33 insertions(+), 13 deletions(-)

diff --git a/drivers/staging/usbip/usbip_common.c b/drivers/staging/usbip/usbip_common.c
index 5240816..6a499f0 100644
--- a/drivers/staging/usbip/usbip_common.c
+++ b/drivers/staging/usbip/usbip_common.c
@@ -378,47 +378,67 @@ int usbip_thread(void *param)
 	complete_and_exit(&ut->thread_done, 0);
 }
 
+static void stop_rx_thread(struct usbip_device *ud)
+{
+	if (ud->tcp_rx.thread != NULL) {
+		send_sig(SIGKILL, ud->tcp_rx.thread, 1);
+		wait_for_completion(&ud->tcp_rx.thread_done);
+		usbip_udbg("rx_thread for ud %p has finished\n", ud);
+	}
+}
+
+static void stop_tx_thread(struct usbip_device *ud)
+{
+	if (ud->tcp_tx.thread != NULL) {
+		send_sig(SIGKILL, ud->tcp_tx.thread, 1);
+		wait_for_completion(&ud->tcp_tx.thread_done);
+		usbip_udbg("tx_thread for ud %p has finished\n", ud);
+	}
+}
+
 int usbip_start_threads(struct usbip_device *ud)
 {
 	/*
 	 * threads are invoked per one device (per one connection).
 	 */
 	struct task_struct *th;
+	int err = 0;
 
 	th = kthread_run(usbip_thread, (void *)&ud->tcp_rx, "usbip");
 	if (IS_ERR(th)) {
 		printk(KERN_WARNING
 			"Unable to start control thread\n");
-		return PTR_ERR(th);
+		err = PTR_ERR(th);
+		goto ust_exit;
 	}
+
 	th = kthread_run(usbip_thread, (void *)&ud->tcp_tx, "usbip");
 	if (IS_ERR(th)) {
 		printk(KERN_WARNING
 			"Unable to start control thread\n");
-		return PTR_ERR(th);
+		err = PTR_ERR(th);
+		goto tx_thread_err;
 	}
 
 	/* confirm threads are starting */
 	wait_for_completion(&ud->tcp_rx.thread_done);
 	wait_for_completion(&ud->tcp_tx.thread_done);
+
 	return 0;
+
+tx_thread_err:
+	stop_rx_thread(ud);
+
+ust_exit:
+	return err;
 }
 EXPORT_SYMBOL_GPL(usbip_start_threads);
 
 void usbip_stop_threads(struct usbip_device *ud)
 {
 	/* kill threads related to this sdev, if v.c. exists */
-	if (ud->tcp_rx.thread != NULL) {
-		send_sig(SIGKILL, ud->tcp_rx.thread, 1);
-		wait_for_completion(&ud->tcp_rx.thread_done);
-		usbip_udbg("rx_thread for ud %p has finished\n", ud);
-	}
-
-	if (ud->tcp_tx.thread != NULL) {
-		send_sig(SIGKILL, ud->tcp_tx.thread, 1);
-		wait_for_completion(&ud->tcp_tx.thread_done);
-		usbip_udbg("tx_thread for ud %p has finished\n", ud);
-	}
+	stop_rx_thread(ud);
+	stop_tx_thread(ud);
 }
 EXPORT_SYMBOL_GPL(usbip_stop_threads);
 
-- 
1.7.1

_______________________________________________
devel mailing list
devel@xxxxxxxxxxxxxxxxxxxxxx
http://driverdev.linuxdriverproject.org/mailman/listinfo/devel


[Index of Archives]     [Linux Driver Backports]     [DMA Engine]     [Linux GPIO]     [Linux SPI]     [Video for Linux]     [Linux USB Devel]     [Linux Coverity]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux