]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
RDMA/rxe: Remove tasklet call from rxe_cq.c
authorBob Pearson <rpearsonhpe@gmail.com>
Mon, 27 Mar 2023 21:56:44 +0000 (16:56 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 11 May 2023 14:11:27 +0000 (23:11 +0900)
[ Upstream commit 78b26a335310a097d6b22581b706050db42f196c ]

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@gmail.com>
Link: https://lore.kernel.org/r/20230327215643.10410-1-rpearsonhpe@gmail.com
Acked-by: Zhu Yanjun <zyjzyj2000@gmail.com>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/infiniband/sw/rxe/rxe_cq.c
drivers/infiniband/sw/rxe/rxe_verbs.c
drivers/infiniband/sw/rxe/rxe_verbs.h

index 1df186534639aa507f100801fca835ed6ec59852..faf49c50bbaba464be1c23c4017fb0f61e4769ae 100644 (file)
@@ -39,21 +39,6 @@ err1:
        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;
@@ -135,21 +117,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);
index a3aee247aa157a977652f67924d2716fb72cab94..9ae7cf93365c7024ffa230767c0a9854a6a01ef8 100644 (file)
@@ -786,8 +786,6 @@ static int rxe_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
        if (atomic_read(&cq->num_wq))
                return -EINVAL;
 
-       rxe_cq_disable(cq);
-
        rxe_cleanup(cq);
        return 0;
 }
index c269ae2a322432ff00ec2ef6b4e9155dd91241ff..d812093a3916613ac1ddc2e41072a66c008680e1 100644 (file)
@@ -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;
 };