This is a note to let you know that I've just added the patch titled
RDMA/rxe: Fix a race condition in rxe_requester()
to the 4.15-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git%3Ba=su...
The filename of the patch is: rdma-rxe-fix-a-race-condition-in-rxe_requester.patch and it can be found in the queue-4.15 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let stable@vger.kernel.org know about it.
From 65567e41219888feec72fee1de98ccf1efbbc16d Mon Sep 17 00:00:00 2001
From: Bart Van Assche bart.vanassche@wdc.com Date: Fri, 12 Jan 2018 15:11:58 -0800 Subject: RDMA/rxe: Fix a race condition in rxe_requester()
From: Bart Van Assche bart.vanassche@wdc.com
commit 65567e41219888feec72fee1de98ccf1efbbc16d upstream.
The rxe driver works as follows: * The send queue, receive queue and completion queues are implemented as circular buffers. * ib_post_send() and ib_post_recv() calls are serialized through a spinlock. * Removing elements from various queues happens from tasklet context. Tasklets are guaranteed to run on at most one CPU. This serializes access to these queues. See also rxe_completer(), rxe_requester() and rxe_responder(). * rxe_completer() processes the skbs queued onto qp->resp_pkts. * rxe_requester() handles the send queue (qp->sq.queue). * rxe_responder() processes the skbs queued onto qp->req_pkts.
Since rxe_drain_req_pkts() processes qp->req_pkts, calling rxe_drain_req_pkts() from rxe_requester() is racy. Hence this patch.
Reported-by: Moni Shoua monis@mellanox.com Signed-off-by: Bart Van Assche bart.vanassche@wdc.com Cc: stable@vger.kernel.org Signed-off-by: Doug Ledford dledford@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/infiniband/sw/rxe/rxe_loc.h | 1 - drivers/infiniband/sw/rxe/rxe_req.c | 9 +-------- drivers/infiniband/sw/rxe/rxe_resp.c | 2 +- 3 files changed, 2 insertions(+), 10 deletions(-)
--- a/drivers/infiniband/sw/rxe/rxe_loc.h +++ b/drivers/infiniband/sw/rxe/rxe_loc.h @@ -237,7 +237,6 @@ int rxe_srq_from_attr(struct rxe_dev *rx
void rxe_release(struct kref *kref);
-void rxe_drain_req_pkts(struct rxe_qp *qp, bool notify); int rxe_completer(void *arg); int rxe_requester(void *arg); int rxe_responder(void *arg); --- a/drivers/infiniband/sw/rxe/rxe_req.c +++ b/drivers/infiniband/sw/rxe/rxe_req.c @@ -594,15 +594,8 @@ int rxe_requester(void *arg) rxe_add_ref(qp);
next_wqe: - if (unlikely(!qp->valid)) { - rxe_drain_req_pkts(qp, true); + if (unlikely(!qp->valid || qp->req.state == QP_STATE_ERROR)) goto exit; - } - - if (unlikely(qp->req.state == QP_STATE_ERROR)) { - rxe_drain_req_pkts(qp, true); - goto exit; - }
if (unlikely(qp->req.state == QP_STATE_RESET)) { qp->req.wqe_index = consumer_index(qp->sq.queue); --- a/drivers/infiniband/sw/rxe/rxe_resp.c +++ b/drivers/infiniband/sw/rxe/rxe_resp.c @@ -1210,7 +1210,7 @@ static enum resp_states do_class_d1e_err } }
-void rxe_drain_req_pkts(struct rxe_qp *qp, bool notify) +static void rxe_drain_req_pkts(struct rxe_qp *qp, bool notify) { struct sk_buff *skb;
Patches currently in stable-queue which might be from bart.vanassche@wdc.com are
queue-4.15/ib-core-fix-two-kernel-warnings-triggered-by-rxe-registration.patch queue-4.15/rdma-rxe-fix-a-race-condition-in-rxe_requester.patch queue-4.15/rdma-rxe-fix-rxe_qp_cleanup.patch queue-4.15/rdma-rxe-fix-a-race-condition-related-to-the-qp-error-state.patch
linux-stable-mirror@lists.linaro.org