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.

Signed-off-by: James Chapman <jchap...@katalix.com>
---
 net/l2tp/l2tp_core.c | 32 ++++----------------------------
 1 file changed, 4 insertions(+), 28 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)
-- 
1.9.1

Reply via email to