aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/sw/rxe/rxe_req.c
diff options
context:
space:
mode:
authorAndrew Boyer <andrew.boyer@dell.com>2016-12-05 08:43:21 -0500
committerDoug Ledford <dledford@redhat.com>2016-12-12 16:34:22 -0500
commit37f69f43fb5aba4288d38ea32bbe0dfdb412c763 (patch)
treee7d01aaa85ce347d6858ad09c3369b0580b2ccd2 /drivers/infiniband/sw/rxe/rxe_req.c
parentIB/rxe: Wait for tasklets to finish before tearing down QP (diff)
downloadlinux-dev-37f69f43fb5aba4288d38ea32bbe0dfdb412c763.tar.xz
linux-dev-37f69f43fb5aba4288d38ea32bbe0dfdb412c763.zip
IB/rxe: Hold refs when running tasklets
It might be possible for all of a QP's references to be dropped while one of that QP's tasklets is running. For example, the completer might run during QP destroy. If qp->valid is false, it will drop all of the packets on the resp_pkts list, potentially removing the last reference. Then it tries to advance the SQ consumer pointer. If the SQ's buffer has already been destroyed, the system will panic. To be safe, hold a reference on the QP for the duration of each tasklet. Signed-off-by: Andrew Boyer <andrew.boyer@dell.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
Diffstat (limited to 'drivers/infiniband/sw/rxe/rxe_req.c')
-rw-r--r--drivers/infiniband/sw/rxe/rxe_req.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/drivers/infiniband/sw/rxe/rxe_req.c b/drivers/infiniband/sw/rxe/rxe_req.c
index 205222909e53..b246653cf713 100644
--- a/drivers/infiniband/sw/rxe/rxe_req.c
+++ b/drivers/infiniband/sw/rxe/rxe_req.c
@@ -596,6 +596,8 @@ int rxe_requester(void *arg)
struct rxe_send_wqe rollback_wqe;
u32 rollback_psn;
+ rxe_add_ref(qp);
+
next_wqe:
if (unlikely(!qp->valid || qp->req.state == QP_STATE_ERROR))
goto exit;
@@ -750,9 +752,10 @@ complete:
while (rxe_completer(qp) == 0)
;
}
-
+ rxe_drop_ref(qp);
return 0;
exit:
+ rxe_drop_ref(qp);
return -EAGAIN;
}