diff options
author | David Herrmann <dh.herrmann@googlemail.com> | 2011-10-24 09:30:58 -0400 |
---|---|---|
committer | Gustavo F. Padovan <padovan@profusion.mobi> | 2011-11-07 14:24:40 -0500 |
commit | 96af7391b752cf3d2de3aef8f03c45ba76d3ac5e (patch) | |
tree | 2aa2af0a3fb4980199056df76fdf4a8eeb108bf5 | |
parent | 5ada9913630d48438f2e07551af43cbf297372d4 (diff) |
Bluetooth: Replace rfcomm tty tasklet by workqueue
Remove old tasklets and replace by workqueue. To avoid reentrancy (which
tasklets always avoid) we use the system_nrt_wq.
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
-rw-r--r-- | net/bluetooth/rfcomm/tty.c | 16 |
1 files changed, 9 insertions, 7 deletions
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index 2b753a3f4d61..947f1b3afd15 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/capability.h> | 34 | #include <linux/capability.h> |
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <linux/skbuff.h> | 36 | #include <linux/skbuff.h> |
37 | #include <linux/workqueue.h> | ||
37 | 38 | ||
38 | #include <net/bluetooth/bluetooth.h> | 39 | #include <net/bluetooth/bluetooth.h> |
39 | #include <net/bluetooth/hci_core.h> | 40 | #include <net/bluetooth/hci_core.h> |
@@ -65,7 +66,7 @@ struct rfcomm_dev { | |||
65 | struct rfcomm_dlc *dlc; | 66 | struct rfcomm_dlc *dlc; |
66 | struct tty_struct *tty; | 67 | struct tty_struct *tty; |
67 | wait_queue_head_t wait; | 68 | wait_queue_head_t wait; |
68 | struct tasklet_struct wakeup_task; | 69 | struct work_struct wakeup_task; |
69 | 70 | ||
70 | struct device *tty_dev; | 71 | struct device *tty_dev; |
71 | 72 | ||
@@ -81,7 +82,7 @@ static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb); | |||
81 | static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err); | 82 | static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err); |
82 | static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig); | 83 | static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig); |
83 | 84 | ||
84 | static void rfcomm_tty_wakeup(unsigned long arg); | 85 | static void rfcomm_tty_wakeup(struct work_struct *work); |
85 | 86 | ||
86 | /* ---- Device functions ---- */ | 87 | /* ---- Device functions ---- */ |
87 | static void rfcomm_dev_destruct(struct rfcomm_dev *dev) | 88 | static void rfcomm_dev_destruct(struct rfcomm_dev *dev) |
@@ -257,7 +258,7 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc) | |||
257 | atomic_set(&dev->opened, 0); | 258 | atomic_set(&dev->opened, 0); |
258 | 259 | ||
259 | init_waitqueue_head(&dev->wait); | 260 | init_waitqueue_head(&dev->wait); |
260 | tasklet_init(&dev->wakeup_task, rfcomm_tty_wakeup, (unsigned long) dev); | 261 | INIT_WORK(&dev->wakeup_task, rfcomm_tty_wakeup); |
261 | 262 | ||
262 | skb_queue_head_init(&dev->pending); | 263 | skb_queue_head_init(&dev->pending); |
263 | 264 | ||
@@ -351,7 +352,7 @@ static void rfcomm_wfree(struct sk_buff *skb) | |||
351 | struct rfcomm_dev *dev = (void *) skb->sk; | 352 | struct rfcomm_dev *dev = (void *) skb->sk; |
352 | atomic_sub(skb->truesize, &dev->wmem_alloc); | 353 | atomic_sub(skb->truesize, &dev->wmem_alloc); |
353 | if (test_bit(RFCOMM_TTY_ATTACHED, &dev->flags)) | 354 | if (test_bit(RFCOMM_TTY_ATTACHED, &dev->flags)) |
354 | tasklet_schedule(&dev->wakeup_task); | 355 | queue_work(system_nrt_wq, &dev->wakeup_task); |
355 | rfcomm_dev_put(dev); | 356 | rfcomm_dev_put(dev); |
356 | } | 357 | } |
357 | 358 | ||
@@ -635,9 +636,10 @@ static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig) | |||
635 | } | 636 | } |
636 | 637 | ||
637 | /* ---- TTY functions ---- */ | 638 | /* ---- TTY functions ---- */ |
638 | static void rfcomm_tty_wakeup(unsigned long arg) | 639 | static void rfcomm_tty_wakeup(struct work_struct *work) |
639 | { | 640 | { |
640 | struct rfcomm_dev *dev = (void *) arg; | 641 | struct rfcomm_dev *dev = container_of(work, struct rfcomm_dev, |
642 | wakeup_task); | ||
641 | struct tty_struct *tty = dev->tty; | 643 | struct tty_struct *tty = dev->tty; |
642 | if (!tty) | 644 | if (!tty) |
643 | return; | 645 | return; |
@@ -762,7 +764,7 @@ static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp) | |||
762 | rfcomm_dlc_close(dev->dlc, 0); | 764 | rfcomm_dlc_close(dev->dlc, 0); |
763 | 765 | ||
764 | clear_bit(RFCOMM_TTY_ATTACHED, &dev->flags); | 766 | clear_bit(RFCOMM_TTY_ATTACHED, &dev->flags); |
765 | tasklet_kill(&dev->wakeup_task); | 767 | cancel_work_sync(&dev->wakeup_task); |
766 | 768 | ||
767 | rfcomm_dlc_lock(dev->dlc); | 769 | rfcomm_dlc_lock(dev->dlc); |
768 | tty->driver_data = NULL; | 770 | tty->driver_data = NULL; |