--- y/net/bluetooth/l2cap_core.c +++ x/net/bluetooth/l2cap_core.c @@ -458,10 +458,6 @@ struct l2cap_chan *l2cap_chan_create(voi /* Set default lock nesting level */ atomic_set(&chan->nesting, L2CAP_NESTING_NORMAL); - write_lock(&chan_list_lock); - list_add(&chan->global_l, &chan_list); - write_unlock(&chan_list_lock); - INIT_DELAYED_WORK(&chan->chan_timer, l2cap_chan_timeout); chan->state = BT_OPEN; @@ -473,6 +469,10 @@ struct l2cap_chan *l2cap_chan_create(voi BT_DBG("chan %p", chan); + write_lock(&chan_list_lock); + list_add(&chan->global_l, &chan_list); + write_unlock(&chan_list_lock); + return chan; } EXPORT_SYMBOL_GPL(l2cap_chan_create); @@ -497,6 +497,14 @@ void l2cap_chan_hold(struct l2cap_chan * kref_get(&c->kref); } +static struct l2cap_chan *l2cap_chan_hold_not_zero(struct l2cap_chan *c) +{ + if (kref_get_unless_zero(&c->kref)) + return c; + else + return NULL; +} + void l2cap_chan_put(struct l2cap_chan *c) { BT_DBG("chan %p orig refcnt %u", c, kref_read(&c->kref)); @@ -1983,7 +1991,7 @@ static struct l2cap_chan *l2cap_global_c } if (c1) - l2cap_chan_hold(c1); + c1 = l2cap_chan_hold_not_zero(c1); read_unlock(&chan_list_lock);