]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.19.34/iw_cxgb4-fix-srqidx-leak-during-connection-abort.patch
Linux 4.19.34
[thirdparty/kernel/stable-queue.git] / releases / 4.19.34 / iw_cxgb4-fix-srqidx-leak-during-connection-abort.patch
1 From d6d57b2eff6aec8ef25a2b61c5216ad63a69f70e Mon Sep 17 00:00:00 2001
2 From: Raju Rangoju <rajur@chelsio.com>
3 Date: Wed, 6 Feb 2019 22:54:44 +0530
4 Subject: iw_cxgb4: fix srqidx leak during connection abort
5
6 [ Upstream commit f368ff188ae4b3ef6f740a15999ea0373261b619 ]
7
8 When an application aborts the connection by moving QP from RTS to ERROR,
9 then iw_cxgb4's modify_rc_qp() RTS->ERROR logic sets the
10 *srqidxp to 0 via t4_set_wq_in_error(&qhp->wq, 0), and aborts the
11 connection by calling c4iw_ep_disconnect().
12
13 c4iw_ep_disconnect() does the following:
14 1. sends up a close_complete_upcall(ep, -ECONNRESET) to libcxgb4.
15 2. sends abort request CPL to hw.
16
17 But, since the close_complete_upcall() is sent before sending the
18 ABORT_REQ to hw, libcxgb4 would fail to release the srqidx if the
19 connection holds one. Because, the srqidx is passed up to libcxgb4 only
20 after corresponding ABORT_RPL is processed by kernel in abort_rpl().
21
22 This patch handle the corner-case by moving the call to
23 close_complete_upcall() from c4iw_ep_disconnect() to abort_rpl(). So that
24 libcxgb4 is notified about the -ECONNRESET only after abort_rpl(), and
25 libcxgb4 can relinquish the srqidx properly.
26
27 Signed-off-by: Raju Rangoju <rajur@chelsio.com>
28 Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
29 Signed-off-by: Sasha Levin <sashal@kernel.org>
30 ---
31 drivers/infiniband/hw/cxgb4/cm.c | 5 +++--
32 1 file changed, 3 insertions(+), 2 deletions(-)
33
34 diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c
35 index 0f83cbec33f3..a68569ec86bf 100644
36 --- a/drivers/infiniband/hw/cxgb4/cm.c
37 +++ b/drivers/infiniband/hw/cxgb4/cm.c
38 @@ -1904,8 +1904,10 @@ static int abort_rpl(struct c4iw_dev *dev, struct sk_buff *skb)
39 }
40 mutex_unlock(&ep->com.mutex);
41
42 - if (release)
43 + if (release) {
44 + close_complete_upcall(ep, -ECONNRESET);
45 release_ep_resources(ep);
46 + }
47 c4iw_put_ep(&ep->com);
48 return 0;
49 }
50 @@ -3608,7 +3610,6 @@ int c4iw_ep_disconnect(struct c4iw_ep *ep, int abrupt, gfp_t gfp)
51 if (close) {
52 if (abrupt) {
53 set_bit(EP_DISC_ABORT, &ep->com.history);
54 - close_complete_upcall(ep, -ECONNRESET);
55 ret = send_abort(ep);
56 } else {
57 set_bit(EP_DISC_CLOSE, &ep->com.history);
58 --
59 2.19.1
60