On Thu, Mar 17, 2022 at 08:55:11PM -0500, Bob Pearson wrote: > diff --git a/drivers/infiniband/sw/rxe/rxe_mr.c b/drivers/infiniband/sw/rxe/rxe_mr.c > index fc3942e04a1f..8059f31882ae 100644 > +++ b/drivers/infiniband/sw/rxe/rxe_mr.c > @@ -687,6 +687,7 @@ int rxe_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata) > if (atomic_read(&mr->num_mw) > 0) > return -EINVAL; > > + rxe_disable_lookup(mr); > rxe_put(mr); > > return 0; > @@ -32,6 +34,7 @@ int rxe_dealloc_mw(struct ib_mw *ibmw) > { > struct rxe_mw *mw = to_rmw(ibmw); > > + rxe_disable_lookup(mw); > rxe_put(mw); > > return 0; > @@ -487,6 +491,7 @@ static int rxe_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata) > struct rxe_qp *qp = to_rqp(ibqp); > int ret; > > + rxe_disable_lookup(qp); > ret = rxe_qp_chk_destroy(qp); > if (ret) > return ret; All the places doing 'rxe_disable_lookup' immediately follow it by rxe_put(), except this one. This one is buggy and should be ordered after. If all places do rxe_disable_lookp()/rxe_put() then I'm back to what I said earlier, this should just be a function that does xa_erase and forget about 'disable' Putting the xa_erase in the kref release is a mistake. Jason