Commit 9720b4bc76a83807c68e00c62bfba575251bb73e

Authored by Arnd Bergmann
Committed by Greg Kroah-Hartman
1 parent 8c81161615

staging/usbip: convert to kthread

usbip has its own infrastructure for managing kernel
threads, similar to kthread. By changing it to use
the standard functions, we can simplify the code
and get rid of one of the last BKL users at the
same time.

Includes changes suggested by Max Vozeler.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Cc: Greg Kroah-Hartman <gregkh@suse.de>
Cc: Takahiro Hirofuchi <hirofuchi@users.sourceforge.net>
Cc: Max Vozeler <max@vozeler.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

Showing 13 changed files with 64 additions and 203 deletions Side-by-side Diff

drivers/staging/usbip/Kconfig
1 1 config USB_IP_COMMON
2 2 tristate "USB IP support (EXPERIMENTAL)"
3   - depends on USB && NET && EXPERIMENTAL && BKL
  3 + depends on USB && NET && EXPERIMENTAL
4 4 default N
5 5 ---help---
6 6 This enables pushing USB packets over IP to allow remote
drivers/staging/usbip/stub.h
... ... @@ -95,13 +95,13 @@
95 95  
96 96 /* stub_tx.c */
97 97 void stub_complete(struct urb *);
98   -void stub_tx_loop(struct usbip_task *);
  98 +int stub_tx_loop(void *data);
99 99  
100 100 /* stub_dev.c */
101 101 extern struct usb_driver stub_driver;
102 102  
103 103 /* stub_rx.c */
104   -void stub_rx_loop(struct usbip_task *);
  104 +int stub_rx_loop(void *data);
105 105 void stub_enqueue_ret_unlink(struct stub_device *, __u32, __u32);
106 106  
107 107 /* stub_main.c */
drivers/staging/usbip/stub_dev.c
... ... @@ -18,6 +18,7 @@
18 18 */
19 19  
20 20 #include <linux/slab.h>
  21 +#include <linux/kthread.h>
21 22  
22 23 #include "usbip_common.h"
23 24 #include "stub.h"
... ... @@ -138,7 +139,8 @@
138 139  
139 140 spin_unlock(&sdev->ud.lock);
140 141  
141   - usbip_start_threads(&sdev->ud);
  142 + sdev->ud.tcp_rx = kthread_run(stub_rx_loop, &sdev->ud, "stub_rx");
  143 + sdev->ud.tcp_tx = kthread_run(stub_tx_loop, &sdev->ud, "stub_tx");
142 144  
143 145 spin_lock(&sdev->ud.lock);
144 146 sdev->ud.status = SDEV_ST_USED;
... ... @@ -218,7 +220,8 @@
218 220 }
219 221  
220 222 /* 1. stop threads */
221   - usbip_stop_threads(ud);
  223 + kthread_stop(ud->tcp_rx);
  224 + kthread_stop(ud->tcp_tx);
222 225  
223 226 /* 2. close the socket */
224 227 /*
... ... @@ -336,9 +339,6 @@
336 339 */
337 340 sdev->devid = (busnum << 16) | devnum;
338 341  
339   - usbip_task_init(&sdev->ud.tcp_rx, "stub_rx", stub_rx_loop);
340   - usbip_task_init(&sdev->ud.tcp_tx, "stub_tx", stub_tx_loop);
341   -
342 342 sdev->ud.side = USBIP_STUB;
343 343 sdev->ud.status = SDEV_ST_AVAILABLE;
344 344 /* sdev->ud.lock = SPIN_LOCK_UNLOCKED; */
... ... @@ -543,7 +543,7 @@
543 543 stub_remove_files(&interface->dev);
544 544  
545 545 /*If usb reset called from event handler*/
546   - if (busid_priv->sdev->ud.eh.thread == current) {
  546 + if (busid_priv->sdev->ud.eh == current) {
547 547 busid_priv->interf_count--;
548 548 return;
549 549 }
drivers/staging/usbip/stub_rx.c
... ... @@ -18,6 +18,7 @@
18 18 */
19 19  
20 20 #include <linux/slab.h>
  21 +#include <linux/kthread.h>
21 22  
22 23 #include "usbip_common.h"
23 24 #include "stub.h"
24 25  
25 26  
26 27  
... ... @@ -616,20 +617,16 @@
616 617  
617 618 }
618 619  
619   -void stub_rx_loop(struct usbip_task *ut)
  620 +int stub_rx_loop(void *data)
