Skip to content

Commit d6ed4b6

Browse files
shirazsaleemrleon
authored andcommitted
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>
1 parent 2ad49ae commit d6ed4b6

6 files changed

Lines changed: 174 additions & 22 deletions

File tree

drivers/infiniband/hw/irdma/ctrl.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,14 @@ static void irdma_set_qos_info(struct irdma_sc_vsi *vsi,
7474
{
7575
u8 i;
7676

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+
}
7785
vsi->qos_rel_bw = l2p->vsi_rel_bw;
7886
vsi->qos_prio_type = l2p->vsi_prio_type;
7987
vsi->dscp_mode = l2p->dscp_mode;
@@ -1877,7 +1885,7 @@ void irdma_sc_vsi_init(struct irdma_sc_vsi *vsi,
18771885
mutex_init(&vsi->qos[i].qos_mutex);
18781886
INIT_LIST_HEAD(&vsi->qos[i].qplist);
18791887
}
1880-
if (vsi->register_qset) {
1888+
if (vsi->dev->hw_attrs.uk_attrs.hw_rev == IRDMA_GEN_2) {
18811889
vsi->dev->ws_add = irdma_ws_add;
18821890
vsi->dev->ws_remove = irdma_ws_remove;
18831891
vsi->dev->ws_reset = irdma_ws_reset;

drivers/infiniband/hw/irdma/main.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ struct irdma_pci_f {
260260
bool reset:1;
261261
bool rsrc_created:1;
262262
bool msix_shared:1;
263+
bool hwqp1_rsvd:1;
263264
u8 rsrc_profile;
264265
u8 *hmc_info_mem;
265266
u8 *mem_rsrc;

drivers/infiniband/hw/irdma/utils.c

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,6 +1113,26 @@ static void irdma_dealloc_push_page(struct irdma_pci_f *rf,
11131113
irdma_put_cqp_request(&rf->cqp, cqp_request);
11141114
}
11151115

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+
11161136
/**
11171137
* irdma_free_qp_rsrc - free up memory resources for qp
11181138
* @iwqp: qp ptr (user or kernel)
@@ -1121,7 +1141,7 @@ void irdma_free_qp_rsrc(struct irdma_qp *iwqp)
11211141
{
11221142
struct irdma_device *iwdev = iwqp->iwdev;
11231143
struct irdma_pci_f *rf = iwdev->rf;
1124-
u32 qp_num = iwqp->ibqp.qp_num;
1144+
u32 qp_num = iwqp->sc_qp.qp_uk.qp_id;
11251145

11261146
irdma_ieq_cleanup_qp(iwdev->vsi.ieq, &iwqp->sc_qp);
11271147
irdma_dealloc_push_page(rf, &iwqp->sc_qp);
@@ -1131,8 +1151,12 @@ void irdma_free_qp_rsrc(struct irdma_qp *iwqp)
11311151
iwqp->sc_qp.user_pri);
11321152
}
11331153

1134-
if (qp_num > 2)
1135-
irdma_free_rsrc(rf, rf->allocated_qps, qp_num);
1154+
if (iwqp->ibqp.qp_type == IB_QPT_GSI) {
1155+
irdma_free_gsi_qp_rsrc(iwqp, qp_num);
1156+
} else {
1157+
if (qp_num > 2)
1158+
irdma_free_rsrc(rf, rf->allocated_qps, qp_num);
1159+
}
11361160
dma_free_coherent(rf->sc_dev.hw->device, iwqp->q2_ctx_mem.size,
11371161
iwqp->q2_ctx_mem.va, iwqp->q2_ctx_mem.pa);
11381162
iwqp->q2_ctx_mem.va = NULL;

drivers/infiniband/hw/irdma/verbs.c

Lines changed: 66 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,9 @@ static int irdma_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata)
545545
irdma_cqp_qp_destroy_cmd(&iwdev->rf->sc_dev, &iwqp->sc_qp);
546546

547547
irdma_remove_push_mmap_entries(iwqp);
548+
549+
if (iwqp->sc_qp.qp_uk.qp_id == 1)
550+
iwdev->rf->hwqp1_rsvd = false;
548551
irdma_free_qp_rsrc(iwqp);
549552

550553
return 0;
@@ -723,6 +726,7 @@ static int irdma_setup_kmode_qp(struct irdma_device *iwdev,
723726
info->rq_pa + (ukinfo->rq_depth * IRDMA_QP_WQE_MIN_SIZE);
724727
ukinfo->sq_size = ukinfo->sq_depth >> ukinfo->sq_shift;
725728
ukinfo->rq_size = ukinfo->rq_depth >> ukinfo->rq_shift;
729+
ukinfo->qp_id = info->qp_uk_init_info.qp_id;
726730

727731
iwqp->max_send_wr = (ukinfo->sq_depth - IRDMA_SQ_RSVD) >> ukinfo->sq_shift;
728732
iwqp->max_recv_wr = (ukinfo->rq_depth - IRDMA_RQ_RSVD) >> ukinfo->rq_shift;
@@ -779,6 +783,8 @@ static void irdma_roce_fill_and_set_qpctx_info(struct irdma_qp *iwqp,
779783
roce_info = &iwqp->roce_info;
780784
ether_addr_copy(roce_info->mac_addr, iwdev->netdev->dev_addr);
781785

786+
if (iwqp->ibqp.qp_type == IB_QPT_GSI && iwqp->ibqp.qp_num != 1)
787+
roce_info->is_qp1 = true;
782788
roce_info->rd_en = true;
783789
roce_info->wr_rdresp_en = true;
784790
roce_info->bind_en = true;
@@ -868,6 +874,47 @@ static void irdma_flush_worker(struct work_struct *work)
868874
irdma_generate_flush_completions(iwqp);
869875
}
870876

877+
static int irdma_setup_gsi_qp_rsrc(struct irdma_qp *iwqp, u32 *qp_num)
878+
{
879+
struct irdma_device *iwdev = iwqp->iwdev;
880+
struct irdma_pci_f *rf = iwdev->rf;
881+
unsigned long flags;
882+
int ret;
883+
884+
if (rf->rdma_ver <= IRDMA_GEN_2) {
885+
*qp_num = 1;
886+
return 0;
887+
}
888+
889+
spin_lock_irqsave(&rf->rsrc_lock, flags);
890+
if (!rf->hwqp1_rsvd) {
891+
*qp_num = 1;
892+
rf->hwqp1_rsvd = true;
893+
spin_unlock_irqrestore(&rf->rsrc_lock, flags);
894+
} else {
895+
spin_unlock_irqrestore(&rf->rsrc_lock, flags);
896+
ret = irdma_alloc_rsrc(rf, rf->allocated_qps, rf->max_qp,
897+
qp_num, &rf->next_qp);
898+
if (ret)
899+
return ret;
900+
}
901+
902+
ret = irdma_vchnl_req_add_vport(&rf->sc_dev, iwdev->vport_id, *qp_num,
903+
(&iwdev->vsi)->qos);
904+
if (ret) {
905+
if (*qp_num != 1) {
906+
irdma_free_rsrc(rf, rf->allocated_qps, *qp_num);
907+
} else {
908+
spin_lock_irqsave(&rf->rsrc_lock, flags);
909+
rf->hwqp1_rsvd = false;
910+
spin_unlock_irqrestore(&rf->rsrc_lock, flags);
911+
}
912+
return ret;
913+
}
914+
915+
return 0;
916+
}
917+
871918
/**
872919
* irdma_create_qp - create qp
873920
* @ibqp: ptr of qp
@@ -929,16 +976,20 @@ static int irdma_create_qp(struct ib_qp *ibqp,
929976
init_info.host_ctx = (__le64 *)(init_info.q2 + IRDMA_Q2_BUF_SIZE);
930977
init_info.host_ctx_pa = init_info.q2_pa + IRDMA_Q2_BUF_SIZE;
931978

932-
if (init_attr->qp_type == IB_QPT_GSI)
933-
qp_num = 1;
934-
else
979+
if (init_attr->qp_type == IB_QPT_GSI) {
980+
err_code = irdma_setup_gsi_qp_rsrc(iwqp, &qp_num);
981+
if (err_code)
982+
goto error;
983+
iwqp->ibqp.qp_num = 1;
984+
} else {
935985
err_code = irdma_alloc_rsrc(rf, rf->allocated_qps, rf->max_qp,
936986
&qp_num, &rf->next_qp);
937-
if (err_code)
938-
goto error;
987+
if (err_code)
988+
goto error;
989+
iwqp->ibqp.qp_num = qp_num;
990+
}
939991

940992
iwqp->iwpd = iwpd;
941-
iwqp->ibqp.qp_num = qp_num;
942993
qp = &iwqp->sc_qp;
943994
iwqp->iwscq = to_iwcq(init_attr->send_cq);
944995
iwqp->iwrcq = to_iwcq(init_attr->recv_cq);
@@ -998,10 +1049,17 @@ static int irdma_create_qp(struct ib_qp *ibqp,
9981049
ctx_info->send_cq_num = iwqp->iwscq->sc_cq.cq_uk.cq_id;
9991050
ctx_info->rcv_cq_num = iwqp->iwrcq->sc_cq.cq_uk.cq_id;
10001051

1001-
if (rdma_protocol_roce(&iwdev->ibdev, 1))
1052+
if (rdma_protocol_roce(&iwdev->ibdev, 1)) {
1053+
if (dev->ws_add(&iwdev->vsi, 0)) {
1054+
irdma_cqp_qp_destroy_cmd(&rf->sc_dev, &iwqp->sc_qp);
1055+
err_code = -EINVAL;
1056+
goto error;
1057+
}
1058+
irdma_qp_add_qos(&iwqp->sc_qp);
10021059
irdma_roce_fill_and_set_qpctx_info(iwqp, ctx_info);
1003-
else
1060+
} else {
10041061
irdma_iw_fill_and_set_qpctx_info(iwqp, ctx_info);
1062+
}
10051063

10061064
err_code = irdma_cqp_create_qp_cmd(iwqp);
10071065
if (err_code)
@@ -1013,16 +1071,6 @@ static int irdma_create_qp(struct ib_qp *ibqp,
10131071
iwqp->sig_all = init_attr->sq_sig_type == IB_SIGNAL_ALL_WR;
10141072
rf->qp_table[qp_num] = iwqp;
10151073

1016-
if (rdma_protocol_roce(&iwdev->ibdev, 1)) {
1017-
if (dev->ws_add(&iwdev->vsi, 0)) {
1018-
irdma_cqp_qp_destroy_cmd(&rf->sc_dev, &iwqp->sc_qp);
1019-
err_code = -EINVAL;
1020-
goto error;
1021-
}
1022-
1023-
irdma_qp_add_qos(&iwqp->sc_qp);
1024-
}
1025-
10261074
if (udata) {
10271075
/* GEN_1 legacy support with libi40iw does not have expanded uresp struct */
10281076
if (udata->outlen < sizeof(uresp)) {

drivers/infiniband/hw/irdma/virtchnl.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ static int irdma_vchnl_req_verify_resp(struct irdma_vchnl_req *vchnl_req,
112112
case IRDMA_VCHNL_OP_GET_REG_LAYOUT:
113113
case IRDMA_VCHNL_OP_QUEUE_VECTOR_MAP:
114114
case IRDMA_VCHNL_OP_QUEUE_VECTOR_UNMAP:
115+
case IRDMA_VCHNL_OP_ADD_VPORT:
116+
case IRDMA_VCHNL_OP_DEL_VPORT:
115117
break;
116118
default:
117119
return -EOPNOTSUPP;
@@ -317,6 +319,56 @@ int irdma_vchnl_req_get_reg_layout(struct irdma_sc_dev *dev)
317319
return 0;
318320
}
319321

322+
int irdma_vchnl_req_add_vport(struct irdma_sc_dev *dev, u16 vport_id,
323+
u32 qp1_id, struct irdma_qos *qos)
324+
{
325+
struct irdma_vchnl_resp_vport_info resp_vport = { 0 };
326+
struct irdma_vchnl_req_vport_info req_vport = { 0 };
327+
struct irdma_vchnl_req_init_info info = { 0 };
328+
int ret, i;
329+
330+
if (!dev->vchnl_up)
331+
return -EBUSY;
332+
333+
info.op_code = IRDMA_VCHNL_OP_ADD_VPORT;
334+
info.op_ver = IRDMA_VCHNL_OP_ADD_VPORT_V0;
335+
req_vport.vport_id = vport_id;
336+
req_vport.qp1_id = qp1_id;
337+
info.req_parm_len = sizeof(req_vport);
338+
info.req_parm = &req_vport;
339+
info.resp_parm = &resp_vport;
340+
info.resp_parm_len = sizeof(resp_vport);
341+
342+
ret = irdma_vchnl_req_send_sync(dev, &info);
343+
if (ret)
344+
return ret;
345+
346+
for (i = 0; i < IRDMA_MAX_USER_PRIORITY; i++) {
347+
qos[i].qs_handle = resp_vport.qs_handle[i];
348+
qos[i].valid = true;
349+
}
350+
351+
return 0;
352+
}
353+
354+
int irdma_vchnl_req_del_vport(struct irdma_sc_dev *dev, u16 vport_id, u32 qp1_id)
355+
{
356+
struct irdma_vchnl_req_init_info info = { 0 };
357+
struct irdma_vchnl_req_vport_info req_vport = { 0 };
358+
359+
if (!dev->vchnl_up)
360+
return -EBUSY;
361+
362+
info.op_code = IRDMA_VCHNL_OP_DEL_VPORT;
363+
info.op_ver = IRDMA_VCHNL_OP_DEL_VPORT_V0;
364+
req_vport.vport_id = vport_id;
365+
req_vport.qp1_id = qp1_id;
366+
info.req_parm_len = sizeof(req_vport);
367+
info.req_parm = &req_vport;
368+
369+
return irdma_vchnl_req_send_sync(dev, &info);
370+
}
371+
320372
/**
321373
* irdma_vchnl_req_aeq_vec_map - Map AEQ to vector on this function
322374
* @dev: RDMA device pointer

drivers/infiniband/hw/irdma/virtchnl.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
#define IRDMA_VCHNL_OP_GET_REG_LAYOUT_V0 0
1818
#define IRDMA_VCHNL_OP_QUEUE_VECTOR_MAP_V0 0
1919
#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
2022
#define IRDMA_VCHNL_OP_GET_RDMA_CAPS_V0 0
2123
#define IRDMA_VCHNL_OP_GET_RDMA_CAPS_MIN_SIZE 1
2224

@@ -57,6 +59,8 @@ enum irdma_vchnl_ops {
5759
IRDMA_VCHNL_OP_GET_RDMA_CAPS = 13,
5860
IRDMA_VCHNL_OP_QUEUE_VECTOR_MAP = 14,
5961
IRDMA_VCHNL_OP_QUEUE_VECTOR_UNMAP = 15,
62+
IRDMA_VCHNL_OP_ADD_VPORT = 16,
63+
IRDMA_VCHNL_OP_DEL_VPORT = 17,
6064
};
6165

6266
struct irdma_vchnl_req_hmc_info {
@@ -81,6 +85,15 @@ struct irdma_vchnl_qvlist_info {
8185
struct irdma_vchnl_qv_info qv_info[];
8286
};
8387

88+
struct irdma_vchnl_req_vport_info {
89+
u16 vport_id;
90+
u32 qp1_id;
91+
};
92+
93+
struct irdma_vchnl_resp_vport_info {
94+
u16 qs_handle[IRDMA_MAX_USER_PRIORITY];
95+
};
96+
8497
struct irdma_vchnl_op_buf {
8598
u16 op_code;
8699
u16 op_ver;
@@ -141,6 +154,8 @@ struct irdma_vchnl_req_init_info {
141154
u16 op_ver;
142155
} __packed;
143156

157+
struct irdma_qos;
158+
144159
int irdma_sc_vchnl_init(struct irdma_sc_dev *dev,
145160
struct irdma_vchnl_init_info *info);
146161
int irdma_vchnl_req_get_ver(struct irdma_sc_dev *dev, u16 ver_req,
@@ -154,4 +169,8 @@ int irdma_vchnl_req_get_reg_layout(struct irdma_sc_dev *dev);
154169
int irdma_vchnl_req_aeq_vec_map(struct irdma_sc_dev *dev, u32 v_idx);
155170
int irdma_vchnl_req_ceq_vec_map(struct irdma_sc_dev *dev, u16 ceq_id,
156171
u32 v_idx);
172+
int irdma_vchnl_req_add_vport(struct irdma_sc_dev *dev, u16 vport_id,
173+
u32 qp1_id, struct irdma_qos *qos);
174+
int irdma_vchnl_req_del_vport(struct irdma_sc_dev *dev, u16 vport_id,
175+
u32 qp1_id);
157176
#endif /* IRDMA_VIRTCHNL_H */

0 commit comments

Comments
 (0)