diff --git a/net/handshake/netlink.c b/net/handshake/netlink.c index 80c7302692c74cb52d429392cd57ae283a91f4f0..2ce4e2a07fe463a2499d1e21f30d64da84039ab5 100644 --- a/net/handshake/netlink.c +++ b/net/handshake/netlink.c @@ -205,7 +205,7 @@ static void __net_exit handshake_net_exit(struct net *net) */ spin_lock(&hn->hn_lock); set_bit(HANDSHAKE_F_NET_DRAINING, &hn->hn_flags); - list_splice_init(&requests, &hn->hn_requests); + list_splice_init(&hn->hn_requests, &requests); spin_unlock(&hn->hn_lock); while (!list_empty(&requests)) { diff --git a/net/handshake/request.c b/net/handshake/request.c index 5df102534a596f925e7c4e7aec0c0c9e6a385de3..45685c3c4afe16712f845709d20f9165ee901881 100644 --- a/net/handshake/request.c +++ b/net/handshake/request.c @@ -163,13 +163,16 @@ static void __remove_pending_locked(struct handshake_net *hn, * otherwise %false. * * If @req was on a pending list, it has not yet been accepted. + * Returns %false when the net namespace is draining; the drain + * loop has taken ownership of the pending list. */ static bool remove_pending(struct handshake_net *hn, struct handshake_req *req) { bool ret = false; spin_lock(&hn->hn_lock); - if (!list_empty(&req->hr_list)) { + if (!test_bit(HANDSHAKE_F_NET_DRAINING, &hn->hn_flags) && + !list_empty(&req->hr_list)) { __remove_pending_locked(hn, req); ret = true; }