620 621 {
621   - struct usbip_device *ud = container_of(ut, struct usbip_device, tcp_rx);
  622 + struct usbip_device *ud = data;
622 623  
623   - while (1) {
624   - if (signal_pending(current)) {
625   - usbip_dbg_stub_rx("signal caught!\n");
626   - break;
627   - }
628   -
  624 + while (!kthread_should_stop()) {
629 625 if (usbip_event_happened(ud))
630 626 break;
631 627  
632 628 stub_rx_pdu(ud);
633 629 }
  630 + return 0;
634 631 }
drivers/staging/usbip/stub_tx.c
... ... @@ -18,6 +18,7 @@
18 18 */
19 19  
20 20 #include <linux/slab.h>
  21 +#include <linux/kthread.h>
21 22  
22 23 #include "usbip_common.h"
23 24 #include "stub.h"
24 25  
25 26  
... ... @@ -333,17 +334,12 @@
333 334  
334 335 /*-------------------------------------------------------------------------*/
335 336  
336   -void stub_tx_loop(struct usbip_task *ut)
  337 +int stub_tx_loop(void *data)
337 338 {
338   - struct usbip_device *ud = container_of(ut, struct usbip_device, tcp_tx);
  339 + struct usbip_device *ud = data;
339 340 struct stub_device *sdev = container_of(ud, struct stub_device, ud);
340 341  
341   - while (1) {
342   - if (signal_pending(current)) {
343   - usbip_dbg_stub_tx("signal catched\n");
344   - break;
345   - }
346   -
  342 + while (!kthread_should_stop()) {
347 343 if (usbip_event_happened(ud))
348 344 break;
349 345  
350 346  
... ... @@ -369,7 +365,10 @@
369 365  
370 366 wait_event_interruptible(sdev->tx_waitq,
371 367 (!list_empty(&sdev->priv_tx) ||
372   - !list_empty(&sdev->unlink_tx)));
  368 + !list_empty(&sdev->unlink_tx) ||
  369 + kthread_should_stop()));
373 370 }
  371 +
  372 + return 0;
374 373 }
drivers/staging/usbip/usbip_common.c
... ... @@ -18,7 +18,6 @@
18 18 */
19 19  
20 20 #include <linux/kernel.h>
21   -#include <linux/smp_lock.h>
22 21 #include <linux/file.h>
23 22 #include <linux/tcp.h>
24 23 #include <linux/in.h>
... ... @@ -348,110 +347,6 @@
348 347 }
349 348 }
350 349 EXPORT_SYMBOL_GPL(usbip_dump_header);
351   -
352   -
353   -/*-------------------------------------------------------------------------*/
354   -/* thread routines */
355   -
356   -int usbip_thread(void *param)
357   -{
358   - struct usbip_task *ut = param;
359   -
360   - if (!ut)
361   - return -EINVAL;
362   -
363   - lock_kernel();
364   - daemonize(ut->name);
365   - allow_signal(SIGKILL);
366   - ut->thread = current;
367   - unlock_kernel();
368   -
369   - /* srv.rb must wait for rx_thread starting */
370   - complete(&ut->thread_done);
371   -
372   - /* start of while loop */
373   - ut->loop_ops(ut);
374   -
375   - /* end of loop */
376   - ut->thread = NULL;
377   -
378   - complete_and_exit(&ut->thread_done, 0);
379   -}
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   -
399   -int usbip_start_threads(struct usbip_device *ud)
400   -{
401   - /*
402   - * threads are invoked per one device (per one connection).
403   - */
404   - struct task_struct *th;
405   - int err = 0;
406   -
407   - th = kthread_run(usbip_thread, (void *)&ud->tcp_rx, "usbip");
408   - if (IS_ERR(th)) {
409   - printk(KERN_WARNING
410   - "Unable to start control thread\n");
411   - err = PTR_ERR(th);
412   - goto ust_exit;
413   - }
414   -
415   - th = kthread_run(usbip_thread, (void *)&ud->tcp_tx, "usbip");
416   - if (IS_ERR(th)) {
417   - printk(KERN_WARNING
418   - "Unable to start control thread\n");
419   - err = PTR_ERR(th);
420   - goto tx_thread_err;
421   - }
422   -
423   - /* confirm threads are starting */
424   - wait_for_completion(&ud->tcp_rx.thread_done);
425   - wait_for_completion(&ud->tcp_tx.thread_done);
426   -
427   - return 0;
428   -
429   -tx_thread_err:
430   - stop_rx_thread(ud);
431   -
432   -ust_exit:
433   - return err;
434   -}
435   -EXPORT_SYMBOL_GPL(usbip_start_threads);
436   -
437   -void usbip_stop_threads(struct usbip_device *ud)
438   -{
439   - /* kill threads related to this sdev, if v.c. exists */
440   - stop_rx_thread(ud);
441   - stop_tx_thread(ud);
442   -}
443   -EXPORT_SYMBOL_GPL(usbip_stop_threads);
444   -
445   -void usbip_task_init(struct usbip_task *ut, char *name,
446   - void (*loop_ops)(struct usbip_task *))
447   -{
448   - ut->thread = NULL;
449   - init_completion(&ut->thread_done);
450   - ut->name = name;
451   - ut->loop_ops = loop_ops;
452   -}
453   -EXPORT_SYMBOL_GPL(usbip_task_init);
454   -
455 350  
456 351 /*-------------------------------------------------------------------------*/
457 352 /* socket routines */
drivers/staging/usbip/usbip_common.h
... ... @@ -307,13 +307,6 @@
307 307  
308 308 struct usbip_device;
309 309  
310   -struct usbip_task {
311   - struct task_struct *thread;
312   - struct completion thread_done;
313   - char *name;
314   - void (*loop_ops)(struct usbip_task *);
315   -};
316   -
317 310 enum usbip_side {
318 311 USBIP_VHCI,
319 312 USBIP_STUB,
... ... @@ -346,8 +339,8 @@
346 339  
347 340 struct socket *tcp_socket;
348 341  
349   - struct usbip_task tcp_rx;
350   - struct usbip_task tcp_tx;
  342 + struct task_struct *tcp_rx;
  343 + struct task_struct *tcp_tx;
351 344  
352 345 /* event handler */
353 346 #define USBIP_EH_SHUTDOWN (1 << 0)
... ... @@ -367,7 +360,7 @@
367 360 #define VDEV_EVENT_ERROR_MALLOC (USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE)
368 361  
369 362 unsigned long event;
370   - struct usbip_task eh;
  363 + struct task_struct *eh;
371 364 wait_queue_head_t eh_waitq;
372 365  
373 366 struct eh_ops {
... ... @@ -377,13 +370,6 @@
377 370 } eh_ops;
378 371 };
379 372  
380   -
381   -void usbip_task_init(struct usbip_task *ut, char *,
382   - void (*loop_ops)(struct usbip_task *));
383   -
384   -int usbip_start_threads(struct usbip_device *ud);
385   -void usbip_stop_threads(struct usbip_device *ud);
386   -int usbip_thread(void *param);
387 373  
388 374 void usbip_pack_pdu(struct usbip_header *pdu, struct urb *urb, int cmd,
389 375 int pack);
drivers/staging/usbip/usbip_event.c
... ... @@ -62,55 +62,43 @@
62 62 return 0;
63 63 }
64 64  
65   -static void event_handler_loop(struct usbip_task *ut)
  65 +static int event_handler_loop(void *data)
