Skip to content

Commit

Permalink
RDMA/efa: Support QP with unsolicited write w/ imm. receive
Browse files Browse the repository at this point in the history
Add a new EFA flags attribute for QP creation, and support unsolicited
write with immediate flag. QPs created with this flag set will not
consume receive work requests for incoming RDMA write with immediate.
Expose device capability bit for this feature support.

Reviewed-by: Daniel Kranzdorf <[email protected]>
Reviewed-by: Firas Jahjah <[email protected]>
Signed-off-by: Michael Margolin <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Leon Romanovsky <[email protected]>
  • Loading branch information
mrgolin authored and rleon committed May 8, 2024
1 parent f483f6a commit 2b8af50
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 3 deletions.
11 changes: 9 additions & 2 deletions drivers/infiniband/hw/efa/efa_admin_cmds_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,10 @@ struct efa_admin_create_qp_cmd {
* virtual (IOVA returned by MR registration)
* 1 : rq_virt - If set, RQ ring base address is
* virtual (IOVA returned by MR registration)
* 7:2 : reserved - MBZ
* 2 : unsolicited_write_recv - If set, work requests
* will not be consumed for incoming RDMA write with
* immediate
* 7:3 : reserved - MBZ
*/
u8 flags;

Expand Down Expand Up @@ -663,7 +666,9 @@ struct efa_admin_feature_device_attr_desc {
* polling is supported
* 3 : rdma_write - If set, RDMA Write is supported
* on TX queues
* 31:4 : reserved - MBZ
* 4 : unsolicited_write_recv - If set, unsolicited
* write with imm. receive is supported
* 31:5 : reserved - MBZ
*/
u32 device_caps;

Expand Down Expand Up @@ -1009,6 +1014,7 @@ struct efa_admin_host_info {
/* create_qp_cmd */
#define EFA_ADMIN_CREATE_QP_CMD_SQ_VIRT_MASK BIT(0)
#define EFA_ADMIN_CREATE_QP_CMD_RQ_VIRT_MASK BIT(1)
#define EFA_ADMIN_CREATE_QP_CMD_UNSOLICITED_WRITE_RECV_MASK BIT(2)

/* modify_qp_cmd */
#define EFA_ADMIN_MODIFY_QP_CMD_QP_STATE_MASK BIT(0)
Expand Down Expand Up @@ -1044,6 +1050,7 @@ struct efa_admin_host_info {
#define EFA_ADMIN_FEATURE_DEVICE_ATTR_DESC_RNR_RETRY_MASK BIT(1)
#define EFA_ADMIN_FEATURE_DEVICE_ATTR_DESC_DATA_POLLING_128_MASK BIT(2)
#define EFA_ADMIN_FEATURE_DEVICE_ATTR_DESC_RDMA_WRITE_MASK BIT(3)
#define EFA_ADMIN_FEATURE_DEVICE_ATTR_DESC_UNSOLICITED_WRITE_RECV_MASK BIT(4)

/* create_eq_cmd */
#define EFA_ADMIN_CREATE_EQ_CMD_ENTRY_SIZE_WORDS_MASK GENMASK(4, 0)
Expand Down
3 changes: 3 additions & 0 deletions drivers/infiniband/hw/efa/efa_com_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ int efa_com_create_qp(struct efa_com_dev *edev,
params->rq_depth;
create_qp_cmd.uar = params->uarn;

if (params->unsolicited_write_recv)
EFA_SET(&create_qp_cmd.flags, EFA_ADMIN_CREATE_QP_CMD_UNSOLICITED_WRITE_RECV, 1);

err = efa_com_cmd_exec(aq,
(struct efa_admin_aq_entry *)&create_qp_cmd,
sizeof(create_qp_cmd),
Expand Down
1 change: 1 addition & 0 deletions drivers/infiniband/hw/efa/efa_com_cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ struct efa_com_create_qp_params {
u16 pd;
u16 uarn;
u8 qp_type;
u8 unsolicited_write_recv : 1;
};

struct efa_com_create_qp_result {
Expand Down
19 changes: 18 additions & 1 deletion drivers/infiniband/hw/efa/efa_verbs.c
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,9 @@ int efa_query_device(struct ib_device *ibdev,
if (EFA_DEV_CAP(dev, RDMA_WRITE))
resp.device_caps |= EFA_QUERY_DEVICE_CAPS_RDMA_WRITE;

if (EFA_DEV_CAP(dev, UNSOLICITED_WRITE_RECV))
resp.device_caps |= EFA_QUERY_DEVICE_CAPS_UNSOLICITED_WRITE_RECV;

if (dev->neqs)
resp.device_caps |= EFA_QUERY_DEVICE_CAPS_CQ_NOTIFICATIONS;

Expand Down Expand Up @@ -639,6 +642,7 @@ int efa_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *init_attr,
struct efa_ibv_create_qp cmd = {};
struct efa_qp *qp = to_eqp(ibqp);
struct efa_ucontext *ucontext;
u16 supported_efa_flags = 0;
int err;

ucontext = rdma_udata_to_drv_context(udata, struct efa_ucontext,
Expand Down Expand Up @@ -676,13 +680,23 @@ int efa_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *init_attr,
goto err_out;
}

if (cmd.comp_mask) {
if (cmd.comp_mask || !is_reserved_cleared(cmd.reserved_90)) {
ibdev_dbg(&dev->ibdev,
"Incompatible ABI params, unknown fields in udata\n");
err = -EINVAL;
goto err_out;
}

if (EFA_DEV_CAP(dev, UNSOLICITED_WRITE_RECV))
supported_efa_flags |= EFA_CREATE_QP_WITH_UNSOLICITED_WRITE_RECV;

if (cmd.flags & ~supported_efa_flags) {
ibdev_dbg(&dev->ibdev, "Unsupported EFA QP create flags[%#x], supported[%#x]\n",
cmd.flags, supported_efa_flags);
err = -EOPNOTSUPP;
goto err_out;
}

create_qp_params.uarn = ucontext->uarn;
create_qp_params.pd = to_epd(ibqp->pd)->pdn;

Expand Down Expand Up @@ -722,6 +736,9 @@ int efa_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *init_attr,
create_qp_params.rq_base_addr = qp->rq_dma_addr;
}

if (cmd.flags & EFA_CREATE_QP_WITH_UNSOLICITED_WRITE_RECV)
create_qp_params.unsolicited_write_recv = true;

err = efa_com_create_qp(&dev->edev, &create_qp_params,
&create_qp_resp);
if (err)
Expand Down
7 changes: 7 additions & 0 deletions include/uapi/rdma/efa-abi.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,17 @@ enum {
EFA_QP_DRIVER_TYPE_SRD = 0,
};

enum {
EFA_CREATE_QP_WITH_UNSOLICITED_WRITE_RECV = 1 << 0,
};

struct efa_ibv_create_qp {
__u32 comp_mask;
__u32 rq_ring_size; /* bytes */
__u32 sq_ring_size; /* bytes */
__u32 driver_qp_type;
__u16 flags;
__u8 reserved_90[6];
};

struct efa_ibv_create_qp_resp {
Expand Down Expand Up @@ -123,6 +129,7 @@ enum {
EFA_QUERY_DEVICE_CAPS_CQ_WITH_SGID = 1 << 3,
EFA_QUERY_DEVICE_CAPS_DATA_POLLING_128 = 1 << 4,
EFA_QUERY_DEVICE_CAPS_RDMA_WRITE = 1 << 5,
EFA_QUERY_DEVICE_CAPS_UNSOLICITED_WRITE_RECV = 1 << 6,
};

struct efa_ibv_ex_query_device_resp {
Expand Down

0 comments on commit 2b8af50

Please sign in to comment.