aboutsummaryrefslogtreecommitdiffstats
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
parent07bf9627d5f1c0334fc543a5435a31a3b5907944 (diff)
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>
-rw-r--r--drivers/infiniband/sw/rxe/rxe_comp.c4
-rw-r--r--drivers/infiniband/sw/rxe/rxe_req.c5
-rw-r--r--drivers/infiniband/sw/rxe/rxe_resp.c3
3 files changed, 11 insertions, 1 deletions
diff --git a/drivers/infiniband/sw/rxe/rxe_comp.c b/drivers/infiniband/sw/rxe/rxe_comp.c
index d46c49b33b13..cd27cbde7652 100644
--- a/drivers/infiniband/sw/rxe/rxe_comp.c
+++ b/drivers/infiniband/sw/rxe/rxe_comp.c
@@ -511,6 +511,8 @@ int rxe_completer(void *arg)
511 struct rxe_pkt_info *pkt = NULL; 511 struct rxe_pkt_info *pkt = NULL;
512 enum comp_state state; 512 enum comp_state state;
513 513
514 rxe_add_ref(qp);
515
514 if (!qp->valid) { 516 if (!qp->valid) {
515 while ((skb = skb_dequeue(&qp->resp_pkts))) { 517 while ((skb = skb_dequeue(&qp->resp_pkts))) {
516 rxe_drop_ref(qp); 518 rxe_drop_ref(qp);
@@ -740,11 +742,13 @@ exit:
740 /* we come here if we are done with processing and want the task to 742 /* we come here if we are done with processing and want the task to
741 * exit from the loop calling us 743 * exit from the loop calling us
742 */ 744 */
745 rxe_drop_ref(qp);
743 return -EAGAIN; 746 return -EAGAIN;
744 747
745done: 748done:
746 /* we come here if we have processed a packet we want the task to call 749 /* we come here if we have processed a packet we want the task to call
747 * us again to see if there is anything else to do 750 * us again to see if there is anything else to do
748 */ 751 */
752 rxe_drop_ref(qp);
749 return 0; 753 return 0;
750} 754}
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)
596 struct rxe_send_wqe rollback_wqe; 596 struct rxe_send_wqe rollback_wqe;
597 u32 rollback_psn; 597 u32 rollback_psn;
598 598
599 rxe_add_ref(qp);
600
599next_wqe: 601next_wqe:
600 if (unlikely(!qp->valid || qp->req.state == QP_STATE_ERROR)) 602 if (unlikely(!qp->valid || qp->req.state == QP_STATE_ERROR))
601 goto exit; 603 goto exit;
@@ -750,9 +752,10 @@ complete:
750 while (rxe_completer(qp) == 0) 752 while (rxe_completer(qp) == 0)
751 ; 753 ;
752 } 754 }
753 755 rxe_drop_ref(qp);
754 return 0; 756 return 0;
755 757
756exit: 758exit:
759 rxe_drop_ref(qp);
757 return -EAGAIN; 760 return -EAGAIN;
758} 761}
diff --git a/drivers/infiniband/sw/rxe/rxe_resp.c b/drivers/infiniband/sw/rxe/rxe_resp.c
index 8643797fb530..7a36ec9dbc0c 100644
--- a/drivers/infiniband/sw/rxe/rxe_resp.c
+++ b/drivers/infiniband/sw/rxe/rxe_resp.c
@@ -1212,6 +1212,8 @@ int rxe_responder(void *arg)
1212 struct rxe_pkt_info *pkt = NULL; 1212 struct rxe_pkt_info *pkt = NULL;
1213 int ret = 0; 1213 int ret = 0;
1214 1214
1215 rxe_add_ref(qp);
1216
1215 qp->resp.aeth_syndrome = AETH_ACK_UNLIMITED; 1217 qp->resp.aeth_syndrome = AETH_ACK_UNLIMITED;
1216 1218
1217 if (!qp->valid) { 1219 if (!qp->valid) {
@@ -1400,5 +1402,6 @@ int rxe_responder(void *arg)
1400exit: 1402exit:
1401 ret = -EAGAIN; 1403 ret = -EAGAIN;
1402done: 1404done:
1405 rxe_drop_ref(qp);
1403 return ret; 1406 return ret;
1404} 1407}