int err;
 
        spin_lock_bh(&tunnel->list_lock);
+       spin_lock_bh(&pn->l2tp_session_idr_lock);
+
        if (!tunnel->acpt_newsess) {
                err = -ENODEV;
-               goto err_tlock;
+               goto out;
        }
 
        if (tunnel->version == L2TP_HDR_VER_3) {
                session_key = session->session_id;
-               spin_lock_bh(&pn->l2tp_session_idr_lock);
                err = idr_alloc_u32(&pn->l2tp_v3_session_idr, NULL,
                                    &session_key, session_key, GFP_ATOMIC);
                /* IP encap expects session IDs to be globally unique, while
                        err = l2tp_session_collision_add(pn, session,
                                                         other_session);
                }
-               spin_unlock_bh(&pn->l2tp_session_idr_lock);
        } else {
                session_key = l2tp_v2_session_key(tunnel->tunnel_id,
                                                  session->session_id);
-               spin_lock_bh(&pn->l2tp_session_idr_lock);
                err = idr_alloc_u32(&pn->l2tp_v2_session_idr, NULL,
                                    &session_key, session_key, GFP_ATOMIC);
-               spin_unlock_bh(&pn->l2tp_session_idr_lock);
        }
 
        if (err) {
                if (err == -ENOSPC)
                        err = -EEXIST;
-               goto err_tlock;
+               goto out;
        }
 
        l2tp_tunnel_inc_refcount(tunnel);
-
        list_add(&session->list, &tunnel->session_list);
-       spin_unlock_bh(&tunnel->list_lock);
 
-       spin_lock_bh(&pn->l2tp_session_idr_lock);
        if (tunnel->version == L2TP_HDR_VER_3) {
                if (!other_session)
                        idr_replace(&pn->l2tp_v3_session_idr, session, session_key);
        } else {
                idr_replace(&pn->l2tp_v2_session_idr, session, session_key);
        }
-       spin_unlock_bh(&pn->l2tp_session_idr_lock);
-
-       trace_register_session(session);
 
-       return 0;
-
-err_tlock:
+out:
+       spin_unlock_bh(&pn->l2tp_session_idr_lock);
        spin_unlock_bh(&tunnel->list_lock);
 
+       if (!err)
+               trace_register_session(session);
+
        return err;
 }
 EXPORT_SYMBOL_GPL(l2tp_session_register);
                struct l2tp_net *pn = l2tp_pernet(tunnel->l2tp_net);
                struct l2tp_session *removed = session;
 
-               /* Remove from the per-tunnel list */
                spin_lock_bh(&tunnel->list_lock);
+               spin_lock_bh(&pn->l2tp_session_idr_lock);
+
+               /* Remove from the per-tunnel list */
                list_del_init(&session->list);
-               spin_unlock_bh(&tunnel->list_lock);
 
                /* Remove from per-net IDR */
-               spin_lock_bh(&pn->l2tp_session_idr_lock);
                if (tunnel->version == L2TP_HDR_VER_3) {
                        if (hash_hashed(&session->hlist))
                                l2tp_session_collision_del(pn, session);
                                             session_key);
                }
                WARN_ON_ONCE(removed && removed != session);
+
                spin_unlock_bh(&pn->l2tp_session_idr_lock);
+               spin_unlock_bh(&tunnel->list_lock);
 
                synchronize_rcu();
        }