aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/misc/lvstest.c
diff options
context:
space:
mode:
authorBhaktipriya Shridhar <bhaktipriya96@gmail.com>2016-07-28 04:45:11 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-08-09 09:49:01 -0400
commitbd783108acfe359f1817365823d4a98d79e37dbb (patch)
treee910147b4593e2819d64989a39a53117273dce3e /drivers/usb/misc/lvstest.c
parent72cd194f897d7f7e334d570662b25f71068e5637 (diff)
usb: lvstest: Remove deprecated create_singlethread_workqueue
The workqueue has a single work item(&lvs->rh_work) and hence doesn't require ordering. Also, it is not being used on a memory reclaim path. Hence, the singlethreaded workqueue has been replaced with the use of system_wq. System workqueues have been able to handle high level of concurrency for a long time now and hence it's not required to have a singlethreaded workqueue just to gain concurrency. Unlike a dedicated per-cpu workqueue created with create_singlethread_workqueue(), system_wq allows multiple work items to overlap executions even on the same CPU; however, a per-cpu workqueue doesn't have any CPU locality or global ordering guarantee unless the target CPU is explicitly specified and thus the increase of local concurrency shouldn't make any difference. The work item has been flushed in lvs_rh_disconnect() to ensure that there are no pending tasks while disconnecting the driver. Signed-off-by: Bhaktipriya Shridhar <bhaktipriya96@gmail.com> Acked-by: Tejun Heo <tj@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/misc/lvstest.c')
-rw-r--r--drivers/usb/misc/lvstest.c17
1 files changed, 3 insertions, 14 deletions
diff --git a/drivers/usb/misc/lvstest.c b/drivers/usb/misc/lvstest.c
index 86b4e4b2ab9a..a985cadc0b76 100644
--- a/drivers/usb/misc/lvstest.c
+++ b/drivers/usb/misc/lvstest.c
@@ -34,8 +34,6 @@ struct lvs_rh {
34 struct usb_hub_descriptor descriptor; 34 struct usb_hub_descriptor descriptor;
35 /* urb for polling interrupt pipe */ 35 /* urb for polling interrupt pipe */
36 struct urb *urb; 36 struct urb *urb;
37 /* LVS RH work queue */
38 struct workqueue_struct *rh_queue;
39 /* LVH RH work */ 37 /* LVH RH work */
40 struct work_struct rh_work; 38 struct work_struct rh_work;
41 /* RH port status */ 39 /* RH port status */
@@ -355,7 +353,7 @@ static void lvs_rh_irq(struct urb *urb)
355{ 353{
356 struct lvs_rh *lvs = urb->context; 354 struct lvs_rh *lvs = urb->context;
357 355
358 queue_work(lvs->rh_queue, &lvs->rh_work); 356 schedule_work(&lvs->rh_work);
359} 357}
360 358
361static int lvs_rh_probe(struct usb_interface *intf, 359static int lvs_rh_probe(struct usb_interface *intf,
@@ -402,19 +400,12 @@ static int lvs_rh_probe(struct usb_interface *intf,
402 return -ENOMEM; 400 return -ENOMEM;
403 } 401 }
404 402
405 lvs->rh_queue = create_singlethread_workqueue("lvs_rh_queue");
406 if (!lvs->rh_queue) {
407 dev_err(&intf->dev, "couldn't create workqueue\n");
408 ret = -ENOMEM;
409 goto free_urb;
410 }
411
412 INIT_WORK(&lvs->rh_work, lvs_rh_work); 403 INIT_WORK(&lvs->rh_work, lvs_rh_work);
413 404
414 ret = sysfs_create_group(&intf->dev.kobj, &lvs_attr_group); 405 ret = sysfs_create_group(&intf->dev.kobj, &lvs_attr_group);
415 if (ret < 0) { 406 if (ret < 0) {
416 dev_err(&intf->dev, "Failed to create sysfs node %d\n", ret); 407 dev_err(&intf->dev, "Failed to create sysfs node %d\n", ret);
417 goto destroy_queue; 408 goto free_urb;
418 } 409 }
419 410
420 pipe = usb_rcvintpipe(hdev, endpoint->bEndpointAddress); 411 pipe = usb_rcvintpipe(hdev, endpoint->bEndpointAddress);
@@ -432,8 +423,6 @@ static int lvs_rh_probe(struct usb_interface *intf,
432 423
433sysfs_remove: 424sysfs_remove:
434 sysfs_remove_group(&intf->dev.kobj, &lvs_attr_group); 425 sysfs_remove_group(&intf->dev.kobj, &lvs_attr_group);
435destroy_queue:
436 destroy_workqueue(lvs->rh_queue);
437free_urb: 426free_urb:
438 usb_free_urb(lvs->urb); 427 usb_free_urb(lvs->urb);
439 return ret; 428 return ret;
@@ -444,7 +433,7 @@ static void lvs_rh_disconnect(struct usb_interface *intf)
444 struct lvs_rh *lvs = usb_get_intfdata(intf); 433 struct lvs_rh *lvs = usb_get_intfdata(intf);
445 434
446 sysfs_remove_group(&intf->dev.kobj, &lvs_attr_group); 435 sysfs_remove_group(&intf->dev.kobj, &lvs_attr_group);
447 destroy_workqueue(lvs->rh_queue); 436 flush_work(&lvs->rh_work);
448 usb_free_urb(lvs->urb); 437 usb_free_urb(lvs->urb);
449} 438}
450 439