aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@googlemail.com>2011-11-19 07:23:33 -0500
committerGustavo F. Padovan <padovan@profusion.mobi>2011-11-21 11:29:25 -0500
commit9b338c3dd12918f7f7df2b882f63f71e9efbcb41 (patch)
tree21c1476a90ad3214a2ffc6cdfbc94941e64bf427 /net
parent48b28b8db9a74cc5c43e76485dc397e22bea2984 (diff)
Bluetooth: bnep: Fix module reference
We cannot call module_put(THIS_MODULE) if this is our last reference. Otherwise, this call may cleanup our module before it returns. Gladly, the kthread API provides a simple wrapper for us. So lets use module_put_and_exit() to avoid a race condition with the module cleanup code. Signed-off-by: David Herrmann <dh.herrmann@googlemail.com> Acked-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/bnep/core.c8
1 files changed, 3 insertions, 5 deletions
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c
index 91bcd3a961ec..1eea8208b2cc 100644
--- a/net/bluetooth/bnep/core.c
+++ b/net/bluetooth/bnep/core.c
@@ -79,17 +79,12 @@ static struct bnep_session *__bnep_get_session(u8 *dst)
79 79
80static void __bnep_link_session(struct bnep_session *s) 80static void __bnep_link_session(struct bnep_session *s)
81{ 81{
82 /* It's safe to call __module_get() here because sessions are added
83 by the socket layer which has to hold the reference to this module.
84 */
85 __module_get(THIS_MODULE);
86 list_add(&s->list, &bnep_session_list); 82 list_add(&s->list, &bnep_session_list);
87} 83}
88 84
89static void __bnep_unlink_session(struct bnep_session *s) 85static void __bnep_unlink_session(struct bnep_session *s)
90{ 86{
91 list_del(&s->list); 87 list_del(&s->list);
92 module_put(THIS_MODULE);
93} 88}
94 89
95static int bnep_send(struct bnep_session *s, void *data, size_t len) 90static int bnep_send(struct bnep_session *s, void *data, size_t len)
@@ -530,6 +525,7 @@ static int bnep_session(void *arg)
530 525
531 up_write(&bnep_session_sem); 526 up_write(&bnep_session_sem);
532 free_netdev(dev); 527 free_netdev(dev);
528 module_put_and_exit(0);
533 return 0; 529 return 0;
534} 530}
535 531
@@ -616,9 +612,11 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
616 612
617 __bnep_link_session(s); 613 __bnep_link_session(s);
618 614
615 __module_get(THIS_MODULE);
619 s->task = kthread_run(bnep_session, s, "kbnepd %s", dev->name); 616 s->task = kthread_run(bnep_session, s, "kbnepd %s", dev->name);
620 if (IS_ERR(s->task)) { 617 if (IS_ERR(s->task)) {
621 /* Session thread start failed, gotta cleanup. */ 618 /* Session thread start failed, gotta cleanup. */
619 module_put(THIS_MODULE);
622 unregister_netdev(dev); 620 unregister_netdev(dev);
623 __bnep_unlink_session(s); 621 __bnep_unlink_session(s);
624 err = PTR_ERR(s->task); 622 err = PTR_ERR(s->task);