--- x/net/l2tp/l2tp_core.c +++ y/net/l2tp/l2tp_core.c @@ -1189,6 +1189,7 @@ static void l2tp_session_unhash(struct l } } +static void __l2tp_session_delete(struct l2tp_session *); /* When the tunnel is closed, all the attached sessions need to go too. */ static void l2tp_tunnel_closeall(struct l2tp_tunnel *tunnel) @@ -1201,10 +1202,12 @@ static void l2tp_tunnel_closeall(struct for (hash = 0; hash < L2TP_HASH_SIZE; hash++) { again: hlist_for_each_entry_rcu(session, &tunnel->session_hlist[hash], hlist) { + if (test_and_set_bit(0, &session->dead)) + continue; hlist_del_init_rcu(&session->hlist); spin_unlock_bh(&tunnel->hlist_lock); - l2tp_session_delete(session); + __l2tp_session_delete(session); spin_lock_bh(&tunnel->hlist_lock); /* Now restart from the beginning of this hash @@ -1550,11 +1553,8 @@ void l2tp_tunnel_delete(struct l2tp_tunn } EXPORT_SYMBOL_GPL(l2tp_tunnel_delete); -void l2tp_session_delete(struct l2tp_session *session) +static void __l2tp_session_delete(struct l2tp_session *session) { - if (test_and_set_bit(0, &session->dead)) - return; - trace_delete_session(session); l2tp_session_unhash(session); l2tp_session_queue_purge(session); @@ -1563,6 +1563,13 @@ void l2tp_session_delete(struct l2tp_ses l2tp_session_dec_refcount(session); } + +void l2tp_session_delete(struct l2tp_session *session) +{ + if (test_and_set_bit(0, &session->dead)) + return; + __l2tp_session_delete(session); +} EXPORT_SYMBOL_GPL(l2tp_session_delete); /* We come here whenever a session's send_seq, cookie_len or