get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/2216189/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2216189,
    "url": "http://patchwork.ozlabs.org/api/patches/2216189/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/ubuntu-kernel/patch/20260325232149.127814-7-ian.whitfield@canonical.com/",
    "project": {
        "id": 15,
        "url": "http://patchwork.ozlabs.org/api/projects/15/?format=api",
        "name": "Ubuntu Kernel",
        "link_name": "ubuntu-kernel",
        "list_id": "kernel-team.lists.ubuntu.com",
        "list_email": "kernel-team@lists.ubuntu.com",
        "web_url": null,
        "scm_url": null,
        "webscm_url": null,
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<20260325232149.127814-7-ian.whitfield@canonical.com>",
    "list_archive_url": null,
    "date": "2026-03-25T23:21:49",
    "name": "[SRU,Q:linux-gcp,6/6] RDMA/irdma: Use CQ ID for CEQE context",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "6d948cc4dbf54fab338510a428f46c91d62f76d6",
    "submitter": {
        "id": 89403,
        "url": "http://patchwork.ozlabs.org/api/people/89403/?format=api",
        "name": "Ian Whitfield",
        "email": "ian.whitfield@canonical.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/ubuntu-kernel/patch/20260325232149.127814-7-ian.whitfield@canonical.com/mbox/",
    "series": [
        {
            "id": 497521,
            "url": "http://patchwork.ozlabs.org/api/series/497521/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/ubuntu-kernel/list/?series=497521",
            "date": "2026-03-25T23:21:43",
            "name": "Add irdma fixups since 6.19",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/497521/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2216189/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2216189/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<kernel-team-bounces@lists.ubuntu.com>",
        "X-Original-To": "incoming@patchwork.ozlabs.org",
        "Delivered-To": "patchwork-incoming@legolas.ozlabs.org",
        "Authentication-Results": [
            "legolas.ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (4096-bit key;\n unprotected) header.d=canonical.com header.i=@canonical.com\n header.a=rsa-sha256 header.s=20251003 header.b=Uphw+6PW;\n\tdkim-atps=neutral",
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com\n (client-ip=185.125.189.65; helo=lists.ubuntu.com;\n envelope-from=kernel-team-bounces@lists.ubuntu.com;\n receiver=patchwork.ozlabs.org)"
        ],
        "Received": [
            "from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fh2xF4Hkqz1xy1\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 26 Mar 2026 10:22:09 +1100 (AEDT)",
            "from localhost ([127.0.0.1] helo=lists.ubuntu.com)\n\tby lists.ubuntu.com with esmtp (Exim 4.86_2)\n\t(envelope-from <kernel-team-bounces@lists.ubuntu.com>)\n\tid 1w5XY3-0004xh-2W; Wed, 25 Mar 2026 23:22:03 +0000",
            "from smtp-relay-internal-0.internal ([10.131.114.225]\n helo=smtp-relay-internal-0.canonical.com)\n by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)\n (Exim 4.86_2) (envelope-from <ian.whitfield@canonical.com>)\n id 1w5XXx-0004nA-T3\n for kernel-team@lists.ubuntu.com; Wed, 25 Mar 2026 23:21:57 +0000",
            "from mail-qt1-f200.google.com (mail-qt1-f200.google.com\n [209.85.160.200])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest\n SHA256)\n (No client certificate requested)\n by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id A88603F29D\n for <kernel-team@lists.ubuntu.com>; Wed, 25 Mar 2026 23:21:57 +0000 (UTC)",
            "by mail-qt1-f200.google.com with SMTP id\n d75a77b69052e-50b6f869676so14147591cf.2\n for <kernel-team@lists.ubuntu.com>; Wed, 25 Mar 2026 16:21:57 -0700 (PDT)",
            "from localhost ([2600:4041:dc:e800:448b:3cc:c137:e67a])\n by smtp.gmail.com with ESMTPSA id\n d75a77b69052e-50b920faa8asm10613951cf.4.2026.03.25.16.21.55\n for <kernel-team@lists.ubuntu.com>\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Wed, 25 Mar 2026 16:21:55 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com;\n s=20251003; t=1774480917;\n bh=DboaqHW3ErGyzYvPsxa2Kn2q89YwjVmg8XGR5CJKeEM=;\n h=From:To:Subject:Date:Message-ID:In-Reply-To:References:\n MIME-Version;\n b=Uphw+6PW8BIeCVX2ijihgVymALAtzhxOA9gG9zq9bvOcUkZtbWOZnaFaA09kocBC/\n f2brNhcgag56/ujpZ/qBbYPdmHyg9LqazX8F/IYfj8y5qeYF3Xx2p7yKtYLlH+rU+0\n bg1B2lx+gd/13frqOob0Qg7yBeV+fI2sQDmISl3LGXgjVmUBqBqZyvXQsKPcOQBn9l\n ZcDjmH/JdTJxsyq/gaVKop0lYRpNC8wz4lXfwCn13KnfeXEmwv50oUtJsw0pRNEK5l\n rNFtsOYfxfappb+3ZlUgxofXlDOPM3nRt0UOCi79GmyFrJ8e2arB4/QwkBO3bj99bh\n /wWU+c+UtW1h6TpbyZY/4e0uwqvjdTvp6ooOvOCJpQJkPF84syFCb9acUcZHKczQuV\n xtxP8fo1Ytys+p1aIXcIcqChgrQAoYAJEwWDeRkNWcrcCLVrVC5/Yn2MJ0nYc7H9L7\n eWCroFocaEO8UQDqIDKrQCEpvFbsNRbIkPvtbLqgbIUvDOOtsLragUYYDoOS2cIwYF\n AkfmANxk/2wSZmn+AsAUpmOZOoprTz2BbAanSeIGOV3Q4H9Hj1wml++1fjzqTgcPJD\n WMktIaEvqcBECC/et/GTY12V2t6Fl82qsc9Uti+sx+IHT9n32+JeLeLBHFwEAdDobH\n wN+IeBeqS5mm113rpkRMr0mc=",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1774480916; x=1775085716;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to\n :cc:subject:date:message-id:reply-to;\n bh=DboaqHW3ErGyzYvPsxa2Kn2q89YwjVmg8XGR5CJKeEM=;\n b=k2tk174U4J9cJJQ1peDkIqVKjtlDxcmXe8371/yC4643j9Set6TVvmNb2GJqm5qHqi\n Lkc33qyayY1ky+mBV31P4MvDWHiW14a/Q5wGilbWIliwrTEtuE4O9VWGeTjjSvXoFnzu\n AJZxy+UaCdvX9ZxDZ6RBfLAtZM8ICKk/RNFRGR/VL3mteMtDYrQMIJ8VdR4KtNdjwZuH\n MaeFd76UPqQfsQA0Go7FZD/q0FNllhdUWAaT6UdqqWhabL3PPXw84lQ0T1EPauPf4JG/\n IqvzrKj8xcvNDMkPzXHRGw3UUPQp3MkN6o4dZgB8hm3/tgBnd8OekRAd6SmfEYNvka4f\n tSAQ==",
        "X-Gm-Message-State": "AOJu0YxuEtE47NiBrPqzh4XakFKcqt2ruNfTvC7xcB+jFv7wobntgXF7\n lMUWMzpgwIVe6OrC+BzdU4baqHCjRa9bmeFKk19wa87I6MqlRE5wcJpyFggchahhHnNJb9gcQY/\n kCPIXhNGYhuDcAHcGjelYZs/BZZze/JawLCw/1GXwEfLGEk0jWYJlVENr8ZGA6HpcgrzAP8im3R\n hf+wJreJJxFC2SzQ==",
        "X-Gm-Gg": "ATEYQzyy+JycE4V6yxLCRiCDB2mFrc+y66HjAnYBKz28mHF/aYTUV4H5WYCicd6Kx2g\n f5b7Zy5B0QN3MrSAMnKh9nRHVeh1E8UihgKciSlkDLqitqO6Zg07GJxw1qLFjuNqrBULb2XVNK9\n /KWhL7EGXaUnu4Vf3pun1CfXTooWFHUFQk/bRdWgqQrlNN+B2s4DLePYAmuxT/SIxd08KpgMSUb\n ah9Ml4wHj8IoZV0DP4soL2lbIhFwo8CBrJB61H967cM+TSwpRk8jU0gj0i/JKiCq3RRBqJFYNhc\n nQ6H4joXljD7p1VL9cjPe+AeDRxHj3pNR8TTmqOCKhGvd9oSsoEV22MHevCeejxCYPjR15D59Tj\n HGTTsUvTWhJv0nNgLvtZcwRnES+GSxg==",
        "X-Received": [
            "by 2002:a05:622a:248f:b0:50b:4f56:f6ee with SMTP id\n d75a77b69052e-50b80e07c18mr81338161cf.40.1774480916386;\n Wed, 25 Mar 2026 16:21:56 -0700 (PDT)",
            "by 2002:a05:622a:248f:b0:50b:4f56:f6ee with SMTP id\n d75a77b69052e-50b80e07c18mr81337831cf.40.1774480915797;\n Wed, 25 Mar 2026 16:21:55 -0700 (PDT)"
        ],
        "From": "Ian Whitfield <ian.whitfield@canonical.com>",
        "To": "kernel-team@lists.ubuntu.com",
        "Subject": "[SRU][Q:linux-gcp][PATCH 6/6] RDMA/irdma: Use CQ ID for CEQE context",
        "Date": "Wed, 25 Mar 2026 19:21:49 -0400",
        "Message-ID": "<20260325232149.127814-7-ian.whitfield@canonical.com>",
        "X-Mailer": "git-send-email 2.43.0",
        "In-Reply-To": "<20260325232149.127814-1-ian.whitfield@canonical.com>",
        "References": "<20260325232149.127814-1-ian.whitfield@canonical.com>",
        "MIME-Version": "1.0",
        "X-BeenThere": "kernel-team@lists.ubuntu.com",
        "X-Mailman-Version": "2.1.20",
        "Precedence": "list",
        "List-Id": "Kernel team discussions <kernel-team.lists.ubuntu.com>",
        "List-Unsubscribe": "<https://lists.ubuntu.com/mailman/options/kernel-team>,\n <mailto:kernel-team-request@lists.ubuntu.com?subject=unsubscribe>",
        "List-Archive": "<https://lists.ubuntu.com/archives/kernel-team>",
        "List-Post": "<mailto:kernel-team@lists.ubuntu.com>",
        "List-Help": "<mailto:kernel-team-request@lists.ubuntu.com?subject=help>",
        "List-Subscribe": "<https://lists.ubuntu.com/mailman/listinfo/kernel-team>,\n <mailto:kernel-team-request@lists.ubuntu.com?subject=subscribe>",
        "Content-Type": "text/plain; charset=\"utf-8\"",
        "Content-Transfer-Encoding": "base64",
        "Errors-To": "kernel-team-bounces@lists.ubuntu.com",
        "Sender": "\"kernel-team\" <kernel-team-bounces@lists.ubuntu.com>"
    },
    "content": "From: Jacob Moroni <jmoroni@google.com>\n\nBugLink: https://bugs.launchpad.net/bugs/2146168\n\nThe hardware allows for an opaque CQ context field to be carried\nover into CEQEs for the CQ. Previously, a pointer to the CQ was used\nfor this context. In the normal CQ destroy flow, the CEQ ring is\nscrubbed to remove any preexisting CEQEs for the CQ that may not have\nbeen processed yet so that the CQ structure is not dereferenced in the\nCEQ ISR after the CQ has been freed.\n\nHowever, in some cases, it is possible for a CEQE to be in flight in\nHW even after the CQ destroy command completion is received, so it\ncould be missed during the scrub.\n\nTo protect against this, we can take advantage of the CQ table that\nalready exists and use the CQ ID for this context rather than a CQ\npointer.\n\nSigned-off-by: Jacob Moroni <jmoroni@google.com>\nLink: https://patch.msgid.link/20260120212546.1893076-2-jmoroni@google.com\nSigned-off-by: Leon Romanovsky <leon@kernel.org>\n(cherry picked from commit 2529aead51673814ebf464723626ac608b8635a5)\nSigned-off-by: Ian Whitfield <ian.whitfield@canonical.com>\n---\n drivers/infiniband/hw/irdma/ctrl.c  | 62 ++++++++------------\n drivers/infiniband/hw/irdma/hw.c    | 88 +++++++++++++++++++++++++----\n drivers/infiniband/hw/irdma/puda.c  | 14 +++++\n drivers/infiniband/hw/irdma/type.h  |  6 +-\n drivers/infiniband/hw/irdma/utils.c |  3 +-\n drivers/infiniband/hw/irdma/verbs.c |  5 +-\n 6 files changed, 127 insertions(+), 51 deletions(-)",
    "diff": "diff --git a/drivers/infiniband/hw/irdma/ctrl.c b/drivers/infiniband/hw/irdma/ctrl.c\nindex c17b1c14dfe2..a996a194516f 100644\n--- a/drivers/infiniband/hw/irdma/ctrl.c\n+++ b/drivers/infiniband/hw/irdma/ctrl.c\n@@ -2886,15 +2886,6 @@ static int irdma_sc_resume_qp(struct irdma_sc_cqp *cqp, struct irdma_sc_qp *qp,\n \treturn 0;\n }\n \n-/**\n- * irdma_sc_cq_ack - acknowledge completion q\n- * @cq: cq struct\n- */\n-static inline void irdma_sc_cq_ack(struct irdma_sc_cq *cq)\n-{\n-\twritel(cq->cq_uk.cq_id, cq->cq_uk.cq_ack_db);\n-}\n-\n /**\n  * irdma_sc_cq_init - initialize completion q\n  * @cq: cq struct\n@@ -2956,7 +2947,7 @@ static int irdma_sc_cq_create(struct irdma_sc_cq *cq, u64 scratch,\n \t\treturn -ENOMEM;\n \n \tset_64bit_val(wqe, 0, cq->cq_uk.cq_size);\n-\tset_64bit_val(wqe, 8, (uintptr_t)cq >> 1);\n+\tset_64bit_val(wqe, 8, cq->cq_uk.cq_id);\n \tset_64bit_val(wqe, 16,\n \t\t      FIELD_PREP(IRDMA_CQPSQ_CQ_SHADOW_READ_THRESHOLD, cq->shadow_read_threshold));\n \tset_64bit_val(wqe, 32, (cq->virtual_map ? 0 : cq->cq_pa));\n@@ -3013,7 +3004,7 @@ int irdma_sc_cq_destroy(struct irdma_sc_cq *cq, u64 scratch, bool post_sq)\n \t\treturn -ENOMEM;\n \n \tset_64bit_val(wqe, 0, cq->cq_uk.cq_size);\n-\tset_64bit_val(wqe, 8, (uintptr_t)cq >> 1);\n+\tset_64bit_val(wqe, 8, cq->cq_uk.cq_id);\n \tset_64bit_val(wqe, 40, cq->shadow_area_pa);\n \tset_64bit_val(wqe, 48,\n \t\t      (cq->virtual_map ? cq->first_pm_pbl_idx : 0));\n@@ -3082,7 +3073,7 @@ static int irdma_sc_cq_modify(struct irdma_sc_cq *cq,\n \t\treturn -ENOMEM;\n \n \tset_64bit_val(wqe, 0, info->cq_size);\n-\tset_64bit_val(wqe, 8, (uintptr_t)cq >> 1);\n+\tset_64bit_val(wqe, 8, cq->cq_uk.cq_id);\n \tset_64bit_val(wqe, 16,\n \t\t      FIELD_PREP(IRDMA_CQPSQ_CQ_SHADOW_READ_THRESHOLD, info->shadow_read_threshold));\n \tset_64bit_val(wqe, 32, info->cq_pa);\n@@ -4460,47 +4451,38 @@ int irdma_sc_ceq_destroy(struct irdma_sc_ceq *ceq, u64 scratch, bool post_sq)\n  * irdma_sc_process_ceq - process ceq\n  * @dev: sc device struct\n  * @ceq: ceq sc structure\n+ * @cq_idx: Pointer to a CQ ID that will be populated.\n  *\n  * It is expected caller serializes this function with cleanup_ceqes()\n  * because these functions manipulate the same ceq\n+ *\n+ * Return: True if cq_idx has been populated with a CQ ID.\n  */\n-void *irdma_sc_process_ceq(struct irdma_sc_dev *dev, struct irdma_sc_ceq *ceq)\n+bool irdma_sc_process_ceq(struct irdma_sc_dev *dev, struct irdma_sc_ceq *ceq,\n+\t\t\t  u32 *cq_idx)\n {\n \tu64 temp;\n \t__le64 *ceqe;\n-\tstruct irdma_sc_cq *cq = NULL;\n-\tstruct irdma_sc_cq *temp_cq;\n \tu8 polarity;\n-\tu32 cq_idx;\n \n \tdo {\n-\t\tcq_idx = 0;\n \t\tceqe = IRDMA_GET_CURRENT_CEQ_ELEM(ceq);\n \t\tget_64bit_val(ceqe, 0, &temp);\n \t\tpolarity = (u8)FIELD_GET(IRDMA_CEQE_VALID, temp);\n \t\tif (polarity != ceq->polarity)\n-\t\t\treturn NULL;\n+\t\t\treturn false;\n \n-\t\ttemp_cq = (struct irdma_sc_cq *)(unsigned long)(temp << 1);\n-\t\tif (!temp_cq) {\n-\t\t\tcq_idx = IRDMA_INVALID_CQ_IDX;\n-\t\t\tIRDMA_RING_MOVE_TAIL(ceq->ceq_ring);\n-\n-\t\t\tif (!IRDMA_RING_CURRENT_TAIL(ceq->ceq_ring))\n-\t\t\t\tceq->polarity ^= 1;\n-\t\t\tcontinue;\n-\t\t}\n-\n-\t\tcq = temp_cq;\n+\t\t/* Truncate. Discard valid bit which is MSb of temp. */\n+\t\t*cq_idx = temp;\n+\t\tif (*cq_idx >= dev->hmc_info->hmc_obj[IRDMA_HMC_IW_CQ].cnt)\n+\t\t\t*cq_idx = IRDMA_INVALID_CQ_IDX;\n \n \t\tIRDMA_RING_MOVE_TAIL(ceq->ceq_ring);\n \t\tif (!IRDMA_RING_CURRENT_TAIL(ceq->ceq_ring))\n \t\t\tceq->polarity ^= 1;\n-\t} while (cq_idx == IRDMA_INVALID_CQ_IDX);\n+\t} while (*cq_idx == IRDMA_INVALID_CQ_IDX);\n \n-\tif (cq)\n-\t\tirdma_sc_cq_ack(cq);\n-\treturn cq;\n+\treturn true;\n }\n \n /**\n@@ -4514,10 +4496,10 @@ void *irdma_sc_process_ceq(struct irdma_sc_dev *dev, struct irdma_sc_ceq *ceq)\n  */\n void irdma_sc_cleanup_ceqes(struct irdma_sc_cq *cq, struct irdma_sc_ceq *ceq)\n {\n-\tstruct irdma_sc_cq *next_cq;\n \tu8 ceq_polarity = ceq->polarity;\n \t__le64 *ceqe;\n \tu8 polarity;\n+\tu32 cq_idx;\n \tu64 temp;\n \tint next;\n \tu32 i;\n@@ -4532,9 +4514,10 @@ void irdma_sc_cleanup_ceqes(struct irdma_sc_cq *cq, struct irdma_sc_ceq *ceq)\n \t\tif (polarity != ceq_polarity)\n \t\t\treturn;\n \n-\t\tnext_cq = (struct irdma_sc_cq *)(unsigned long)(temp << 1);\n-\t\tif (cq == next_cq)\n-\t\t\tset_64bit_val(ceqe, 0, temp & IRDMA_CEQE_VALID);\n+\t\tcq_idx = temp;\n+\t\tif (cq_idx == cq->cq_uk.cq_id)\n+\t\t\tset_64bit_val(ceqe, 0, (temp & IRDMA_CEQE_VALID) |\n+\t\t\t\t      IRDMA_INVALID_CQ_IDX);\n \n \t\tnext = IRDMA_RING_GET_NEXT_TAIL(ceq->ceq_ring, i);\n \t\tif (!next)\n@@ -4974,7 +4957,7 @@ int irdma_sc_ccq_destroy(struct irdma_sc_cq *ccq, u64 scratch, bool post_sq)\n \t\treturn -ENOMEM;\n \n \tset_64bit_val(wqe, 0, ccq->cq_uk.cq_size);\n-\tset_64bit_val(wqe, 8, (uintptr_t)ccq >> 1);\n+\tset_64bit_val(wqe, 8, ccq->cq_uk.cq_id);\n \tset_64bit_val(wqe, 40, ccq->shadow_area_pa);\n \n \thdr = ccq->cq_uk.cq_id |\n@@ -6461,6 +6444,9 @@ int irdma_sc_dev_init(enum irdma_vers ver, struct irdma_sc_dev *dev,\n \tint ret_code = 0;\n \tu8 db_size;\n \n+\tspin_lock_init(&dev->puda_cq_lock);\n+\tdev->ilq_cq = NULL;\n+\tdev->ieq_cq = NULL;\n \tINIT_LIST_HEAD(&dev->cqp_cmd_head); /* for CQP command backlog */\n \tmutex_init(&dev->ws_mutex);\n \tdev->hmc_fn_id = info->hmc_fn_id;\ndiff --git a/drivers/infiniband/hw/irdma/hw.c b/drivers/infiniband/hw/irdma/hw.c\nindex da63e00b4264..616588552b9c 100644\n--- a/drivers/infiniband/hw/irdma/hw.c\n+++ b/drivers/infiniband/hw/irdma/hw.c\n@@ -98,6 +98,74 @@ static void irdma_puda_ce_handler(struct irdma_pci_f *rf,\n \tirdma_sc_ccq_arm(cq);\n }\n \n+/**\n+ * irdma_process_normal_ceqe - Handle a CEQE for a normal CQ.\n+ * @rf: RDMA PCI function.\n+ * @dev: iWARP device.\n+ * @cq_idx: CQ ID. Must be in table bounds.\n+ *\n+ * Context: Atomic (CEQ lock must be held)\n+ */\n+static void irdma_process_normal_ceqe(struct irdma_pci_f *rf,\n+\t\t\t\t      struct irdma_sc_dev *dev, u32 cq_idx)\n+{\n+\t/* cq_idx bounds validated in irdma_sc_process_ceq. */\n+\tstruct irdma_cq *icq = READ_ONCE(rf->cq_table[cq_idx]);\n+\tstruct irdma_sc_cq *cq;\n+\n+\tif (unlikely(!icq)) {\n+\t\t/* Should not happen since CEQ is scrubbed upon CQ delete. */\n+\t\tibdev_warn_ratelimited(to_ibdev(dev), \"Stale CEQE for CQ %u\",\n+\t\t\t\t       cq_idx);\n+\t\treturn;\n+\t}\n+\n+\tcq = &icq->sc_cq;\n+\n+\tif (unlikely(cq->cq_type != IRDMA_CQ_TYPE_IWARP)) {\n+\t\tibdev_warn_ratelimited(to_ibdev(dev), \"Unexpected CQ type %u\",\n+\t\t\t\t       cq->cq_type);\n+\t\treturn;\n+\t}\n+\n+\twritel(cq->cq_uk.cq_id, cq->cq_uk.cq_ack_db);\n+\tirdma_iwarp_ce_handler(cq);\n+}\n+\n+/**\n+ * irdma_process_reserved_ceqe - Handle a CEQE for a reserved CQ.\n+ * @rf: RDMA PCI function.\n+ * @dev: iWARP device.\n+ * @cq_idx: CQ ID.\n+ *\n+ * Context: Atomic\n+ */\n+static void irdma_process_reserved_ceqe(struct irdma_pci_f *rf,\n+\t\t\t\t\tstruct irdma_sc_dev *dev, u32 cq_idx)\n+{\n+\tstruct irdma_sc_cq *cq;\n+\n+\tif (cq_idx == IRDMA_RSVD_CQ_ID_CQP) {\n+\t\tcq = &rf->ccq.sc_cq;\n+\t\t/* CQP CQ lifetime > CEQ. */\n+\t\twritel(cq->cq_uk.cq_id, cq->cq_uk.cq_ack_db);\n+\t\tqueue_work(rf->cqp_cmpl_wq, &rf->cqp_cmpl_work);\n+\t} else if (cq_idx == IRDMA_RSVD_CQ_ID_ILQ ||\n+\t\t   cq_idx == IRDMA_RSVD_CQ_ID_IEQ) {\n+\t\tscoped_guard(spinlock_irqsave, &dev->puda_cq_lock) {\n+\t\t\tcq = (cq_idx == IRDMA_RSVD_CQ_ID_ILQ) ?\n+\t\t\t\tdev->ilq_cq : dev->ieq_cq;\n+\t\t\tif (!cq) {\n+\t\t\t\tibdev_warn_ratelimited(to_ibdev(dev),\n+\t\t\t\t\t\t       \"Stale ILQ/IEQ CEQE\");\n+\t\t\t\treturn;\n+\t\t\t}\n+\t\t\twritel(cq->cq_uk.cq_id, cq->cq_uk.cq_ack_db);\n+\t\t\tirdma_puda_ce_handler(rf, cq);\n+\t\t}\n+\t}\n+}\n+\n /**\n  * irdma_process_ceq - handle ceq for completions\n  * @rf: RDMA PCI function\n@@ -107,28 +175,28 @@ static void irdma_process_ceq(struct irdma_pci_f *rf, struct irdma_ceq *ceq)\n {\n \tstruct irdma_sc_dev *dev = &rf->sc_dev;\n \tstruct irdma_sc_ceq *sc_ceq;\n-\tstruct irdma_sc_cq *cq;\n \tunsigned long flags;\n+\tu32 cq_idx;\n \n \tsc_ceq = &ceq->sc_ceq;\n \tdo {\n \t\tspin_lock_irqsave(&ceq->ce_lock, flags);\n-\t\tcq = irdma_sc_process_ceq(dev, sc_ceq);\n-\t\tif (!cq) {\n+\n+\t\tif (!irdma_sc_process_ceq(dev, sc_ceq, &cq_idx)) {\n \t\t\tspin_unlock_irqrestore(&ceq->ce_lock, flags);\n \t\t\tbreak;\n \t\t}\n \n-\t\tif (cq->cq_type == IRDMA_CQ_TYPE_IWARP)\n-\t\t\tirdma_iwarp_ce_handler(cq);\n+\t\t/* Normal CQs must be handled while holding CEQ lock. */\n+\t\tif (likely(cq_idx > IRDMA_RSVD_CQ_ID_IEQ)) {\n+\t\t\tirdma_process_normal_ceqe(rf, dev, cq_idx);\n+\t\t\tspin_unlock_irqrestore(&ceq->ce_lock, flags);\n+\t\t\tcontinue;\n+\t\t}\n \n \t\tspin_unlock_irqrestore(&ceq->ce_lock, flags);\n \n-\t\tif (cq->cq_type == IRDMA_CQ_TYPE_CQP)\n-\t\t\tqueue_work(rf->cqp_cmpl_wq, &rf->cqp_cmpl_work);\n-\t\telse if (cq->cq_type == IRDMA_CQ_TYPE_ILQ ||\n-\t\t\t cq->cq_type == IRDMA_CQ_TYPE_IEQ)\n-\t\t\tirdma_puda_ce_handler(rf, cq);\n+\t\tirdma_process_reserved_ceqe(rf, dev, cq_idx);\n \t} while (1);\n }\n \ndiff --git a/drivers/infiniband/hw/irdma/puda.c b/drivers/infiniband/hw/irdma/puda.c\nindex cee47ddbd1b5..4f1a8c97faf1 100644\n--- a/drivers/infiniband/hw/irdma/puda.c\n+++ b/drivers/infiniband/hw/irdma/puda.c\n@@ -809,6 +809,13 @@ static int irdma_puda_cq_create(struct irdma_puda_rsrc *rsrc)\n \t\tdma_free_coherent(dev->hw->device, rsrc->cqmem.size,\n \t\t\t\t  rsrc->cqmem.va, rsrc->cqmem.pa);\n \t\trsrc->cqmem.va = NULL;\n+\t} else {\n+\t\tscoped_guard(spinlock_irqsave, &dev->puda_cq_lock) {\n+\t\t\tif (rsrc->type == IRDMA_PUDA_RSRC_TYPE_ILQ)\n+\t\t\t\tdev->ilq_cq = cq;\n+\t\t\telse\n+\t\t\t\tdev->ieq_cq = cq;\n+\t\t}\n \t}\n \n \treturn ret;\n@@ -856,6 +863,13 @@ static void irdma_puda_free_cq(struct irdma_puda_rsrc *rsrc)\n \tstruct irdma_ccq_cqe_info compl_info;\n \tstruct irdma_sc_dev *dev = rsrc->dev;\n \n+\tscoped_guard(spinlock_irqsave, &dev->puda_cq_lock) {\n+\t\tif (rsrc->type == IRDMA_PUDA_RSRC_TYPE_ILQ)\n+\t\t\tdev->ilq_cq = NULL;\n+\t\telse\n+\t\t\tdev->ieq_cq = NULL;\n+\t}\n+\n \tif (rsrc->dev->ceq_valid) {\n \t\tirdma_cqp_cq_destroy_cmd(dev, &rsrc->cq);\n \t\treturn;\ndiff --git a/drivers/infiniband/hw/irdma/type.h b/drivers/infiniband/hw/irdma/type.h\nindex 3de9240b727f..da8c54d1f035 100644\n--- a/drivers/infiniband/hw/irdma/type.h\n+++ b/drivers/infiniband/hw/irdma/type.h\n@@ -707,6 +707,9 @@ struct irdma_sc_dev {\n \tstruct irdma_sc_aeq *aeq;\n \tstruct irdma_sc_ceq *ceq[IRDMA_CEQ_MAX_COUNT];\n \tstruct irdma_sc_cq *ccq;\n+\tspinlock_t puda_cq_lock;\n+\tstruct irdma_sc_cq *ilq_cq;\n+\tstruct irdma_sc_cq *ieq_cq;\n \tconst struct irdma_irq_ops *irq_ops;\n \tstruct irdma_qos qos[IRDMA_MAX_USER_PRIORITY];\n \tstruct irdma_hmc_fpm_misc hmc_fpm_misc;\n@@ -1344,7 +1347,8 @@ int irdma_sc_ceq_destroy(struct irdma_sc_ceq *ceq, u64 scratch, bool post_sq);\n int irdma_sc_ceq_init(struct irdma_sc_ceq *ceq,\n \t\t      struct irdma_ceq_init_info *info);\n void irdma_sc_cleanup_ceqes(struct irdma_sc_cq *cq, struct irdma_sc_ceq *ceq);\n-void *irdma_sc_process_ceq(struct irdma_sc_dev *dev, struct irdma_sc_ceq *ceq);\n+bool irdma_sc_process_ceq(struct irdma_sc_dev *dev, struct irdma_sc_ceq *ceq,\n+\t\t\t  u32 *cq_idx);\n \n int irdma_sc_aeq_init(struct irdma_sc_aeq *aeq,\n \t\t      struct irdma_aeq_init_info *info);\ndiff --git a/drivers/infiniband/hw/irdma/utils.c b/drivers/infiniband/hw/irdma/utils.c\nindex a1d9ebe4f731..90aeb687b1c5 100644\n--- a/drivers/infiniband/hw/irdma/utils.c\n+++ b/drivers/infiniband/hw/irdma/utils.c\n@@ -829,7 +829,8 @@ void irdma_cq_rem_ref(struct ib_cq *ibcq)\n \t\treturn;\n \t}\n \n-\tiwdev->rf->cq_table[iwcq->cq_num] = NULL;\n+\t/* May be asynchronously sampled by CEQ ISR without holding tbl lock. */\n+\tWRITE_ONCE(iwdev->rf->cq_table[iwcq->cq_num], NULL);\n \tspin_unlock_irqrestore(&iwdev->rf->cqtable_lock, flags);\n \tcomplete(&iwcq->free_cq);\n }\ndiff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c\nindex 5e098215d1c0..ee08d97e56f1 100644\n--- a/drivers/infiniband/hw/irdma/verbs.c\n+++ b/drivers/infiniband/hw/irdma/verbs.c\n@@ -2658,9 +2658,12 @@ static int irdma_create_cq(struct ib_cq *ibcq,\n \t\t\tgoto cq_destroy;\n \t\t}\n \t}\n-\trf->cq_table[cq_num] = iwcq;\n+\n \tinit_completion(&iwcq->free_cq);\n \n+\t/* Populate table entry after CQ is fully created. */\n+\tsmp_store_release(&rf->cq_table[cq_num], iwcq);\n+\n \treturn 0;\n cq_destroy:\n \tirdma_cq_wq_destroy(rf, cq);\n",
    "prefixes": [
        "SRU",
        "Q:linux-gcp",
        "6/6"
    ]
}