diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index e0a1f2293679..41029163eb7d 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -825,6 +825,10 @@ void l2cap_chan_hold(struct l2cap_chan *c); struct l2cap_chan *l2cap_chan_hold_unless_zero(struct l2cap_chan *c); void l2cap_chan_put(struct l2cap_chan *c); +struct l2cap_conn *l2cap_conn_get(struct l2cap_conn *conn); +struct l2cap_conn *l2cap_conn_hold_unless_zero(struct l2cap_conn *conn); +void l2cap_conn_put(struct l2cap_conn *conn); + static inline void l2cap_chan_lock(struct l2cap_chan *chan) { mutex_lock_nested(&chan->lock, atomic_read(&chan->nesting)); @@ -843,8 +847,11 @@ static inline void l2cap_set_timer(struct l2cap_chan *chan, /* If delayed work cancelled do not hold(chan) since it is already done with previous set_timer */ - if (!cancel_delayed_work(work)) + if (!cancel_delayed_work(work)) { l2cap_chan_hold(chan); + if (chan->conn) + l2cap_conn_get(chan->conn); + } schedule_delayed_work(work, timeout); } @@ -857,9 +864,13 @@ static inline bool l2cap_clear_timer(struct l2cap_chan *chan, /* put(chan) if delayed work cancelled otherwise it is done in delayed work function */ ret = cancel_delayed_work(work); - if (ret) - l2cap_chan_put(chan); + if (ret) { + struct l2cap_conn *conn = chan->conn; + l2cap_chan_put(chan); + if (conn) + l2cap_conn_put(conn); + } return ret; } @@ -973,10 +984,6 @@ void l2cap_chan_list(struct l2cap_conn *conn, l2cap_chan_func_t func, void l2cap_chan_del(struct l2cap_chan *chan, int err); void l2cap_send_conn_req(struct l2cap_chan *chan); -struct l2cap_conn *l2cap_conn_get(struct l2cap_conn *conn); -struct l2cap_conn *l2cap_conn_hold_unless_zero(struct l2cap_conn *conn); -void l2cap_conn_put(struct l2cap_conn *conn); - int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user); void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user); diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index c4ccfbda9d78..8cf1727a0617 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -438,6 +438,8 @@ static void l2cap_chan_timeout(struct work_struct *work) l2cap_chan_put(chan); mutex_unlock(&conn->lock); + + l2cap_conn_put(conn); } struct l2cap_chan *l2cap_chan_create(void)