[PATCH net-next] rxrpc: use timer_shutdown_sync() for cleanup operations
Yu Liao
liaoyu15 at huawei.com
Sun Aug 20 18:10:41 PDT 2023
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
[2] https://lore.kernel.org/r/20221123201625.314230270@linutronix.de
Signed-off-by: Yu Liao <liaoyu15 at huawei.com>
---
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
More information about the linux-afs
mailing list