DORMANTno replies

[PATCH net-next] rxrpc: use timer_shutdown_sync() for cleanup operations

From: Yu Liao <hidden>
Date: 2023-08-21 01:14:21
Subsystem: networking [general], rxrpc sockets (af_rxrpc), the rest · Maintainers: "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, David Howells, Marc Dionne, Linus Torvalds

There was a race [1] between timer and rxrpc_exit_net() which was solved by
calling del_timer_sync() before and after cancel_work_sync(). A better
solution is to use timer_shutdown_sync() [2] to solve the circular
dependency problem. The correct ordering of calls in this case is:

  timer_shutdown_sync(&mything->timer);
  workqueue_destroy(&mything->workqueue);

After calling timer_shutdown_sync(), timer won't be rearmed from the
workqueue.

[1] https://lore.kernel.org/164984498582.2000115.4023190177137486137.stgit@warthog.procyon.org.uk (local)
[2] https://lore.kernel.org/r/20221123201625.314230270@linutronix.de (local)

Signed-off-by: Yu Liao <redacted>
---
 net/rxrpc/conn_object.c | 5 ++---
 net/rxrpc/net_ns.c      | 4 +---
 2 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/net/rxrpc/conn_object.c b/net/rxrpc/conn_object.c
index ac85d4644a3c..1afd677848af 100644
--- a/net/rxrpc/conn_object.c
+++ b/net/rxrpc/conn_object.c
@@ -317,9 +317,8 @@ static void rxrpc_clean_up_connection(struct work_struct *work)
 	       !conn->channels[3].call);
 	ASSERT(list_empty(&conn->cache_link));
 
-	del_timer_sync(&conn->timer);
-	cancel_work_sync(&conn->processor); /* Processing may restart the timer */
-	del_timer_sync(&conn->timer);
+	timer_shutdown_sync(&conn->timer);
+	cancel_work_sync(&conn->processor);
 
 	write_lock(&rxnet->conn_lock);
 	list_del_init(&conn->proc_link);
diff --git a/net/rxrpc/net_ns.c b/net/rxrpc/net_ns.c
index a0319c040c25..38cfbd2c7991 100644
--- a/net/rxrpc/net_ns.c
+++ b/net/rxrpc/net_ns.c
@@ -101,10 +101,8 @@ static __net_exit void rxrpc_exit_net(struct net *net)
 	struct rxrpc_net *rxnet = rxrpc_net(net);
 
 	rxnet->live = false;
-	del_timer_sync(&rxnet->peer_keepalive_timer);
+	timer_shutdown_sync(&rxnet->peer_keepalive_timer);
 	cancel_work_sync(&rxnet->peer_keepalive_work);
-	/* Remove the timer again as the worker may have restarted it. */
-	del_timer_sync(&rxnet->peer_keepalive_timer);
 	rxrpc_destroy_all_calls(rxnet);
 	rxrpc_destroy_all_connections(rxnet);
 	rxrpc_destroy_all_peers(rxnet);
-- 
2.25.1
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help