Skip to content

Commit

Permalink
RDMA/rxe: Add wait for completion to obj destruct
Browse files Browse the repository at this point in the history
This patch adds code to wait until pending activity on RDMA objects has
completed before freeing or returning to rdma-code where the object may
be freed.

Signed-off-by: Bob Pearson <rpearsonhpe@gmail.com>
  • Loading branch information
Bob Pearson authored and intel-lab-lkp committed Dec 2, 2021
1 parent 208059e commit c12d68c
Show file tree
Hide file tree
Showing 10 changed files with 118 additions and 39 deletions.
4 changes: 3 additions & 1 deletion drivers/infiniband/sw/rxe/rxe_comp.c
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,9 @@ int rxe_completer(void *arg)
enum comp_state state;
int ret = 0;

rxe_add_ref(qp);
/* check qp pointer still valid */
if (!rxe_add_ref(qp))
return -EAGAIN;

if (!qp->valid || qp->req.state == QP_STATE_ERROR ||
qp->req.state == QP_STATE_RESET) {
Expand Down
4 changes: 4 additions & 0 deletions drivers/infiniband/sw/rxe/rxe_mcast.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ int rxe_mcast_drop_grp_elem(struct rxe_dev *rxe, struct rxe_qp *qp,

out_drop_ref:
rxe_drop_ref(grp); /* ref from get_key */
if (grp->elem.complete.done)
rxe_fini(grp);
err1:
return ret;
}
Expand Down Expand Up @@ -149,6 +151,8 @@ void rxe_drop_all_mcast_groups(struct rxe_qp *qp)
spin_unlock_bh(&grp->mcg_lock);
rxe_drop_ref(qp);
rxe_drop_ref(grp);
if (grp->elem.complete.done)
rxe_fini(grp);
kfree(elem);
}
}
Expand Down
2 changes: 2 additions & 0 deletions drivers/infiniband/sw/rxe/rxe_mr.c
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,8 @@ int rxe_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata)
rxe_drop_ref(mr_pd(mr));
rxe_drop_ref(mr);

rxe_fini(mr);

return 0;
}

Expand Down
14 changes: 8 additions & 6 deletions drivers/infiniband/sw/rxe/rxe_mw.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ int rxe_alloc_mw(struct ib_mw *ibmw, struct ib_udata *udata)
struct rxe_dev *rxe = to_rdev(ibmw->device);
int ret;

rxe_add_ref(pd);
if (!rxe_add_ref(pd))
return -EINVAL;

ret = rxe_add_to_pool(&rxe->mw_pool, mw);
if (ret) {
Expand Down Expand Up @@ -60,8 +61,9 @@ int rxe_dealloc_mw(struct ib_mw *ibmw)
rxe_do_dealloc_mw(mw);
spin_unlock_bh(&mw->lock);

rxe_drop_ref(mw);
rxe_drop_ref(pd);
rxe_drop_ref(mw);
rxe_fini(mw);

return 0;
}
Expand Down Expand Up @@ -178,11 +180,11 @@ static void rxe_do_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe,
if (mw->length) {
mw->mr = mr;
atomic_inc(&mr->num_mw);
rxe_add_ref(mr);
rxe_add_ref(mr); /* safe */
}

if (mw->ibmw.type == IB_MW_TYPE_2) {
rxe_add_ref(qp);
rxe_add_ref(qp); /* safe */
mw->qp = qp;
}
}
Expand All @@ -199,7 +201,7 @@ int rxe_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe)
mw = rxe_pool_get_index(&rxe->mw_pool, mw_rkey >> 8);
if (unlikely(!mw)) {
ret = -EINVAL;
goto err;
goto err_out;
}

if (unlikely(mw->rkey != mw_rkey)) {
Expand Down Expand Up @@ -236,7 +238,7 @@ int rxe_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe)
rxe_drop_ref(mr);
err_drop_mw:
rxe_drop_ref(mw);
err:
err_out:
return ret;
}

Expand Down
24 changes: 22 additions & 2 deletions drivers/infiniband/sw/rxe/rxe_pool.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ static void *__rxe_alloc(struct rxe_pool *pool, gfp_t flags)
elem->pool = pool;
elem->obj = obj;
kref_init(&elem->ref_cnt);
init_completion(&elem->complete);

