[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20230821011041.3186528-1-liaoyu15@huawei.com>
Date: Mon, 21 Aug 2023 09:10:41 +0800
From: Yu Liao <liaoyu15@...wei.com>
To: <dhowells@...hat.com>, <marc.dionne@...istor.com>, <davem@...emloft.net>,
<edumazet@...gle.com>, <kuba@...nel.org>, <pabeni@...hat.com>
CC: <liaoyu15@...wei.com>, <linux-afs@...ts.infradead.org>,
<netdev@...r.kernel.org>, <liwei391@...wei.com>
Subject: [PATCH net-next] rxrpc: use timer_shutdown_sync() for cleanup operations
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@...wei.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
Powered by blists - more mailing lists