| From 9c16827976a9392bcbcdd81270f92cb1465a0863 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Mon, 20 Sep 2021 21:18:15 +0200 |
| Subject: net/smc: fix 'workqueue leaked lock' in smc_conn_abort_work |
| |
| From: Karsten Graul <kgraul@linux.ibm.com> |
| |
| [ Upstream commit a18cee4791b1123d0a6579a7c89f4b87e48abe03 ] |
| |
| The abort_work is scheduled when a connection was detected to be |
| out-of-sync after a link failure. The work calls smc_conn_kill(), |
| which calls smc_close_active_abort() and that might end up calling |
| smc_close_cancel_work(). |
| smc_close_cancel_work() cancels any pending close_work and tx_work but |
| needs to release the sock_lock before and acquires the sock_lock again |
| afterwards. So when the sock_lock was NOT acquired before then it may |
| be held after the abort_work completes. Thats why the sock_lock is |
| acquired before the call to smc_conn_kill() in __smc_lgr_terminate(), |
| but this is missing in smc_conn_abort_work(). |
| |
| Fix that by acquiring the sock_lock first and release it after the |
| call to smc_conn_kill(). |
| |
| Fixes: b286a0651e44 ("net/smc: handle incoming CDC validation message") |
| Signed-off-by: Karsten Graul <kgraul@linux.ibm.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| net/smc/smc_core.c | 2 ++ |
| 1 file changed, 2 insertions(+) |
| |
| diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c |
| index c160ff50c053..116cfd6fac1f 100644 |
| --- a/net/smc/smc_core.c |
| +++ b/net/smc/smc_core.c |
| @@ -1474,7 +1474,9 @@ static void smc_conn_abort_work(struct work_struct *work) |
| abort_work); |
| struct smc_sock *smc = container_of(conn, struct smc_sock, conn); |
| |
| + lock_sock(&smc->sk); |
| smc_conn_kill(conn, true); |
| + release_sock(&smc->sk); |
| sock_put(&smc->sk); /* sock_hold done by schedulers of abort_work */ |
| } |
| |
| -- |
| 2.33.0 |
| |