On Tue, Mar 28, 2023 at 5:58 AM Bob Pearson <rpearsonhpe@xxxxxxxxx> wrote: > > Remove the tasklet call in rxe_cq.c and also the is_dying in the > cq struct. There is no reason for the rxe driver to defer the call > to the cq completion handler by scheduling a tasklet. rxe_cq_post() > is not called in a hard irq context. > > The rxe driver currently is incorrect because the tasklet call is > made without protecting the cq pointer with a reference from having > the underlying memory freed before the deferred routine is called. > Executing the comp_handler inline fixes this problem. > > Fixes: 8700e3e7c485 ("Soft RoCE driver") > Signed-off-by: Bob Pearson <rpearsonhpe@xxxxxxxxx> Thanks Acked-by: Zhu Yanjun <zyjzyj2000@xxxxxxxxx> Zhu Yanjun > --- > drivers/infiniband/sw/rxe/rxe_cq.c | 32 +++------------------------ > drivers/infiniband/sw/rxe/rxe_verbs.c | 2 -- > drivers/infiniband/sw/rxe/rxe_verbs.h | 2 -- > 3 files changed, 3 insertions(+), 33 deletions(-) > > diff --git a/drivers/infiniband/sw/rxe/rxe_cq.c b/drivers/infiniband/sw/rxe/rxe_cq.c > index 66a13c935d50..20ff0c0c4605 100644 > --- a/drivers/infiniband/sw/rxe/rxe_cq.c > +++ b/drivers/infiniband/sw/rxe/rxe_cq.c > @@ -39,21 +39,6 @@ int rxe_cq_chk_attr(struct rxe_dev *rxe, struct rxe_cq *cq, > return -EINVAL; > } > > -static void rxe_send_complete(struct tasklet_struct *t) > -{ > - struct rxe_cq *cq = from_tasklet(cq, t, comp_task); > - unsigned long flags; > - > - spin_lock_irqsave(&cq->cq_lock, flags); > - if (cq->is_dying) { > - spin_unlock_irqrestore(&cq->cq_lock, flags); > - return; > - } > - spin_unlock_irqrestore(&cq->cq_lock, flags); > - > - cq->ibcq.comp_handler(&cq->ibcq, cq->ibcq.cq_context); > -} > - > int rxe_cq_from_init(struct rxe_dev *rxe, struct rxe_cq *cq, int cqe, > int comp_vector, struct ib_udata *udata, > struct rxe_create_cq_resp __user *uresp) > @@ -79,10 +64,6 @@ int rxe_cq_from_init(struct rxe_dev *rxe, struct rxe_cq *cq, int cqe, > > cq->is_user = uresp; > > - cq->is_dying = false; > - > - tasklet_setup(&cq->comp_task, rxe_send_complete); > - > spin_lock_init(&cq->cq_lock); > cq->ibcq.cqe = cqe; > return 0; > @@ -103,6 +84,7 @@ int rxe_cq_resize_queue(struct rxe_cq *cq, int cqe, > return err; > } > > +/* caller holds reference to cq */ > int rxe_cq_post(struct rxe_cq *cq, struct rxe_cqe *cqe, int solicited) > { > struct ib_event ev; > @@ -136,21 +118,13 @@ int rxe_cq_post(struct rxe_cq *cq, struct rxe_cqe *cqe, int solicited) > if ((cq->notify == IB_CQ_NEXT_COMP) || > (cq->notify == IB_CQ_SOLICITED && solicited)) { > cq->notify = 0; > - tasklet_schedule(&cq->comp_task); > + > + cq->ibcq.comp_handler(&cq->ibcq, cq->ibcq.cq_context); > } > > return 0; > } > > -void rxe_cq_disable(struct rxe_cq *cq) > -{ > - unsigned long flags; > - > - spin_lock_irqsave(&cq->cq_lock, flags); > - cq->is_dying = true; > - spin_unlock_irqrestore(&cq->cq_lock, flags); > -} > - > void rxe_cq_cleanup(struct rxe_pool_elem *elem) > { > struct rxe_cq *cq = container_of(elem, typeof(*cq), elem); > diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.c b/drivers/infiniband/sw/rxe/rxe_verbs.c > index 84b53c070fc5..090d5bfb1e18 100644 > --- a/drivers/infiniband/sw/rxe/rxe_verbs.c > +++ b/drivers/infiniband/sw/rxe/rxe_verbs.c > @@ -1178,8 +1178,6 @@ static int rxe_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata) > goto err_out; > } > > - rxe_cq_disable(cq); > - > err = rxe_cleanup(cq); > if (err) > rxe_err_cq(cq, "cleanup failed, err = %d", err); > diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.h b/drivers/infiniband/sw/rxe/rxe_verbs.h > index 84994a474e9a..dab6fa305bf2 100644 > --- a/drivers/infiniband/sw/rxe/rxe_verbs.h > +++ b/drivers/infiniband/sw/rxe/rxe_verbs.h > @@ -63,9 +63,7 @@ struct rxe_cq { > struct rxe_queue *queue; > spinlock_t cq_lock; > u8 notify; > - bool is_dying; > bool is_user; > - struct tasklet_struct comp_task; > atomic_t num_wq; > }; > > -- > 2.37.2 >