]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
RDMA/hns: Notify ULP of remaining soft-WCs during reset
authorChengchang Tang <tangchengchang@huawei.com>
Sun, 4 Jan 2026 06:40:57 +0000 (14:40 +0800)
committerLeon Romanovsky <leon@kernel.org>
Sun, 4 Jan 2026 15:09:51 +0000 (10:09 -0500)
During a reset, software-generated WCs cannot be reported via
interrupts. This may cause the ULP to miss some WCs.

To avoid this, add check in the CQ arm process: if a hardware reset
has occurred and there are still unreported soft-WCs, notify the ULP
to handle the remaining WCs, thereby preventing any loss of completions.

Fixes: 626903e9355b ("RDMA/hns: Add support for reporting wc as software mode")
Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
Signed-off-by: Junxian Huang <huangjunxian6@hisilicon.com>
Link: https://patch.msgid.link/20260104064057.1582216-5-huangjunxian6@hisilicon.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
drivers/infiniband/hw/hns/hns_roce_hw_v2.c

index 1f37d74b466b555bfe898f7a8bc11cda1375631e..a2ae4f33e459f3a49f90225446bac2ff749b374d 100644 (file)
@@ -3739,6 +3739,23 @@ static void hns_roce_v2_write_cqc(struct hns_roce_dev *hr_dev,
                     HNS_ROCE_V2_CQ_DEFAULT_INTERVAL);
 }
 
+static bool left_sw_wc(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq)
+{
+       struct hns_roce_qp *hr_qp;
+
+       list_for_each_entry(hr_qp, &hr_cq->sq_list, sq_node) {
+               if (hr_qp->sq.head != hr_qp->sq.tail)
+                       return true;
+       }
+
+       list_for_each_entry(hr_qp, &hr_cq->rq_list, rq_node) {
+               if (hr_qp->rq.head != hr_qp->rq.tail)
+                       return true;
+       }
+
+       return false;
+}
+
 static int hns_roce_v2_req_notify_cq(struct ib_cq *ibcq,
                                     enum ib_cq_notify_flags flags)
 {
@@ -3747,6 +3764,12 @@ static int hns_roce_v2_req_notify_cq(struct ib_cq *ibcq,
        struct hns_roce_v2_db cq_db = {};
        u32 notify_flag;
 
+       if (hr_dev->state >= HNS_ROCE_DEVICE_STATE_RST_DOWN) {
+               if ((flags & IB_CQ_REPORT_MISSED_EVENTS) &&
+                   left_sw_wc(hr_dev, hr_cq))
+                       return 1;
+               return 0;
+       }
        /*
         * flags = 0, then notify_flag : next
         * flags = 1, then notify flag : solocited