Skip to content

Commit

Permalink
IB/rxe: Hold refs when running tasklets
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Andrew Boyer authored and Doug Ledford committed Dec 12, 2016
1 parent 07bf962 commit 37f69f4
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 1 deletion.
4 changes: 4 additions & 0 deletions drivers/infiniband/sw/rxe/rxe_comp.c
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,8 @@ int rxe_completer(void *arg)
struct rxe_pkt_info *pkt = NULL;
enum comp_state state;

rxe_add_ref(qp);

if (!qp->valid) {
while ((skb = skb_dequeue(&qp->resp_pkts))) {
rxe_drop_ref(qp);
Expand Down Expand Up @@ -740,11 +742,13 @@ int rxe_completer(void *arg)
/* we come here if we are done with processing and want the task to
* exit from the loop calling us
*/
rxe_drop_ref(qp);
return -EAGAIN;

done:
/* we come here if we have processed a packet we want the task to call
* us again to see if there is anything else to do
*/
rxe_drop_ref(qp);
return 0;
}
5 changes: 4 additions & 1 deletion drivers/infiniband/sw/rxe/rxe_req.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -750,9 +752,10 @@ int rxe_requester(void *arg)
while (rxe_completer(qp) == 0)
;
}

rxe_drop_ref(qp);
return 0;

exit:
rxe_drop_ref(qp);
return -EAGAIN;
}
3 changes: 3 additions & 0 deletions drivers/infiniband/sw/rxe/rxe_resp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1212,6 +1212,8 @@ int rxe_responder(void *arg)
struct rxe_pkt_info *pkt = NULL;
int ret = 0;

rxe_add_ref(qp);

qp->resp.aeth_syndrome = AETH_ACK_UNLIMITED;

if (!qp->valid) {
Expand Down Expand Up @@ -1400,5 +1402,6 @@ int rxe_responder(void *arg)
exit:
ret = -EAGAIN;
done:
rxe_drop_ref(qp);
return ret;
}

0 comments on commit 37f69f4

Please sign in to comment.