with skb queue we can run out of skbs. So, we should be able to drop the session and unlock pending sock without skbs. Signed-off-by: Oleksij Rempel <o.rempel@xxxxxxxxxxxxxx> --- net/can/j1939/j1939-priv.h | 1 + net/can/j1939/transport.c | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/net/can/j1939/j1939-priv.h b/net/can/j1939/j1939-priv.h index 9e62e63aafbb..df058d08fe68 100644 --- a/net/can/j1939/j1939-priv.h +++ b/net/can/j1939/j1939-priv.h @@ -189,6 +189,7 @@ struct j1939_session { struct list_head list; struct kref kref; spinlock_t lock; + struct sock *sk; /* ifindex, src, dst, pgn define the session block * the are _never_ modified after insertion in the list diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c index 20577f6b8934..20a0d7291435 100644 --- a/net/can/j1939/transport.c +++ b/net/can/j1939/transport.c @@ -684,13 +684,12 @@ static enum hrtimer_restart j1939_tp_txtimer(struct hrtimer *hrtimer) static void __j1939_session_drop(struct j1939_session *session) { struct j1939_priv *priv = session->priv; - struct sk_buff *se_skb = j1939_session_skb_find(session); - if (session->transmission) { - if (se_skb && se_skb->sk) - j1939_sock_pending_del(se_skb->sk); - wake_up_all(&priv->tp_wait); - } + if (!session->transmission) + return; + + j1939_sock_pending_del(session->sk); + wake_up_all(&priv->tp_wait); } static void j1939_session_completed(struct j1939_session *session) @@ -1275,6 +1274,7 @@ struct j1939_session *j1939_tp_send(struct j1939_priv *priv, return ERR_PTR(-ENOMEM); /* skb is recounted in j1939_session_new() */ + session->sk = skb->sk; session->extd = extd; session->transmission = true; session->pkt.total = (size + 6) / 7; -- 2.19.1