]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
RDMA/irdma: Replace waitqueue and flag with completion
authorJacob Moroni <jmoroni@google.com>
Tue, 16 Jun 2026 15:56:01 +0000 (15:56 +0000)
committerJason Gunthorpe <jgg@nvidia.com>
Tue, 16 Jun 2026 18:29:33 +0000 (15:29 -0300)
The driver previously used a waitqueue along with an explicit
request_done flag, but without proper barriers around request_done.

An earlier patch by Gui-Dong Han <hanguidong02@gmail.com> attempted
to fix this by adding the missing memory barriers. Rather than
adding the barriers, this patch replaces the waitqueue+flag with
a completion, which is designed for this exact purpose.

Fixes: 44d9e52977a1 ("RDMA/irdma: Implement device initialization definitions")
Fixes: 915cc7ac0f8e ("RDMA/irdma: Add miscellaneous utility definitions")
Link: https://patch.msgid.link/r/20260616155601.1081448-1-jmoroni@google.com
Signed-off-by: Jacob Moroni <jmoroni@google.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
drivers/infiniband/hw/irdma/hw.c
drivers/infiniband/hw/irdma/main.h
drivers/infiniband/hw/irdma/utils.c

index f9be467d137f823391b9756d74f55c9818a8fa5c..c345cc6542566b9b3dfc98e687f82f4031573bbb 100644 (file)
@@ -235,8 +235,7 @@ static void irdma_complete_cqp_request(struct irdma_cqp *cqp,
                                       struct irdma_cqp_request *cqp_request)
 {
        if (cqp_request->waiting) {
-               WRITE_ONCE(cqp_request->request_done, true);
-               wake_up(&cqp_request->waitq);
+               complete_all(&cqp_request->comp);
        } else if (cqp_request->callback_fcn) {
                cqp_request->callback_fcn(cqp_request);
        }
@@ -1107,9 +1106,9 @@ static int irdma_create_cqp(struct irdma_pci_f *rf)
        INIT_LIST_HEAD(&cqp->cqp_avail_reqs);
        INIT_LIST_HEAD(&cqp->cqp_pending_reqs);
 
-       /* init the waitqueue of the cqp_requests and add them to the list */
+       /* init the completion of the cqp_requests and add them to the list */
        for (i = 0; i < sqsize; i++) {
-               init_waitqueue_head(&cqp->cqp_requests[i].waitq);
+               init_completion(&cqp->cqp_requests[i].comp);
                list_add_tail(&cqp->cqp_requests[i].list, &cqp->cqp_avail_reqs);
        }
        init_waitqueue_head(&cqp->remove_wq);
index 3d49bd57bae7cf56923b48def0417239aed4f812..8c17a201c1fd2f515a31d321d35f2b4660fc9278 100644 (file)
@@ -161,13 +161,12 @@ struct irdma_cqp_compl_info {
 
 struct irdma_cqp_request {
        struct cqp_cmds_info info;
-       wait_queue_head_t waitq;
+       struct completion comp;
        struct list_head list;
        refcount_t refcnt;
        void (*callback_fcn)(struct irdma_cqp_request *cqp_request);
        void *param;
        struct irdma_cqp_compl_info compl_info;
-       bool request_done; /* READ/WRITE_ONCE macros operate on it */
        bool waiting:1;
        bool dynamic:1;
        bool pending:1;
index 7cc7b107db3cc1a9657ad56cc11a8819bd0e305d..e4037d5ef8993ef23ca1f1191832fae1ec279a21 100644 (file)
@@ -442,7 +442,7 @@ struct irdma_cqp_request *irdma_alloc_and_get_cqp_request(struct irdma_cqp *cqp,
                if (cqp_request) {
                        cqp_request->dynamic = true;
                        if (wait)
-                               init_waitqueue_head(&cqp_request->waitq);
+                               init_completion(&cqp_request->comp);
                }
        }
        if (!cqp_request) {
@@ -480,7 +480,7 @@ void irdma_free_cqp_request(struct irdma_cqp *cqp,
        if (cqp_request->dynamic) {
                kfree(cqp_request);
        } else {
-               WRITE_ONCE(cqp_request->request_done, false);
+               reinit_completion(&cqp_request->comp);
                cqp_request->callback_fcn = NULL;
                cqp_request->waiting = false;
                cqp_request->pending = false;
@@ -515,8 +515,7 @@ irdma_free_pending_cqp_request(struct irdma_cqp *cqp,
 {
        if (cqp_request->waiting) {
                cqp_request->compl_info.error = true;
-               WRITE_ONCE(cqp_request->request_done, true);
-               wake_up(&cqp_request->waitq);
+               complete_all(&cqp_request->comp);
        }
        wait_event_timeout(cqp->remove_wq,
                           refcount_read(&cqp_request->refcnt) == 1, 1000);
@@ -609,9 +608,8 @@ static int irdma_wait_event(struct irdma_pci_f *rf,
        cqp_timeout.compl_cqp_cmds = atomic64_read(&rf->sc_dev.cqp->completed_ops);
        do {
                irdma_cqp_ce_handler(rf, &rf->ccq.sc_cq);
-               if (wait_event_timeout(cqp_request->waitq,
-                                      READ_ONCE(cqp_request->request_done),
-                                      msecs_to_jiffies(CQP_COMPL_WAIT_TIME_MS)))
+               if (wait_for_completion_timeout(&cqp_request->comp,
+                                       msecs_to_jiffies(CQP_COMPL_WAIT_TIME_MS)))
                        break;
 
                if (cqp_request->pending)