Patch "tipc: fix nametbl_lock soft lockup at module exit" has been added to the 4.9-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
tipc: fix nametbl_lock soft lockup at module exit
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
tipc-fix-nametbl_lock-soft-lockup-at-module-exit.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From foo@baz Wed Dec 6 17:39:55 CET 2017
From: Parthasarathy Bhuvaragan <[email protected]>
Date: Tue, 24 Jan 2017 13:00:46 +0100
Subject: tipc: fix nametbl_lock soft lockup at module exit
From: Parthasarathy Bhuvaragan <[email protected]>
[ Upstream commit 9dc3abdd1f7ea524e8552e0a3ef01219892ed1f4 ]
Commit 333f796235a527 ("tipc: fix a race condition leading to subscriber refcnt bug") reveals a soft lockup while acquiring nametbl_lock.
Before commit 333f796235a527, we call tipc_conn_shutdown() from tipc_close_conn() in the context of tipc_topsrv_stop(). In that context, we are allowed to grab the nametbl_lock.
Commit 333f796235a527, moved tipc_conn_release (renamed from tipc_conn_shutdown) to the connection refcount cleanup. This allows either tipc_nametbl_withdraw() or tipc_topsrv_stop() to the cleanup.
Since tipc_exit_net() first calls tipc_topsrv_stop() and then tipc_nametble_withdraw() increases the chances for the later to perform the connection cleanup.
The soft lockup occurs in the call chain of tipc_nametbl_withdraw(), when it performs the tipc_conn_kref_release() as it tries to grab nametbl_lock again while holding it already. tipc_nametbl_withdraw() grabs nametbl_lock
tipc_nametbl_remove_publ()
tipc_subscrp_report_overlap()
tipc_subscrp_send_event()
tipc_conn_sendmsg()
<< if (con->flags != CF_CONNECTED) we do conn_put(),
triggering the cleanup as refcount=0. >>
tipc_conn_kref_release
tipc_sock_release
tipc_conn_release
tipc_subscrb_delete
tipc_subscrp_delete
tipc_nametbl_unsubscribe << Soft Lockup >>
The previous changes in this series fixes the race conditions fixed by commit 333f796235a527. Hence we can now revert the commit.
--- net/tipc/server.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-)
net/tipc/server.c +5 -11
@@ -86,7 +86,6 @@ struct outqueue_entry {static void tipc_recv_work (struct work_struct *work);static void tipc_send_work (struct work_struct *work);static void tipc_clean_outqueues (struct tipc_conn *con); -static void tipc_sock_release (struct tipc_conn *con);static void tipc_conn_kref_release (struct kref *kref) {
@@ -104,7 +103,6 @@ static void tipc_conn_kref_release(struc } saddr->scope = -TIPC_NODE_SCOPE ;kernel_bind (sock, (struct sockaddr *)saddr,sizeof (*saddr)); -tipc_sock_release (con);sock_release (sock); con->sock =NULL ;
@@ -194,19 +192,15 @@ static void tipc_unregister_callbacks(stwrite_unlock_bh (&sk->sk_callback_lock); } -static void tipc_sock_release (struct tipc_conn *con) +static void tipc_close_conn (struct tipc_conn *con) {struct tipc_server *s = con->server; -if (con->conid) - s->tipc_conn_release (con->conid, con->usr_data); - -tipc_unregister_callbacks (con); -} - -static void tipc_close_conn (struct tipc_conn *con) -{if (test_and_clear_bit (CF_CONNECTED , &con->flags)) { +tipc_unregister_callbacks (con); + +if (con->conid) + s->tipc_conn_release (con->conid, con->usr_data);/* We shouldn't flush pending works as we may be in the * thread. In fact the races with pending rx/tx work structs
Patches currently in stable-queue which might be from [email protected] are
queue-4.9/tipc-fix-nametbl_lock-soft-lockup-at-module-exit.patch queue-4.9/tipc-fix-cleanup-at-module-unload.patch