aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJiri Slaby <jslaby@suse.cz>2012-04-02 07:54:51 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-04-09 15:04:31 -0400
commit67054019289ff11a7ffbc1a5d3c95aeb36e2f03e (patch)
treeaaae7634460e55683c1688732acbeefa2064c1f6 /net
parentf60db8c4246ac7c33448fad173bed85354b7d75e (diff)
TTY: rfcomm/tty, use tty_port refcounting
Switch the refcounting from manual atomic plays with refcounter to the one offered by tty_port. Signed-off-by: Jiri Slaby <jslaby@suse.cz> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/rfcomm/tty.c58
1 files changed, 26 insertions, 32 deletions
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index 97c2a087a9f1..da4f54515775 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -50,7 +50,6 @@ static struct tty_driver *rfcomm_tty_driver;
50struct rfcomm_dev { 50struct rfcomm_dev {
51 struct tty_port port; 51 struct tty_port port;
52 struct list_head list; 52 struct list_head list;
53 atomic_t refcnt;
54 53
55 char name[12]; 54 char name[12];
56 int id; 55 int id;
@@ -85,8 +84,17 @@ static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig);
85static void rfcomm_tty_wakeup(struct work_struct *work); 84static void rfcomm_tty_wakeup(struct work_struct *work);
86 85
87/* ---- Device functions ---- */ 86/* ---- Device functions ---- */
88static void rfcomm_dev_destruct(struct rfcomm_dev *dev) 87
88/*
89 * The reason this isn't actually a race, as you no doubt have a little voice
90 * screaming at you in your head, is that the refcount should never actually
91 * reach zero unless the device has already been taken off the list, in
92 * rfcomm_dev_del(). And if that's not true, we'll hit the BUG() in
93 * rfcomm_dev_destruct() anyway.
94 */
95static void rfcomm_dev_destruct(struct tty_port *port)
89{ 96{
97 struct rfcomm_dev *dev = container_of(port, struct rfcomm_dev, port);
90 struct rfcomm_dlc *dlc = dev->dlc; 98 struct rfcomm_dlc *dlc = dev->dlc;
91 99
92 BT_DBG("dev %p dlc %p", dev, dlc); 100 BT_DBG("dev %p dlc %p", dev, dlc);
@@ -113,23 +121,9 @@ static void rfcomm_dev_destruct(struct rfcomm_dev *dev)
113 module_put(THIS_MODULE); 121 module_put(THIS_MODULE);
114} 122}
115 123
116static inline void rfcomm_dev_hold(struct rfcomm_dev *dev) 124static const struct tty_port_operations rfcomm_port_ops = {
117{ 125 .destruct = rfcomm_dev_destruct,
118 atomic_inc(&dev->refcnt); 126};
119}
120
121static inline void rfcomm_dev_put(struct rfcomm_dev *dev)
122{
123 /* The reason this isn't actually a race, as you no
124 doubt have a little voice screaming at you in your
125 head, is that the refcount should never actually
126 reach zero unless the device has already been taken
127 off the list, in rfcomm_dev_del(). And if that's not
128 true, we'll hit the BUG() in rfcomm_dev_destruct()
129 anyway. */
130 if (atomic_dec_and_test(&dev->refcnt))
131 rfcomm_dev_destruct(dev);
132}
133 127
134static struct rfcomm_dev *__rfcomm_dev_get(int id) 128static struct rfcomm_dev *__rfcomm_dev_get(int id)
135{ 129{
@@ -154,7 +148,7 @@ static inline struct rfcomm_dev *rfcomm_dev_get(int id)
154 if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags)) 148 if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags))
155 dev = NULL; 149 dev = NULL;
156 else 150 else
157 rfcomm_dev_hold(dev); 151 tty_port_get(&dev->port);
158 } 152 }
159 153
160 spin_unlock(&rfcomm_dev_lock); 154 spin_unlock(&rfcomm_dev_lock);
@@ -241,7 +235,6 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
241 sprintf(dev->name, "rfcomm%d", dev->id); 235 sprintf(dev->name, "rfcomm%d", dev->id);
242 236
243 list_add(&dev->list, head); 237 list_add(&dev->list, head);
244 atomic_set(&dev->refcnt, 1);
245 238
246 bacpy(&dev->src, &req->src); 239 bacpy(&dev->src, &req->src);
247 bacpy(&dev->dst, &req->dst); 240 bacpy(&dev->dst, &req->dst);
@@ -253,6 +246,7 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
253 atomic_set(&dev->opened, 0); 246 atomic_set(&dev->opened, 0);
254 247
255 tty_port_init(&dev->port); 248 tty_port_init(&dev->port);
249 dev->port.ops = &rfcomm_port_ops;
256 init_waitqueue_head(&dev->wait); 250 init_waitqueue_head(&dev->wait);
257 INIT_WORK(&dev->wakeup_task, rfcomm_tty_wakeup); 251 INIT_WORK(&dev->wakeup_task, rfcomm_tty_wakeup);
258 252
@@ -332,7 +326,7 @@ static void rfcomm_dev_del(struct rfcomm_dev *dev)
332 list_del_init(&dev->list); 326 list_del_init(&dev->list);
333 spin_unlock(&rfcomm_dev_lock); 327 spin_unlock(&rfcomm_dev_lock);
334 328
335 rfcomm_dev_put(dev); 329 tty_port_put(&dev->port);
336} 330}
337 331
338/* ---- Send buffer ---- */ 332/* ---- Send buffer ---- */
@@ -349,12 +343,12 @@ static void rfcomm_wfree(struct sk_buff *skb)
349 atomic_sub(skb->truesize, &dev->wmem_alloc); 343 atomic_sub(skb->truesize, &dev->wmem_alloc);
350 if (test_bit(RFCOMM_TTY_ATTACHED, &dev->flags)) 344 if (test_bit(RFCOMM_TTY_ATTACHED, &dev->flags))
351 queue_work(system_nrt_wq, &dev->wakeup_task); 345 queue_work(system_nrt_wq, &dev->wakeup_task);
352 rfcomm_dev_put(dev); 346 tty_port_put(&dev->port);
353} 347}
354 348
355static inline void rfcomm_set_owner_w(struct sk_buff *skb, struct rfcomm_dev *dev) 349static inline void rfcomm_set_owner_w(struct sk_buff *skb, struct rfcomm_dev *dev)
356{ 350{
357 rfcomm_dev_hold(dev); 351 tty_port_get(&dev->port);
358 atomic_add(skb->truesize, &dev->wmem_alloc); 352 atomic_add(skb->truesize, &dev->wmem_alloc);
359 skb->sk = (void *) dev; 353 skb->sk = (void *) dev;
360 skb->destructor = rfcomm_wfree; 354 skb->destructor = rfcomm_wfree;
@@ -433,7 +427,7 @@ static int rfcomm_release_dev(void __user *arg)
433 return -ENODEV; 427 return -ENODEV;
434 428
435 if (dev->flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN)) { 429 if (dev->flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN)) {
436 rfcomm_dev_put(dev); 430 tty_port_put(&dev->port);
437 return -EPERM; 431 return -EPERM;
438 } 432 }
439 433
@@ -446,7 +440,7 @@ static int rfcomm_release_dev(void __user *arg)
446 440
447 if (!test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) 441 if (!test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags))
448 rfcomm_dev_del(dev); 442 rfcomm_dev_del(dev);
449 rfcomm_dev_put(dev); 443 tty_port_put(&dev->port);
450 return 0; 444 return 0;
451} 445}
452 446
@@ -524,7 +518,7 @@ static int rfcomm_get_dev_info(void __user *arg)
524 if (copy_to_user(arg, &di, sizeof(di))) 518 if (copy_to_user(arg, &di, sizeof(di)))
525 err = -EFAULT; 519 err = -EFAULT;
526 520
527 rfcomm_dev_put(dev); 521 tty_port_put(&dev->port);
528 return err; 522 return err;
529} 523}
530 524
@@ -592,7 +586,7 @@ static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err)
592 * 1. rfcomm_dev_get will take rfcomm_dev_lock 586 * 1. rfcomm_dev_get will take rfcomm_dev_lock
593 * but in rfcomm_dev_add there's lock order: 587 * but in rfcomm_dev_add there's lock order:
594 * rfcomm_dev_lock -> dlc lock 588 * rfcomm_dev_lock -> dlc lock
595 * 2. rfcomm_dev_put will deadlock if it's 589 * 2. tty_port_put will deadlock if it's
596 * the last reference 590 * the last reference
597 */ 591 */
598 rfcomm_dlc_unlock(dlc); 592 rfcomm_dlc_unlock(dlc);
@@ -602,7 +596,7 @@ static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err)
602 } 596 }
603 597
604 rfcomm_dev_del(dev); 598 rfcomm_dev_del(dev);
605 rfcomm_dev_put(dev); 599 tty_port_put(&dev->port);
606 rfcomm_dlc_lock(dlc); 600 rfcomm_dlc_lock(dlc);
607 } 601 }
608 } else 602 } else
@@ -771,11 +765,11 @@ static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp)
771 list_del_init(&dev->list); 765 list_del_init(&dev->list);
772 spin_unlock(&rfcomm_dev_lock); 766 spin_unlock(&rfcomm_dev_lock);
773 767
774 rfcomm_dev_put(dev); 768 tty_port_put(&dev->port);
775 } 769 }
776 } 770 }
777 771
778 rfcomm_dev_put(dev); 772 tty_port_put(&dev->port);
779} 773}
780 774
781static int rfcomm_tty_write(struct tty_struct *tty, const unsigned char *buf, int count) 775static int rfcomm_tty_write(struct tty_struct *tty, const unsigned char *buf, int count)
@@ -1084,7 +1078,7 @@ static void rfcomm_tty_hangup(struct tty_struct *tty)
1084 if (rfcomm_dev_get(dev->id) == NULL) 1078 if (rfcomm_dev_get(dev->id) == NULL)
1085 return; 1079 return;
1086 rfcomm_dev_del(dev); 1080 rfcomm_dev_del(dev);
1087 rfcomm_dev_put(dev); 1081 tty_port_put(&dev->port);
1088 } 1082 }
1089} 1083}
1090 1084