--- x/net/can/j1939/transport.c +++ y/net/can/j1939/transport.c @@ -336,8 +336,6 @@ static void j1939_session_skb_drop_old(s __skb_unlink(do_skb, &session->skb_queue); /* drop ref taken in j1939_session_skb_queue() */ skb_unref(do_skb); - - kfree_skb(do_skb); } spin_unlock_irqrestore(&session->skb_queue.lock, flags); } @@ -1081,14 +1079,19 @@ static bool j1939_session_deactivate_loc static bool j1939_session_deactivate(struct j1939_session *session) { struct j1939_priv *priv = session->priv; - bool active; + bool active = false; j1939_session_list_lock(priv); + if (list_empty(&session->active_session_list_entry)) { + /* J1939_SESSION_DONE already */ + goto out; + } /* This function should be called with a session ref-count of at * least 2. */ WARN_ON_ONCE(kref_read(&session->kref) < 2); active = j1939_session_deactivate_locked(session); +out: j1939_session_list_unlock(priv); return active;