diff options
author | Tejun Heo <tj@kernel.org> | 2010-12-24 09:59:06 -0500 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2010-12-24 09:59:06 -0500 |
commit | 158fa67753e1eb3edfa5a2d1868666d89d1cf09f (patch) | |
tree | 27d65da02ac7d6e4844c8e84af990cadaed2ac19 | |
parent | 7fa5e85a0ab9ed5d2d8b77eec7976c88a5911bda (diff) |
isdn/capi: make kcapi use a separate workqueue
flush_scheduled_work() is deprecated and will be removed. Because
kcapi uses fire-and-forget type works, it's impossible to flush each
work explicitly. Create and use a dedicated workqueue instead.
Please note that with recent workqueue changes, each workqueue doesn't
reserve a lot of resources and using it as a flush domain is fine.
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Jan Kiszka <jan.kiszka@web.de>
-rw-r--r-- | drivers/isdn/capi/kcapi.c | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c index 3acf94cc5acd..2b33b2627fce 100644 --- a/drivers/isdn/capi/kcapi.c +++ b/drivers/isdn/capi/kcapi.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/rcupdate.h> | 38 | #include <linux/rcupdate.h> |
39 | 39 | ||
40 | static int showcapimsgs = 0; | 40 | static int showcapimsgs = 0; |
41 | static struct workqueue_struct *kcapi_wq; | ||
41 | 42 | ||
42 | MODULE_DESCRIPTION("CAPI4Linux: kernel CAPI layer"); | 43 | MODULE_DESCRIPTION("CAPI4Linux: kernel CAPI layer"); |
43 | MODULE_AUTHOR("Carsten Paeth"); | 44 | MODULE_AUTHOR("Carsten Paeth"); |
@@ -291,7 +292,7 @@ static int notify_push(unsigned int event_type, u32 controller) | |||
291 | event->type = event_type; | 292 | event->type = event_type; |
292 | event->controller = controller; | 293 | event->controller = controller; |
293 | 294 | ||
294 | schedule_work(&event->work); | 295 | queue_work(kcapi_wq, &event->work); |
295 | return 0; | 296 | return 0; |
296 | } | 297 | } |
297 | 298 | ||
@@ -408,7 +409,7 @@ void capi_ctr_handle_message(struct capi_ctr *ctr, u16 appl, | |||
408 | goto error; | 409 | goto error; |
409 | } | 410 | } |
410 | skb_queue_tail(&ap->recv_queue, skb); | 411 | skb_queue_tail(&ap->recv_queue, skb); |
411 | schedule_work(&ap->recv_work); | 412 | queue_work(kcapi_wq, &ap->recv_work); |
412 | rcu_read_unlock(); | 413 | rcu_read_unlock(); |
413 | 414 | ||
414 | return; | 415 | return; |
@@ -743,7 +744,7 @@ u16 capi20_release(struct capi20_appl *ap) | |||
743 | 744 | ||
744 | mutex_unlock(&capi_controller_lock); | 745 | mutex_unlock(&capi_controller_lock); |
745 | 746 | ||
746 | flush_scheduled_work(); | 747 | flush_workqueue(kcapi_wq); |
747 | skb_queue_purge(&ap->recv_queue); | 748 | skb_queue_purge(&ap->recv_queue); |
748 | 749 | ||
749 | if (showcapimsgs & 1) { | 750 | if (showcapimsgs & 1) { |
@@ -1285,21 +1286,30 @@ static int __init kcapi_init(void) | |||
1285 | { | 1286 | { |
1286 | int err; | 1287 | int err; |
1287 | 1288 | ||
1289 | kcapi_wq = alloc_workqueue("kcapi", 0, 0); | ||
1290 | if (!kcapi_wq) | ||
1291 | return -ENOMEM; | ||
1292 | |||
1288 | register_capictr_notifier(&capictr_nb); | 1293 | register_capictr_notifier(&capictr_nb); |
1289 | 1294 | ||
1290 | err = cdebug_init(); | 1295 | err = cdebug_init(); |
1291 | if (!err) | 1296 | if (err) { |
1292 | kcapi_proc_init(); | 1297 | unregister_capictr_notifier(&capictr_nb); |
1293 | return err; | 1298 | destroy_workqueue(kcapi_wq); |
1299 | return err; | ||
1300 | } | ||
1301 | |||
1302 | kcapi_proc_init(); | ||
1303 | return 0; | ||
1294 | } | 1304 | } |
1295 | 1305 | ||
1296 | static void __exit kcapi_exit(void) | 1306 | static void __exit kcapi_exit(void) |
1297 | { | 1307 | { |
1298 | kcapi_proc_exit(); | 1308 | kcapi_proc_exit(); |
1299 | 1309 | ||
1300 | /* make sure all notifiers are finished */ | 1310 | unregister_capictr_notifier(&capictr_nb); |
1301 | flush_scheduled_work(); | ||
1302 | cdebug_exit(); | 1311 | cdebug_exit(); |
1312 | destroy_workqueue(kcapi_wq); | ||
1303 | } | 1313 | } |
1304 | 1314 | ||
1305 | module_init(kcapi_init); | 1315 | module_init(kcapi_init); |