66 66 {
67   - struct usbip_device *ud = container_of(ut, struct usbip_device, eh);
  67 + struct usbip_device *ud = data;
68 68  
69   - while (1) {
70   - if (signal_pending(current)) {
71   - usbip_dbg_eh("signal catched!\n");
72   - break;
73   - }
  69 + while (!kthread_should_stop()) {
  70 + wait_event_interruptible(ud->eh_waitq,
  71 + usbip_event_happened(ud) ||
  72 + kthread_should_stop());
  73 + usbip_dbg_eh("wakeup\n");
74 74  
75 75 if (event_handler(ud) < 0)
76 76 break;
77   -
78   - wait_event_interruptible(ud->eh_waitq,
79   - usbip_event_happened(ud));
80   - usbip_dbg_eh("wakeup\n");
81 77 }
  78 + return 0;
82 79 }
83 80  
84 81 int usbip_start_eh(struct usbip_device *ud)
85 82 {
86   - struct usbip_task *eh = &ud->eh;
87   - struct task_struct *th;
88   -
89 83 init_waitqueue_head(&ud->eh_waitq);
90 84 ud->event = 0;
91 85  
92   - usbip_task_init(eh, "usbip_eh", event_handler_loop);
93   -
94   - th = kthread_run(usbip_thread, (void *)eh, "usbip");
95   - if (IS_ERR(th)) {
  86 + ud->eh = kthread_run(event_handler_loop, ud, "usbip_eh");
  87 + if (IS_ERR(ud->eh)) {
96 88 printk(KERN_WARNING
97 89 "Unable to start control thread\n");
98   - return PTR_ERR(th);
  90 + return PTR_ERR(ud->eh);
99 91 }
100   -
101   - wait_for_completion(&eh->thread_done);
102 92 return 0;
103 93 }
104 94 EXPORT_SYMBOL_GPL(usbip_start_eh);
105 95  
106 96 void usbip_stop_eh(struct usbip_device *ud)
107 97 {
108   - struct usbip_task *eh = &ud->eh;
109   -
110   - if (eh->thread == current)
  98 + if (ud->eh == current)
111 99 return; /* do not wait for myself */
112 100  
113   - wait_for_completion(&eh->thread_done);
  101 + kthread_stop(ud->eh);
114 102 usbip_dbg_eh("usbip_eh has finished\n");
115 103 }
116 104 EXPORT_SYMBOL_GPL(usbip_stop_eh);
drivers/staging/usbip/vhci.h
... ... @@ -113,8 +113,8 @@
113 113 /* vhci_hcd.c */
114 114 void rh_port_connect(int rhport, enum usb_device_speed speed);
115 115 void rh_port_disconnect(int rhport);
116   -void vhci_rx_loop(struct usbip_task *ut);
117   -void vhci_tx_loop(struct usbip_task *ut);
  116 +int vhci_rx_loop(void *data);
  117 +int vhci_tx_loop(void *data);
118 118  
119 119 struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev,
120 120 __u32 seqnum);
drivers/staging/usbip/vhci_hcd.c
... ... @@ -18,6 +18,7 @@
18 18 */
19 19  
20 20 #include <linux/slab.h>
  21 +#include <linux/kthread.h>
21 22  
22 23 #include "usbip_common.h"
23 24 #include "vhci.h"
... ... @@ -874,7 +875,10 @@
874 875 kernel_sock_shutdown(ud->tcp_socket, SHUT_RDWR);
875 876 }
876 877  
877   - usbip_stop_threads(&vdev->ud);
  878 + /* kill threads related to this sdev, if v.c. exists */
  879 + kthread_stop(vdev->ud.tcp_rx);
  880 + kthread_stop(vdev->ud.tcp_tx);
  881 +
