]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
RDMA/hns: Fix RoCEv1 failure due to DSCP
authorJunxian Huang <huangjunxian6@hisilicon.com>
Sun, 4 Jan 2026 06:40:56 +0000 (14:40 +0800)
committerLeon Romanovsky <leon@kernel.org>
Sun, 4 Jan 2026 15:09:51 +0000 (10:09 -0500)
DSCP is not supported in RoCEv1, but get_dscp() is still called. If
get_dscp() returns an error, it'll eventually cause create_ah to fail
even when using RoCEv1.

Correct the return value and avoid calling get_dscp() when using
RoCEv1.

Fixes: ee20cc17e9d8 ("RDMA/hns: Support DSCP")
Signed-off-by: Junxian Huang <huangjunxian6@hisilicon.com>
Link: https://patch.msgid.link/20260104064057.1582216-4-huangjunxian6@hisilicon.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
drivers/infiniband/hw/hns/hns_roce_ah.c
drivers/infiniband/hw/hns/hns_roce_hw_v2.c

index 0c1c32d23c8848c51f5557b6bef8fc0659e8f4ba..8a605da8a93c972ac2cb1209e123747e635853e8 100644 (file)
@@ -60,7 +60,7 @@ int hns_roce_create_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *init_attr,
        u8 tclass = get_tclass(grh);
        u8 priority = 0;
        u8 tc_mode = 0;
-       int ret;
+       int ret = 0;
 
        if (hr_dev->pci_dev->revision == PCI_REVISION_ID_HIP08 && udata) {
                ret = -EOPNOTSUPP;
@@ -77,19 +77,18 @@ int hns_roce_create_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *init_attr,
        ah->av.flowlabel = grh->flow_label;
        ah->av.udp_sport = get_ah_udp_sport(ah_attr);
        ah->av.tclass = tclass;
+       ah->av.sl = rdma_ah_get_sl(ah_attr);
 
-       ret = hr_dev->hw->get_dscp(hr_dev, tclass, &tc_mode, &priority);
-       if (ret == -EOPNOTSUPP)
-               ret = 0;
-
-       if (ret && grh->sgid_attr->gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP)
-               goto err_out;
+       if (grh->sgid_attr->gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP) {
+               ret = hr_dev->hw->get_dscp(hr_dev, tclass, &tc_mode, &priority);
+               if (ret == -EOPNOTSUPP)
+                       ret = 0;
+               else if (ret)
+                       goto err_out;
 
-       if (tc_mode == HNAE3_TC_MAP_MODE_DSCP &&
-           grh->sgid_attr->gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP)
-               ah->av.sl = priority;
-       else
-               ah->av.sl = rdma_ah_get_sl(ah_attr);
+               if (tc_mode == HNAE3_TC_MAP_MODE_DSCP)
+                       ah->av.sl = priority;
+       }
 
        if (!check_sl_valid(hr_dev, ah->av.sl)) {
                ret = -EINVAL;
index f95442798ddb3f42120bf6d181da73c7e98095c3..1f37d74b466b555bfe898f7a8bc11cda1375631e 100644 (file)
@@ -5053,20 +5053,22 @@ static int hns_roce_set_sl(struct ib_qp *ibqp,
        struct ib_device *ibdev = &hr_dev->ib_dev;
        int ret;
 
-       ret = hns_roce_hw_v2_get_dscp(hr_dev, get_tclass(&attr->ah_attr.grh),
-                                     &hr_qp->tc_mode, &hr_qp->priority);
-       if (ret && ret != -EOPNOTSUPP &&
-           grh->sgid_attr->gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP) {
-               ibdev_err_ratelimited(ibdev,
-                                     "failed to get dscp, ret = %d.\n", ret);
-               return ret;
-       }
+       hr_qp->sl = rdma_ah_get_sl(&attr->ah_attr);
 
-       if (hr_qp->tc_mode == HNAE3_TC_MAP_MODE_DSCP &&
-           grh->sgid_attr->gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP)
-               hr_qp->sl = hr_qp->priority;
-       else
-               hr_qp->sl = rdma_ah_get_sl(&attr->ah_attr);
+       if (grh->sgid_attr->gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP) {
+               ret = hns_roce_hw_v2_get_dscp(hr_dev,
+                                             get_tclass(&attr->ah_attr.grh),
+                                             &hr_qp->tc_mode, &hr_qp->priority);
+               if (ret && ret != -EOPNOTSUPP) {
+                       ibdev_err_ratelimited(ibdev,
+                                             "failed to get dscp, ret = %d.\n",
+                                             ret);
+                       return ret;
+               }
+
+               if (hr_qp->tc_mode == HNAE3_TC_MAP_MODE_DSCP)
+                       hr_qp->sl = hr_qp->priority;
+       }
 
        if (!check_sl_valid(hr_dev, hr_qp->sl))
                return -EINVAL;