Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

RDMA/irdma: Add GEN3 virtual QP1 support

Add a new RDMA virtual channel op during QP1 creation that allow the
Control Plane (CP) to virtualize a regular QP as QP1 on non-default
RDMA capable vPorts. Additionally, the CP will return the Qsets to use
on the ib_device of the vPort.

Signed-off-by: Shiraz Saleem <shiraz.saleem@intel.com>
Signed-off-by: Tatyana Nikolova <tatyana.e.nikolova@intel.com>
Link: https://patch.msgid.link/20250827152545.2056-9-tatyana.e.nikolova@intel.com
Tested-by: Jacob Moroni <jmoroni@google.com>
Signed-off-by: Leon Romanovsky <leon@kernel.org>

authored by

Shiraz Saleem and committed by
Leon Romanovsky
d6ed4b69 2ad49ae7

+174 -22
+9 -1
drivers/infiniband/hw/irdma/ctrl.c
··· 74 74 { 75 75 u8 i; 76 76 77 + if (vsi->dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_3) { 78 + for (i = 0; i < IRDMA_MAX_USER_PRIORITY; i++) { 79 + vsi->qos[i].qs_handle = vsi->dev->qos[i].qs_handle; 80 + vsi->qos[i].valid = true; 81 + } 82 + 83 + return; 84 + } 77 85 vsi->qos_rel_bw = l2p->vsi_rel_bw; 78 86 vsi->qos_prio_type = l2p->vsi_prio_type; 79 87 vsi->dscp_mode = l2p->dscp_mode; ··· 1885 1877 mutex_init(&vsi->qos[i].qos_mutex); 1886 1878 INIT_LIST_HEAD(&vsi->qos[i].qplist); 1887 1879 } 1888 - if (vsi->register_qset) { 1880 + if (vsi->dev->hw_attrs.uk_attrs.hw_rev == IRDMA_GEN_2) { 1889 1881 vsi->dev->ws_add = irdma_ws_add; 1890 1882 vsi->dev->ws_remove = irdma_ws_remove; 1891 1883 vsi->dev->ws_reset = irdma_ws_reset;
+1
drivers/infiniband/hw/irdma/main.h
··· 260 260 bool reset:1; 261 261 bool rsrc_created:1; 262 262 bool msix_shared:1; 263 + bool hwqp1_rsvd:1; 263 264 u8 rsrc_profile; 264 265 u8 *hmc_info_mem; 265 266 u8 *mem_rsrc;
+27 -3
drivers/infiniband/hw/irdma/utils.c
··· 1113 1113 irdma_put_cqp_request(&rf->cqp, cqp_request); 1114 1114 } 1115 1115 1116 + static void irdma_free_gsi_qp_rsrc(struct irdma_qp *iwqp, u32 qp_num) 1117 + { 1118 + struct irdma_device *iwdev = iwqp->iwdev; 1119 + struct irdma_pci_f *rf = iwdev->rf; 1120 + unsigned long flags; 1121 + 1122 + if (rf->sc_dev.hw_attrs.uk_attrs.hw_rev < IRDMA_GEN_3) 1123 + return; 1124 + 1125 + irdma_vchnl_req_del_vport(&rf->sc_dev, iwdev->vport_id, qp_num); 1126 + 1127 + if (qp_num == 1) { 1128 + spin_lock_irqsave(&rf->rsrc_lock, flags); 1129 + rf->hwqp1_rsvd = false; 1130 + spin_unlock_irqrestore(&rf->rsrc_lock, flags); 1131 + } else if (qp_num > 2) { 1132 + irdma_free_rsrc(rf, rf->allocated_qps, qp_num); 1133 + } 1134 + } 1135 + 1116 1136 /** 1117 1137 * irdma_free_qp_rsrc - free up memory resources for qp 1118 1138 * @iwqp: qp ptr (user or kernel) ··· 1141 1121 { 1142 1122 struct irdma_device *iwdev = iwqp->iwdev; 1143 1123 struct irdma_pci_f *rf = iwdev->rf; 1144 - u32 qp_num = iwqp->ibqp.qp_num; 1124 + u32 qp_num = iwqp->sc_qp.qp_uk.qp_id; 1145 1125 1146 1126 irdma_ieq_cleanup_qp(iwdev->vsi.ieq, &iwqp->sc_qp); 1147 1127 irdma_dealloc_push_page(rf, &iwqp->sc_qp); ··· 1151 1131 iwqp->sc_qp.user_pri); 1152 1132 } 1153 1133 1154 - if (qp_num > 2) 1155 - irdma_free_rsrc(rf, rf->allocated_qps, qp_num); 1134 + if (iwqp->ibqp.qp_type == IB_QPT_GSI) { 1135 + irdma_free_gsi_qp_rsrc(iwqp, qp_num); 1136 + } else { 1137 + if (qp_num > 2) 1138 + irdma_free_rsrc(rf, rf->allocated_qps, qp_num); 1139 + } 1156 1140 dma_free_coherent(rf->sc_dev.hw->device, iwqp->q2_ctx_mem.size, 1157 1141 iwqp->q2_ctx_mem.va, iwqp->q2_ctx_mem.pa); 1158 1142 iwqp->q2_ctx_mem.va = NULL;
+66 -18
drivers/infiniband/hw/irdma/verbs.c
··· 545 545 irdma_cqp_qp_destroy_cmd(&iwdev->rf->sc_dev, &iwqp->sc_qp); 546 546 547 547 irdma_remove_push_mmap_entries(iwqp); 548 + 549 + if (iwqp->sc_qp.qp_uk.qp_id == 1) 550 + iwdev->rf->hwqp1_rsvd = false; 548 551 irdma_free_qp_rsrc(iwqp); 549 552 550 553 return 0; ··· 726 723 info->rq_pa + (ukinfo->rq_depth * IRDMA_QP_WQE_MIN_SIZE); 727 724 ukinfo->sq_size = ukinfo->sq_depth >> ukinfo->sq_shift; 728 725 ukinfo->rq_size = ukinfo->rq_depth >> ukinfo->rq_shift; 726 + ukinfo->qp_id = info->qp_uk_init_info.qp_id; 729 727 730 728 iwqp->max_send_wr = (ukinfo->sq_depth - IRDMA_SQ_RSVD) >> ukinfo->sq_shift; 731 729 iwqp->max_recv_wr = (ukinfo->rq_depth - IRDMA_RQ_RSVD) >> ukinfo->rq_shift; ··· 783 779 roce_info = &iwqp->roce_info; 784 780 ether_addr_copy(roce_info->mac_addr, iwdev->netdev->dev_addr); 785 781 782 + if (iwqp->ibqp.qp_type == IB_QPT_GSI && iwqp->ibqp.qp_num != 1) 783 + roce_info->is_qp1 = true; 786 784 roce_info->rd_en = true; 787 785 roce_info->wr_rdresp_en = true; 788 786 roce_info->bind_en = true; ··· 874 868 irdma_generate_flush_completions(iwqp); 875 869 } 876 870 871 + static int irdma_setup_gsi_qp_rsrc(struct irdma_qp *iwqp, u32 *qp_num) 872 + { 873 + struct irdma_device *iwdev = iwqp->iwdev; 874 + struct irdma_pci_f *rf = iwdev->rf; 875 + unsigned long flags; 876 + int ret; 877 + 878 + if (rf->rdma_ver <= IRDMA_GEN_2) { 879 + *qp_num = 1; 880 + return 0; 881 + } 882 + 883 + spin_lock_irqsave(&rf->rsrc_lock, flags); 884 + if (!rf->hwqp1_rsvd) { 885 + *qp_num = 1; 886 + rf->hwqp1_rsvd = true; 887 + spin_unlock_irqrestore(&rf->rsrc_lock, flags); 888 + } else { 889 + spin_unlock_irqrestore(&rf->rsrc_lock, flags); 890 + ret = irdma_alloc_rsrc(rf, rf->allocated_qps, rf->max_qp, 891 + qp_num, &rf->next_qp); 892 + if (ret) 893 + return ret; 894 + } 895 + 896 + ret = irdma_vchnl_req_add_vport(&rf->sc_dev, iwdev->vport_id, *qp_num, 897 + (&iwdev->vsi)->qos); 898 + if (ret) { 899 + if (*qp_num != 1) { 900 + irdma_free_rsrc(rf, rf->allocated_qps, *qp_num); 901 + } else { 902 + spin_lock_irqsave(&rf->rsrc_lock, flags); 903 + rf->hwqp1_rsvd = false; 904 + spin_unlock_irqrestore(&rf->rsrc_lock, flags); 905 + } 906 + return ret; 907 + } 908 + 909 + return 0; 910 + } 911 + 877 912 /** 878 913 * irdma_create_qp - create qp 879 914 * @ibqp: ptr of qp ··· 976 929 init_info.host_ctx = (__le64 *)(init_info.q2 + IRDMA_Q2_BUF_SIZE); 977 930 init_info.host_ctx_pa = init_info.q2_pa + IRDMA_Q2_BUF_SIZE; 978 931 979 - if (init_attr->qp_type == IB_QPT_GSI) 980 - qp_num = 1; 981 - else 932 + if (init_attr->qp_type == IB_QPT_GSI) { 933 + err_code = irdma_setup_gsi_qp_rsrc(iwqp, &qp_num); 934 + if (err_code) 935 + goto error; 936 + iwqp->ibqp.qp_num = 1; 937 + } else { 982 938 err_code = irdma_alloc_rsrc(rf, rf->allocated_qps, rf->max_qp, 983 939 &qp_num, &rf->next_qp); 984 - if (err_code) 985 - goto error; 940 + if (err_code) 941 + goto error; 942 + iwqp->ibqp.qp_num = qp_num; 943 + } 986 944 987 945 iwqp->iwpd = iwpd; 988 - iwqp->ibqp.qp_num = qp_num; 989 946 qp = &iwqp->sc_qp; 990 947 iwqp->iwscq = to_iwcq(init_attr->send_cq); 991 948 iwqp->iwrcq = to_iwcq(init_attr->recv_cq); ··· 1049 998 ctx_info->send_cq_num = iwqp->iwscq->sc_cq.cq_uk.cq_id; 1050 999 ctx_info->rcv_cq_num = iwqp->iwrcq->sc_cq.cq_uk.cq_id; 1051 1000 1052 - if (rdma_protocol_roce(&iwdev->ibdev, 1)) 1001 + if (rdma_protocol_roce(&iwdev->ibdev, 1)) { 1002 + if (dev->ws_add(&iwdev->vsi, 0)) { 1003 + irdma_cqp_qp_destroy_cmd(&rf->sc_dev, &iwqp->sc_qp); 1004 + err_code = -EINVAL; 1005 + goto error; 1006 + } 1007 + irdma_qp_add_qos(&iwqp->sc_qp); 1053 1008 irdma_roce_fill_and_set_qpctx_info(iwqp, ctx_info); 1054 - else 1009 + } else { 1055 1010 irdma_iw_fill_and_set_qpctx_info(iwqp, ctx_info); 1011 + } 1056 1012 1057 1013 err_code = irdma_cqp_create_qp_cmd(iwqp); 1058 1014 if (err_code) ··· 1070 1012 spin_lock_init(&iwqp->sc_qp.pfpdu.lock); 1071 1013 iwqp->sig_all = init_attr->sq_sig_type == IB_SIGNAL_ALL_WR; 1072 1014 rf->qp_table[qp_num] = iwqp; 1073 - 1074 - if (rdma_protocol_roce(&iwdev->ibdev, 1)) { 1075 - if (dev->ws_add(&iwdev->vsi, 0)) { 1076 - irdma_cqp_qp_destroy_cmd(&rf->sc_dev, &iwqp->sc_qp); 1077 - err_code = -EINVAL; 1078 - goto error; 1079 - } 1080 - 1081 - irdma_qp_add_qos(&iwqp->sc_qp); 1082 - } 1083 1015 1084 1016 if (udata) { 1085 1017 /* GEN_1 legacy support with libi40iw does not have expanded uresp struct */
+52
drivers/infiniband/hw/irdma/virtchnl.c
··· 112 112 case IRDMA_VCHNL_OP_GET_REG_LAYOUT: 113 113 case IRDMA_VCHNL_OP_QUEUE_VECTOR_MAP: 114 114 case IRDMA_VCHNL_OP_QUEUE_VECTOR_UNMAP: 115 + case IRDMA_VCHNL_OP_ADD_VPORT: 116 + case IRDMA_VCHNL_OP_DEL_VPORT: 115 117 break; 116 118 default: 117 119 return -EOPNOTSUPP; ··· 317 315 } 318 316 319 317 return 0; 318 + } 319 + 320 + int irdma_vchnl_req_add_vport(struct irdma_sc_dev *dev, u16 vport_id, 321 + u32 qp1_id, struct irdma_qos *qos) 322 + { 323 + struct irdma_vchnl_resp_vport_info resp_vport = { 0 }; 324 + struct irdma_vchnl_req_vport_info req_vport = { 0 }; 325 + struct irdma_vchnl_req_init_info info = { 0 }; 326 + int ret, i; 327 + 328 + if (!dev->vchnl_up) 329 + return -EBUSY; 330 + 331 + info.op_code = IRDMA_VCHNL_OP_ADD_VPORT; 332 + info.op_ver = IRDMA_VCHNL_OP_ADD_VPORT_V0; 333 + req_vport.vport_id = vport_id; 334 + req_vport.qp1_id = qp1_id; 335 + info.req_parm_len = sizeof(req_vport); 336 + info.req_parm = &req_vport; 337 + info.resp_parm = &resp_vport; 338 + info.resp_parm_len = sizeof(resp_vport); 339 + 340 + ret = irdma_vchnl_req_send_sync(dev, &info); 341 + if (ret) 342 + return ret; 343 + 344 + for (i = 0; i < IRDMA_MAX_USER_PRIORITY; i++) { 345 + qos[i].qs_handle = resp_vport.qs_handle[i]; 346 + qos[i].valid = true; 347 + } 348 + 349 + return 0; 350 + } 351 + 352 + int irdma_vchnl_req_del_vport(struct irdma_sc_dev *dev, u16 vport_id, u32 qp1_id) 353 + { 354 + struct irdma_vchnl_req_init_info info = { 0 }; 355 + struct irdma_vchnl_req_vport_info req_vport = { 0 }; 356 + 357 + if (!dev->vchnl_up) 358 + return -EBUSY; 359 + 360 + info.op_code = IRDMA_VCHNL_OP_DEL_VPORT; 361 + info.op_ver = IRDMA_VCHNL_OP_DEL_VPORT_V0; 362 + req_vport.vport_id = vport_id; 363 + req_vport.qp1_id = qp1_id; 364 + info.req_parm_len = sizeof(req_vport); 365 + info.req_parm = &req_vport; 366 + 367 + return irdma_vchnl_req_send_sync(dev, &info); 320 368 } 321 369 322 370 /**
+19
drivers/infiniband/hw/irdma/virtchnl.h
··· 17 17 #define IRDMA_VCHNL_OP_GET_REG_LAYOUT_V0 0 18 18 #define IRDMA_VCHNL_OP_QUEUE_VECTOR_MAP_V0 0 19 19 #define IRDMA_VCHNL_OP_QUEUE_VECTOR_UNMAP_V0 0 20 + #define IRDMA_VCHNL_OP_ADD_VPORT_V0 0 21 + #define IRDMA_VCHNL_OP_DEL_VPORT_V0 0 20 22 #define IRDMA_VCHNL_OP_GET_RDMA_CAPS_V0 0 21 23 #define IRDMA_VCHNL_OP_GET_RDMA_CAPS_MIN_SIZE 1 22 24 ··· 59 57 IRDMA_VCHNL_OP_GET_RDMA_CAPS = 13, 60 58 IRDMA_VCHNL_OP_QUEUE_VECTOR_MAP = 14, 61 59 IRDMA_VCHNL_OP_QUEUE_VECTOR_UNMAP = 15, 60 + IRDMA_VCHNL_OP_ADD_VPORT = 16, 61 + IRDMA_VCHNL_OP_DEL_VPORT = 17, 62 62 }; 63 63 64 64 struct irdma_vchnl_req_hmc_info { ··· 83 79 struct irdma_vchnl_qvlist_info { 84 80 u32 num_vectors; 85 81 struct irdma_vchnl_qv_info qv_info[]; 82 + }; 83 + 84 + struct irdma_vchnl_req_vport_info { 85 + u16 vport_id; 86 + u32 qp1_id; 87 + }; 88 + 89 + struct irdma_vchnl_resp_vport_info { 90 + u16 qs_handle[IRDMA_MAX_USER_PRIORITY]; 86 91 }; 87 92 88 93 struct irdma_vchnl_op_buf { ··· 154 141 u16 op_ver; 155 142 } __packed; 156 143 144 + struct irdma_qos; 145 + 157 146 int irdma_sc_vchnl_init(struct irdma_sc_dev *dev, 158 147 struct irdma_vchnl_init_info *info); 159 148 int irdma_vchnl_req_get_ver(struct irdma_sc_dev *dev, u16 ver_req, ··· 169 154 int irdma_vchnl_req_aeq_vec_map(struct irdma_sc_dev *dev, u32 v_idx); 170 155 int irdma_vchnl_req_ceq_vec_map(struct irdma_sc_dev *dev, u16 ceq_id, 171 156 u32 v_idx); 157 + int irdma_vchnl_req_add_vport(struct irdma_sc_dev *dev, u16 vport_id, 158 + u32 qp1_id, struct irdma_qos *qos); 159 + int irdma_vchnl_req_del_vport(struct irdma_sc_dev *dev, u16 vport_id, 160 + u32 qp1_id); 172 161 #endif /* IRDMA_VIRTCHNL_H */