Bluetooth: Use kref for l2cap channel reference counting
authorSyam Sidhardhan <s.syam@samsung.com>
Fri, 27 Jul 2012 18:21:21 +0000 (23:51 +0530)
committerGustavo Padovan <gustavo.padovan@collabora.co.uk>
Tue, 21 Aug 2012 17:54:41 +0000 (14:54 -0300)
This patch changes the struct l2cap_chan and associated code to use
kref api for object refcounting and freeing.

Suggested-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Signed-off-by: Jaganath Kanakkassery <jaganath.k@samsung.com>
Signed-off-by: Syam Sidhardhan <s.syam@samsung.com>
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
include/net/bluetooth/l2cap.h
net/bluetooth/l2cap_core.c

index d206296137e2b4fb50aa49bcee18dae9f0d687fb..7ed8e356425a16dc33c5afd5e4a80eaafdd6ea64 100644 (file)
@@ -433,11 +433,10 @@ struct l2cap_chan {
        struct sock *sk;
 
        struct l2cap_conn       *conn;
+       struct kref     kref;
 
        __u8            state;
 
-       atomic_t        refcnt;
-
        __le16          psm;
        __u16           dcid;
        __u16           scid;
index dae895e3ca75961d3f8a744c8af0012eaf711ae9..9732f03cfbef7701786c2edee23d06be3eeab8c7 100644 (file)
@@ -406,7 +406,7 @@ struct l2cap_chan *l2cap_chan_create(void)
 
        chan->state = BT_OPEN;
 
-       atomic_set(&chan->refcnt, 1);
+       kref_init(&chan->kref);
 
        /* This flag is cleared in l2cap_chan_ready() */
        set_bit(CONF_NOT_COMPLETE, &chan->conf_state);
@@ -416,8 +416,10 @@ struct l2cap_chan *l2cap_chan_create(void)
        return chan;
 }
 
-static void l2cap_chan_destroy(struct l2cap_chan *chan)
+static void l2cap_chan_destroy(struct kref *kref)
 {
+       struct l2cap_chan *chan = container_of(kref, struct l2cap_chan, kref);
+
        BT_DBG("chan %p", chan);
 
        write_lock(&chan_list_lock);
@@ -429,17 +431,16 @@ static void l2cap_chan_destroy(struct l2cap_chan *chan)
 
 void l2cap_chan_hold(struct l2cap_chan *c)
 {
-       BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->refcnt));
+       BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
 
-       atomic_inc(&c->refcnt);
+       kref_get(&c->kref);
 }
 
 void l2cap_chan_put(struct l2cap_chan *c)
 {
-       BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->refcnt));
+       BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
 
-       if (atomic_dec_and_test(&c->refcnt))
-               l2cap_chan_destroy(c);
+       kref_put(&c->kref, l2cap_chan_destroy);
 }
 
 void l2cap_chan_set_defaults(struct l2cap_chan *chan)