| From a261c9da32c51e2d21ce8ea110e36eb3e7e7cce1 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Fri, 4 Jun 2021 18:05:59 -0500 |
| Subject: RDMA/rxe: Fix qp reference counting for atomic ops |
| |
| From: Bob Pearson <rpearsonhpe@gmail.com> |
| |
| [ Upstream commit 15ae1375ea91ae2dee6f12d71a79d8c0a10a30bf ] |
| |
| Currently the rdma_rxe driver attempts to protect atomic responder |
| resources by taking a reference to the qp which is only freed when the |
| resource is recycled for a new read or atomic operation. This means that |
| in normal circumstances there is almost always an extra qp reference once |
| an atomic operation has been executed which prevents cleaning up the qp |
| and associated pd and cqs when the qp is destroyed. |
| |
| This patch removes the call to rxe_add_ref() in send_atomic_ack() and the |
| call to rxe_drop_ref() in free_rd_atomic_resource(). If the qp is |
| destroyed while a peer is retrying an atomic op it will cause the |
| operation to fail which is acceptable. |
| |
| Link: https://lore.kernel.org/r/20210604230558.4812-1-rpearsonhpe@gmail.com |
| Reported-by: Zhu Yanjun <zyjzyj2000@gmail.com> |
| Fixes: 86af61764151 ("IB/rxe: remove unnecessary skb_clone") |
| Signed-off-by: Bob Pearson <rpearsonhpe@gmail.com> |
| Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/infiniband/sw/rxe/rxe_qp.c | 1 - |
| drivers/infiniband/sw/rxe/rxe_resp.c | 2 -- |
| 2 files changed, 3 deletions(-) |
| |
| diff --git a/drivers/infiniband/sw/rxe/rxe_qp.c b/drivers/infiniband/sw/rxe/rxe_qp.c |
| index 1e716fe7014c..a1b79015e6f2 100644 |
| --- a/drivers/infiniband/sw/rxe/rxe_qp.c |
| +++ b/drivers/infiniband/sw/rxe/rxe_qp.c |
| @@ -125,7 +125,6 @@ static void free_rd_atomic_resources(struct rxe_qp *qp) |
| void free_rd_atomic_resource(struct rxe_qp *qp, struct resp_res *res) |
| { |
| if (res->type == RXE_ATOMIC_MASK) { |
| - rxe_drop_ref(qp); |
| kfree_skb(res->atomic.skb); |
| } else if (res->type == RXE_READ_MASK) { |
| if (res->read.mr) |
| diff --git a/drivers/infiniband/sw/rxe/rxe_resp.c b/drivers/infiniband/sw/rxe/rxe_resp.c |
| index c7e3b6a4af38..83c03212099a 100644 |
| --- a/drivers/infiniband/sw/rxe/rxe_resp.c |
| +++ b/drivers/infiniband/sw/rxe/rxe_resp.c |
| @@ -966,8 +966,6 @@ static int send_atomic_ack(struct rxe_qp *qp, struct rxe_pkt_info *pkt, |
| goto out; |
| } |
| |
| - rxe_add_ref(qp); |
| - |
| res = &qp->resp.resources[qp->resp.res_head]; |
| free_rd_atomic_resource(qp, res); |
| rxe_advance_resp_resource(qp); |
| -- |
| 2.30.2 |
| |