--- x/net/l2tp/l2tp_core.c +++ y/net/l2tp/l2tp_core.c @@ -1298,8 +1298,10 @@ static void l2tp_tunnel_closeall(struct list_for_each_safe(pos, tmp, &tunnel->session_list) { session = list_entry(pos, struct l2tp_session, list); list_del_init(&session->list); + l2tp_session_inc_refcount(session); spin_unlock_bh(&tunnel->list_lock); l2tp_session_delete(session); + l2tp_session_dec_refcount(session); spin_lock_bh(&tunnel->list_lock); } spin_unlock_bh(&tunnel->list_lock); --- x/net/l2tp/l2tp_ppp.c +++ y/net/l2tp/l2tp_ppp.c @@ -393,14 +393,6 @@ abort: * Session (and tunnel control) socket create/destroy. *****************************************************************************/ -static void pppol2tp_put_sk(struct rcu_head *head) -{ - struct pppol2tp_session *ps; - - ps = container_of(head, typeof(*ps), rcu); - sock_put(ps->__sk); -} - /* Really kill the session socket. (Called from sock_put() if * refcnt == 0.) */ @@ -444,22 +436,8 @@ static int pppol2tp_release(struct socke session = pppol2tp_sock_to_session(sk); if (session) { - struct pppol2tp_session *ps; - l2tp_session_delete(session); - - ps = l2tp_session_priv(session); - mutex_lock(&ps->sk_lock); - ps->__sk = rcu_dereference_protected(ps->sk, - lockdep_is_held(&ps->sk_lock)); - RCU_INIT_POINTER(ps->sk, NULL); - mutex_unlock(&ps->sk_lock); - call_rcu(&ps->rcu, pppol2tp_put_sk); - - /* Rely on the sock_put() call at the end of the function for - * dropping the reference held by pppol2tp_sock_to_session(). - * The last reference will be dropped by pppol2tp_put_sk(). - */ + l2tp_session_dec_refcount(session); } release_sock(sk); @@ -831,6 +809,7 @@ static int pppol2tp_connect(struct socke out_no_ppp: /* This is how we get the session context from the socket. */ sk->sk_user_data = session; + l2tp_session_inc_refcount(session); rcu_assign_pointer(ps->sk, sk); mutex_unlock(&ps->sk_lock);