if (pool->init) {
err = pool->init(elem);
Expand Down Expand Up @@ -189,6 +190,7 @@ int __rxe_add_to_pool(struct rxe_pool *pool, struct rxe_pool_elem *elem)
elem->pool = pool;
elem->obj = (u8 *)elem - pool->elem_offset;
kref_init(&elem->ref_cnt);
init_completion(&elem->complete);

if (pool->init) {
err = pool->init(elem);
Expand Down Expand Up @@ -372,8 +374,26 @@ void rxe_elem_release(struct kref *kref)
if (pool->cleanup)
pool->cleanup(elem);

if (pool->flags & RXE_POOL_ALLOC)
kfree(elem->obj);
complete_all(&elem->complete);

atomic_dec(&pool->num_elem);
}

/**
* rxe_elem_free() - free memory holding pool element
* @elem: the pool elem
*/
void __rxe_fini(struct rxe_pool_elem *elem)
{
struct rxe_pool *pool = elem->pool;
int ret;

ret = wait_for_completion_timeout(&elem->complete, 10);

if (!ret)
pr_info("Timed out waiting for %s#%d\n", pool->name,
elem->index);

if (elem->pool->flags & RXE_POOL_ALLOC)
kfree(elem->obj);
}
4 changes: 4 additions & 0 deletions drivers/infiniband/sw/rxe/rxe_pool.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ struct rxe_pool_elem {
struct rxe_pool *pool;
void *obj;
struct kref ref_cnt;
struct completion complete;
struct list_head list;

/* only used if keyed */
Expand Down Expand Up @@ -105,4 +106,7 @@ static inline bool __rxe_drop_ref(struct rxe_pool_elem *elem)
}
#define rxe_drop_ref(obj) __rxe_drop_ref(&(obj)->elem)

void __rxe_fini(struct rxe_pool_elem *elem);
#define rxe_fini(obj) __rxe_fini(&(obj)->elem)

#endif /* RXE_POOL_H */
4 changes: 2 additions & 2 deletions drivers/infiniband/sw/rxe/rxe_recv.c
Original file line number Diff line number Diff line change
Expand Up @@ -288,11 +288,11 @@ static void rxe_rcv_mcast_pkt(struct rxe_dev *rxe, struct sk_buff *skb)

cpkt = SKB_TO_PKT(cskb);
cpkt->qp = qp;
rxe_add_ref(qp);
rxe_add_ref(qp); /* safe */
rxe_rcv_pkt(cpkt, cskb);
} else {
pkt->qp = qp;
rxe_add_ref(qp);
rxe_add_ref(qp); /* safe */
rxe_rcv_pkt(pkt, skb);
skb = NULL; /* mark consumed */
}
Expand Down
11 changes: 7 additions & 4 deletions drivers/infiniband/sw/rxe/rxe_req.c
Original file line number Diff line number Diff line change
Expand Up @@ -614,9 +614,10 @@ int rxe_requester(void *arg)
struct rxe_ah *ah;
struct rxe_av *av;

rxe_add_ref(qp);
/* check qp pointer still valid */
if (!rxe_add_ref(qp))
return -EAGAIN;

next_wqe:
if (unlikely(!qp->valid || qp->req.state == QP_STATE_ERROR))
goto exit;

Expand Down Expand Up @@ -644,7 +645,7 @@ int rxe_requester(void *arg)
if (unlikely(ret))
goto err;
else
goto next_wqe;
goto done;
}

if (unlikely(qp_type(qp) == IB_QPT_RC &&
Expand Down Expand Up @@ -760,7 +761,9 @@ int rxe_requester(void *arg)

update_state(qp, wqe, &pkt, payload);

goto next_wqe;
done:
rxe_drop_ref(qp);
return 0;

err_drop_ah:
if (ah)
Expand Down
6 changes: 4 additions & 2 deletions drivers/infiniband/sw/rxe/rxe_resp.c
Original file line number Diff line number Diff line change
Expand Up @@ -463,8 +463,8 @@ static enum resp_states check_rkey(struct rxe_qp *qp,
if (mw->access & IB_ZERO_BASED)
qp->resp.offset = mw->addr;

rxe_add_ref(mr); /* safe */
rxe_drop_ref(mw);
rxe_add_ref(mr);
} else {
mr = lookup_mr(qp->pd, access, rkey, RXE_LOOKUP_REMOTE);
if (!mr) {
Expand Down Expand Up @@ -1247,7 +1247,9 @@ int rxe_responder(void *arg)
struct rxe_pkt_info *pkt = NULL;
int ret = 0;

rxe_add_ref(qp);
/* check qp pointer still valid */
if (!rxe_add_ref(qp))
return -EAGAIN;

qp->resp.aeth_syndrome = AETH_ACK_UNLIMITED;

Expand Down

0 comments on commit c12d68c

Please sign in to comment.