Since session destroy now uses a workqueue, let l2tp_session_delete
handle all the work of destroying a session. Don't remove the session
from the tunnel's list immediately. The tunnel will remain extant
until all of its sessions are gone anyway.

The session's dead flag is now unused so is removed.
---
 net/l2tp/l2tp_core.c | 32 ++++----------------------------
 net/l2tp/l2tp_core.h |  1 -
 2 files changed, 4 insertions(+), 29 deletions(-)

diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
index 55b1f312fedc..c909fe9273c9 100644
--- a/net/l2tp/l2tp_core.c
+++ b/net/l2tp/l2tp_core.c
@@ -1254,36 +1254,9 @@ void l2tp_tunnel_closeall(struct l2tp_tunnel *tunnel)
 
        write_lock_bh(&tunnel->hlist_lock);
        for (hash = 0; hash < L2TP_HASH_SIZE; hash++) {
-again:
                hlist_for_each_safe(walk, tmp, &tunnel->session_hlist[hash]) {
                        session = hlist_entry(walk, struct l2tp_session, hlist);
-
-                       l2tp_info(session, L2TP_MSG_CONTROL,
-                                 "%s: closing session\n", session->name);
-
-                       hlist_del_init(&session->hlist);
-
-                       if (test_and_set_bit(0, &session->dead))
-                               goto again;
-
-                       write_unlock_bh(&tunnel->hlist_lock);
-
-                       __l2tp_session_unhash(session);
-                       l2tp_session_queue_purge(session);
-
-                       if (session->session_close != NULL)
-                               (*session->session_close)(session);
-
-                       l2tp_session_dec_refcount(session);
-
-                       write_lock_bh(&tunnel->hlist_lock);
-
-                       /* Now restart from the beginning of this hash
-                        * chain.  We always remove a session from the
-                        * list so we are guaranteed to make forward
-                        * progress.
-                        */
-                       goto again;
+                       l2tp_session_delete(session);
                }
        }
        write_unlock_bh(&tunnel->hlist_lock);
@@ -1708,6 +1681,9 @@ static void l2tp_session_del_work(struct work_struct 
*work)
        struct l2tp_session *session = container_of(work, struct l2tp_session,
                                                    del_work);
 
+       l2tp_info(session, L2TP_MSG_CONTROL,
+                 "%s: closing session\n", session->name);
+
        __l2tp_session_unhash(session);
        l2tp_session_queue_purge(session);
        if (session->session_close)
diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h
index 8a11badb7104..73c4ce79c708 100644
--- a/net/l2tp/l2tp_core.h
+++ b/net/l2tp/l2tp_core.h
@@ -74,7 +74,6 @@ struct l2tp_session_cfg {
 struct l2tp_session {
        int                     magic;          /* should be
                                                 * L2TP_SESSION_MAGIC */
-       long                    dead;
        bool                    closing;
        spinlock_t              lock;           /* protect closing */
 
-- 
1.9.1

Reply via email to