878 882 usbip_uinfo("stop threads\n");
879 883  
880 884 /* active connection is closed */
... ... @@ -945,8 +949,8 @@
945 949 {
946 950 memset(vdev, 0, sizeof(*vdev));
947 951  
948   - usbip_task_init(&vdev->ud.tcp_rx, "vhci_rx", vhci_rx_loop);
949   - usbip_task_init(&vdev->ud.tcp_tx, "vhci_tx", vhci_tx_loop);
  952 + vdev->ud.tcp_rx = kthread_create(vhci_rx_loop, &vdev->ud, "vhci_rx");
  953 + vdev->ud.tcp_tx = kthread_create(vhci_tx_loop, &vdev->ud, "vhci_tx");
950 954  
951 955 vdev->ud.side = USBIP_VHCI;
952 956 vdev->ud.status = VDEV_ST_NULL;
drivers/staging/usbip/vhci_rx.c
... ... @@ -18,6 +18,7 @@
18 18 */
19 19  
20 20 #include <linux/slab.h>
  21 +#include <linux/kthread.h>
21 22  
22 23 #include "usbip_common.h"
23 24 #include "vhci.h"
24 25  
25 26  
26 27  
... ... @@ -269,22 +270,18 @@
269 270  
270 271 /*-------------------------------------------------------------------------*/
271 272  
272   -void vhci_rx_loop(struct usbip_task *ut)
  273 +int vhci_rx_loop(void *data)
273 274 {
274   - struct usbip_device *ud = container_of(ut, struct usbip_device, tcp_rx);
  275 + struct usbip_device *ud = data;
275 276  
276 277  
277   - while (1) {
278   - if (signal_pending(current)) {
279   - usbip_dbg_vhci_rx("signal catched!\n");
280   - break;
281   - }
282   -
283   -
  278 + while (!kthread_should_stop()) {
284 279 if (usbip_event_happened(ud))
285 280 break;
286 281  
287 282 vhci_rx_pdu(ud);
288 283 }
  284 +
  285 + return 0;
289 286 }
drivers/staging/usbip/vhci_sysfs.c
... ... @@ -220,15 +220,12 @@
220 220 vdev->ud.tcp_socket = socket;
221 221 vdev->ud.status = VDEV_ST_NOTASSIGNED;
222 222  
  223 + wake_up_process(vdev->ud.tcp_rx);
  224 + wake_up_process(vdev->ud.tcp_tx);
  225 +
223 226 spin_unlock(&vdev->ud.lock);
224 227 spin_unlock(&the_controller->lock);
225 228 /* end the lock */
226   -
227   - /*
228   - * this function will sleep, so should be out of the lock. but, it's ok
229   - * because we already marked vdev as being used. really?
230   - */
231   - usbip_start_threads(&vdev->ud);
232 229  
233 230 rh_port_connect(rhport, speed);
234 231  
drivers/staging/usbip/vhci_tx.c
... ... @@ -18,6 +18,7 @@
18 18 */
19 19  
20 20 #include <linux/slab.h>
  21 +#include <linux/kthread.h>
21 22  
22 23 #include "usbip_common.h"
23 24 #include "vhci.h"
24 25  
25 26  
... ... @@ -215,17 +216,12 @@
215 216  
216 217 /*-------------------------------------------------------------------------*/
217 218  
218   -void vhci_tx_loop(struct usbip_task *ut)
  219 +int vhci_tx_loop(void *data)
219 220 {
220   - struct usbip_device *ud = container_of(ut, struct usbip_device, tcp_tx);
  221 + struct usbip_device *ud = data;
221 222 struct vhci_device *vdev = container_of(ud, struct vhci_device, ud);
222 223  
223   - while (1) {
224   - if (signal_pending(current)) {
225   - usbip_uinfo("vhci_tx signal catched\n");
226   - break;
227   - }
228   -
  224 + while (!kthread_should_stop()) {
229 225 if (vhci_send_cmd_submit(vdev) < 0)
230 226 break;
231 227  
232 228  
... ... @@ -234,9 +230,12 @@
234 230  
235 231 wait_event_interruptible(vdev->waitq_tx,
236 232 (!list_empty(&vdev->priv_tx) ||
237   - !list_empty(&vdev->unlink_tx)));
  233 + !list_empty(&vdev->unlink_tx) ||
  234 + kthread_should_stop()));
238 235  
239 236 usbip_dbg_vhci_tx("pending urbs ?, now wake up\n");
240 237 }
  238 +
  239 + return 0;
241 240 }