summaryrefslogtreecommitdiff
path: root/net/smc
diff options
context:
space:
mode:
authorWen Gu <guwen@linux.alibaba.com>2022-03-28 14:10:36 +0800
committerJakub Kicinski <kuba@kernel.org>2022-03-28 16:06:27 -0700
commit906b3d64913c19a50d5c553f21b54d2f4ce3ded7 (patch)
tree53da8d611a711b8a37b1a4c5f827264ba0c05bdb /net/smc
parentf32404ae1bb9a7428a3c77419672a28895d185bf (diff)
net/smc: Send out the remaining data in sndbuf before close
The current autocork algorithms will delay the data transmission in BH context to smc_release_cb() when sock_lock is hold by user. So there is a possibility that when connection is being actively closed (sock_lock is hold by user now), some corked data still remains in sndbuf, waiting to be sent by smc_release_cb(). This will cause: - smc_close_stream_wait(), which is called under the sock_lock, has a high probability of timeout because data transmission is delayed until sock_lock is released. - Unexpected data sends may happen after connction closed and use the rtoken which has been deleted by remote peer through LLC_DELETE_RKEY messages. So this patch will try to send out the remaining corked data in sndbuf before active close process, to ensure data integrity and avoid unexpected data transmission after close. Reported-by: Guangguan Wang <guangguan.wang@linux.alibaba.com> Fixes: 6b88af839d20 ("net/smc: don't send in the BH context if sock_owned_by_user") Signed-off-by: Wen Gu <guwen@linux.alibaba.com> Acked-by: Karsten Graul <kgraul@linux.ibm.com> Link: https://lore.kernel.org/r/1648447836-111521-1-git-send-email-guwen@linux.alibaba.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net/smc')
-rw-r--r--net/smc/smc_close.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/net/smc/smc_close.c b/net/smc/smc_close.c
index 292e4d904ab6..676cb2333d3c 100644
--- a/net/smc/smc_close.c
+++ b/net/smc/smc_close.c
@@ -57,6 +57,9 @@ static void smc_close_stream_wait(struct smc_sock *smc, long timeout)
if (!smc_tx_prepared_sends(&smc->conn))
return;
+ /* Send out corked data remaining in sndbuf */
+ smc_tx_pending(&smc->conn);
+
smc->wait_close_tx_prepared = 1;
add_wait_queue(sk_sleep(sk), &wait);
while (!signal_pending(current) && timeout) {