From nobody Wed Sep 16 14:13:17 2026 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4hlLTB23R5z6rXJD for ; Wed, 16 Sep 2026 14:13:18 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR2" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4hlLT9739bz3N00 for ; Wed, 16 Sep 2026 14:13:17 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1789567998; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=7wTE85cE/vhPnSiLGwk7uzfO0yZWS7UhxdR4Txr3Jvc=; b=lltSffBUjQFWBtEWMKTpW9mb/cXanezWHuwlAt3cKzO1WyDB5Mrmp2h/ZBFwK7M1mwzEr8 YbYaXs+3Ng7WRi1+iM3fukmBuADyNymXvKEHh3IlxRg6Nbopk5YNrLhelOKWmIeWBRFPmS V+VC7brOhtAxSJ61Xy3mB9eW3lffaxt53GpAORWIYKRpSjAjglasYWNw79xMCIkQlMzyLs Z9kGAz0Cq2PrB2Ccv5f1aPI2Hx/kk0gSu08Cz1ZKrS0PYkpYFtbCyMsJKJXoLK+mS8v/5N ECxI4v9QaetrNlpvrKh1D8+D/HYqSZgVlYscP5IptDu+LTYZMOtwIGCDmzodMw== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1789567998; b=O3Aqy6ebIVH6lAYDPhwrIRbj6MPpteND82qKNddn0Ys1b4o6UyJ5LflvBo6a/068FTVNOj btgWgTfq2kb7FRRXLzG08tG3a5GRcGJVK0O562+lF9smhrtOT6l8RQaCI1UDKJkiR6THLR vJ2xbNmCV5QD22gj/WnZr0kKPG14dLquzX88N4Oky/u2fohfIEW9OBpGuxXEjsilvaETk9 DOm4qCSl1QzNdFnGBgzaGyuKsNk0N8dVt6B6nwaR9TPcak/2C4GdoV9zQCZ62PpDvZXyPe lAechf3IS9APZAdo2Moy61yxrSu/HRakMZjWoU3Me23Z8YJP/N2AbLUYjspoog== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1789567998; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=7wTE85cE/vhPnSiLGwk7uzfO0yZWS7UhxdR4Txr3Jvc=; b=LIUqKtp/ingT8EooxsgNppmaQknNVG/KIHLh3xBBksBVNXUX7oSTxilXFflPy/71rHm+bh ANBFkAGSs78bjY0Sbt4jkpuXo3PWU8Xx5P7Z6FoPH3v9sQixi1zUBKWyRW7iXpEdf+LD/Q ujISda0hl9wuNTgGdeEDA5Rh2zo3LQQuRAE27bGzEYvosGTRqRz1TdXoeCF9UgY7gJZal5 apFc71UWFct8dKsPCdyeyRbgPqjyb6KmhWYmnlGZJ0jadGOHdRPMhJ2O8DOwLjy8+Xi5bN m+LDRbOk98+/nyJ01oVTZpb+tpy1YF8AGH/CJtNEt/RygUUR3v7TcwPyqwp7OQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hlLT95rMSzqWv for ; Wed, 16 Sep 2026 14:13:17 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 3719b by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Wed, 16 Sep 2026 14:13:17 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Cc: Vag Singh From: Konstantin Belousov Subject: git: 4601cb629538 - main - verbs/mlx5: Expose tag matching capabilities List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kib X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 4601cb62953866e94bac791b5baf10125507038c Auto-Submitted: auto-generated Date: Wed, 16 Sep 2026 14:13:17 +0000 Message-Id: <6aaaa3fd.3719b.51899aa9@gitrepo.freebsd.org> The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=4601cb62953866e94bac791b5baf10125507038c commit 4601cb62953866e94bac791b5baf10125507038c Author: Vag Singh AuthorDate: 2025-08-14 06:49:20 +0000 Commit: Konstantin Belousov CommitDate: 2026-09-16 14:12:09 +0000 verbs/mlx5: Expose tag matching capabilities [PATCH 23/31] FreeBSD OFED support for DPDK MLX5 PMD a) Expose tag matching capabilities and show them in ibv_devinfo. b) verbs: Introduce tag matching SRQ Introducing tag matching SRQ (TM-SRQ), which retains basic semantic of regular SRQ, reports completions to own CQ, and has additional tag based message receiving mechanism. Detailed description for the TM-SRQ usage was added into Documentation/tag_matching.md c) mlx5: Add support to tag matching SRQ type Create command QP for a tag-matching SRQ. Command QP used for inserting/removing entries from the tag matching list. This command QP is hidden from the users in the mlx5_srq structure. New verb ibv_post_srq_ops() will be added in next patch to use it. Differential revision: https://reviews.freebsd.org/D32198 MFC after: 1 month --- contrib/ofed/libibverbs/cmd.c | 28 +++++ contrib/ofed/libibverbs/examples/devinfo.c | 17 +++ contrib/ofed/libibverbs/kern-abi.h | 12 +- contrib/ofed/libibverbs/man/ibv_create_srq_ex.3 | 13 +- contrib/ofed/libibverbs/man/ibv_query_device_ex.3 | 17 +++ contrib/ofed/libibverbs/verbs.h | 30 ++++- contrib/ofed/libmlx5/mlx5.h | 1 + contrib/ofed/libmlx5/verbs.c | 140 +++++++++++++++++++--- 8 files changed, 237 insertions(+), 21 deletions(-) diff --git a/contrib/ofed/libibverbs/cmd.c b/contrib/ofed/libibverbs/cmd.c index af2ff7f21f64..82ceb5fb9fe8 100644 --- a/contrib/ofed/libibverbs/cmd.c +++ b/contrib/ofed/libibverbs/cmd.c @@ -237,6 +237,23 @@ int ibv_cmd_query_device_ex(struct ibv_context *context, attr->raw_packet_caps = resp->raw_packet_caps; } + if (attr_size >= offsetof(struct ibv_device_attr_ex, tm_caps) + + sizeof(attr->tm_caps)) { + if (resp->response_length >= + offsetof(struct ibv_query_device_resp_ex, tm_caps) + + sizeof(resp->tm_caps)) { + attr->tm_caps.max_rndv_hdr_size = + resp->tm_caps.max_rndv_hdr_size; + attr->tm_caps.max_num_tags = + resp->tm_caps.max_num_tags; + attr->tm_caps.flags = resp->tm_caps.flags; + attr->tm_caps.max_ops = + resp->tm_caps.max_ops; + attr->tm_caps.max_sge = + resp->tm_caps.max_sge; + } + } + return 0; } @@ -703,6 +720,17 @@ int ibv_cmd_create_srq_ex(struct ibv_context *context, vxrcd = container_of(attr_ex->xrcd, struct verbs_xrcd, xrcd); cmd->xrcd_handle = vxrcd->handle; cmd->cq_handle = attr_ex->cq->handle; + } else if (attr_ex->comp_mask & IBV_SRQ_INIT_ATTR_TM) { + if (cmd->srq_type != IBV_SRQT_TM) + return EINVAL; + if (!(attr_ex->comp_mask & IBV_SRQ_INIT_ATTR_CQ) || + !attr_ex->tm_cap.max_num_tags) + return EINVAL; + + cmd->cq_handle = attr_ex->cq->handle; + cmd->max_num_tags = attr_ex->tm_cap.max_num_tags; + } else if (cmd->srq_type != IBV_SRQT_BASIC) { + return EINVAL; } ret = pthread_mutex_init(&srq->srq.mutex, NULL); diff --git a/contrib/ofed/libibverbs/examples/devinfo.c b/contrib/ofed/libibverbs/examples/devinfo.c index 866d82718f7d..37191f44e01e 100644 --- a/contrib/ofed/libibverbs/examples/devinfo.c +++ b/contrib/ofed/libibverbs/examples/devinfo.c @@ -343,6 +343,22 @@ static void print_device_cap_flags_ex(uint64_t device_cap_flags_ex) ex_flags & unknown_flags); } +static void print_tm_caps(const struct ibv_tm_caps *caps) +{ + if (caps->max_num_tags) { + printf("\tmax_rndv_hdr_size:\t\t%u\n", + caps->max_rndv_hdr_size); + printf("\tmax_num_tags:\t\t\t%u\n", caps->max_num_tags); + printf("\tmax_ops:\t\t\t%u\n", caps->max_ops); + printf("\tmax_sge:\t\t\t%u\n", caps->max_sge); + printf("\tflags:\n"); + if (caps->flags & IBV_TM_CAP_RC) + printf("\t\t\t\t\tIBV_TM_CAP_RC\n"); + } else { + printf("\ttag matching not supported\n"); + } +} + static void print_tso_caps(const struct ibv_tso_caps *caps) { uint32_t unknown_general_caps = ~(1 << IBV_QPT_RAW_PACKET | @@ -522,6 +538,7 @@ static int print_hca_cap(struct ibv_device *ib_dev, uint8_t ib_port) print_rss_caps(&device_attr.rss_caps); printf("\tmax_wq_type_rq:\t\t\t%u\n", device_attr.max_wq_type_rq); print_packet_pacing_caps(&device_attr.packet_pacing_caps); + print_tm_caps(&device_attr.tm_caps); } for (port = 1; port <= device_attr.orig_attr.phys_port_cnt; ++port) { diff --git a/contrib/ofed/libibverbs/kern-abi.h b/contrib/ofed/libibverbs/kern-abi.h index 75a1caacaf71..9c3557559676 100644 --- a/contrib/ofed/libibverbs/kern-abi.h +++ b/contrib/ofed/libibverbs/kern-abi.h @@ -280,6 +280,15 @@ struct ibv_rss_caps_resp { __u32 reserved; }; +struct ibv_tm_caps_resp { + __u32 max_rndv_hdr_size; + __u32 max_num_tags; + __u32 flags; + __u32 max_ops; + __u32 max_sge; + __u32 reserved; +}; + struct ibv_query_device_resp_ex { struct ibv_query_device_resp base; __u32 comp_mask; @@ -291,6 +300,7 @@ struct ibv_query_device_resp_ex { struct ibv_rss_caps_resp rss_caps; __u32 max_wq_type_rq; __u32 raw_packet_caps; + struct ibv_tm_caps_resp tm_caps; }; struct ibv_query_port { @@ -1116,7 +1126,7 @@ struct ibv_create_xsrq { __u32 max_wr; __u32 max_sge; __u32 srq_limit; - __u32 reserved; + __u32 max_num_tags; __u32 xrcd_handle; __u32 cq_handle; __u64 driver_data[0]; diff --git a/contrib/ofed/libibverbs/man/ibv_create_srq_ex.3 b/contrib/ofed/libibverbs/man/ibv_create_srq_ex.3 index c0319067b0f5..c20a3ce3da25 100644 --- a/contrib/ofed/libibverbs/man/ibv_create_srq_ex.3 +++ b/contrib/ofed/libibverbs/man/ibv_create_srq_ex.3 @@ -26,10 +26,11 @@ struct ibv_srq_init_attr_ex { void *srq_context; /* Associated context of the SRQ */ struct ibv_srq_attr attr; /* SRQ attributes */ uint32_t comp_mask; /* Identifies valid fields */ -enum ibv_srq_type srq_type; /* Basic / XRC */ +enum ibv_srq_type srq_type; /* Basic / XRC / tag matching */ struct ibv_pd *pd; /* PD associated with the SRQ */ struct ibv_xrcd *xrcd; /* XRC domain to associate with the SRQ */ struct ibv_cq *cq; /* CQ to associate with the SRQ for XRC mode */ +struct ibv_tm_cap tm_cap; /* Tag matching attributes */ .in -8 }; .sp @@ -41,6 +42,16 @@ uint32_t max_sge; /* Requested max number of scatter eleme uint32_t srq_limit; /* The limit value of the SRQ */ .in -8 }; +.sp +.nf +struct ibv_tm_cap { +.in +8 +uint32_t max_num_tags; /* Tag matching list size */ +uint32_t max_ops; /* Number of outstanding tag list operations */ +.in -8 +}; +.sp +.nf .fi .PP The function diff --git a/contrib/ofed/libibverbs/man/ibv_query_device_ex.3 b/contrib/ofed/libibverbs/man/ibv_query_device_ex.3 index fdfb70811673..4124b4067948 100644 --- a/contrib/ofed/libibverbs/man/ibv_query_device_ex.3 +++ b/contrib/ofed/libibverbs/man/ibv_query_device_ex.3 @@ -33,6 +33,7 @@ struct ibv_rss_caps rss_caps; /* RSS capabilities */ uint32_t max_wq_type_rq; /* Max Work Queue from type RQ */ struct ibv_packet_pacing_caps packet_pacing_caps; /* Packet pacing capabilities */ uint32_t raw_packet_caps; /* Raw packet capabilities, use enum ibv_raw_packet_caps */ +struct ibv_tm_caps tm_caps; /* Tag matching capabilities */ .in -8 }; @@ -84,6 +85,22 @@ IBV_RAW_PACKET_CAP_IP_CSUM = 1 << 2, /* IP CSUM offload is supported */ .in -8 }; +enum ibv_tm_cap_flags { +.in +8 +IBV_TM_CAP_RC = 1 << 0, /* Support tag matching on RC transport */ +.in -8 +}; + +struct ibv_tm_caps { +.in +8 +uint32_t max_rndv_hdr_size; /* Max size of rendezvous request header */ +uint32_t max_num_tags; /* Max number of tagged buffers in a TM-SRQ matching list */ +uint32_t flags; /* From enum ibv_tm_cap_flags */ +uint32_t max_ops; /* Max number of outstanding list operations */ +uint32_t max_sge; /* Max number of SGEs in a tagged buffer */ +.in -8 +}; + .fi .SH "RETURN VALUE" .B ibv_query_device_ex() diff --git a/contrib/ofed/libibverbs/verbs.h b/contrib/ofed/libibverbs/verbs.h index 5ef6430dca93..e7769e072044 100644 --- a/contrib/ofed/libibverbs/verbs.h +++ b/contrib/ofed/libibverbs/verbs.h @@ -259,6 +259,23 @@ enum ibv_raw_packet_caps { IBV_RAW_PACKET_CAP_IP_CSUM = 1 << 2, }; +enum ibv_tm_cap_flags { + IBV_TM_CAP_RC = 1 << 0, +}; + +struct ibv_tm_caps { + /* Max size of rendezvous request header */ + uint32_t max_rndv_hdr_size; + /* Max number of tagged buffers in a TM-SRQ matching list */ + uint32_t max_num_tags; + /* From enum ibv_tm_cap_flags */ + uint32_t flags; + /* Max number of outstanding list operations */ + uint32_t max_ops; + /* Max number of SGEs in a tagged buffer */ + uint32_t max_sge; +}; + struct ibv_device_attr_ex { struct ibv_device_attr orig_attr; uint32_t comp_mask; @@ -271,6 +288,7 @@ struct ibv_device_attr_ex { uint32_t max_wq_type_rq; struct ibv_packet_pacing_caps packet_pacing_caps; uint32_t raw_packet_caps; /* Use ibv_raw_packet_caps */ + struct ibv_tm_caps tm_caps; }; enum ibv_mtu { @@ -654,7 +672,8 @@ struct ibv_srq_init_attr { enum ibv_srq_type { IBV_SRQT_BASIC, - IBV_SRQT_XRC + IBV_SRQT_XRC, + IBV_SRQT_TM, }; enum ibv_srq_init_attr_mask { @@ -662,7 +681,13 @@ enum ibv_srq_init_attr_mask { IBV_SRQ_INIT_ATTR_PD = 1 << 1, IBV_SRQ_INIT_ATTR_XRCD = 1 << 2, IBV_SRQ_INIT_ATTR_CQ = 1 << 3, - IBV_SRQ_INIT_ATTR_RESERVED = 1 << 4 + IBV_SRQ_INIT_ATTR_TM = 1 << 4, + IBV_SRQ_INIT_ATTR_RESERVED = 1 << 5, +}; + +struct ibv_tm_cap { + uint32_t max_num_tags; + uint32_t max_ops; }; struct ibv_srq_init_attr_ex { @@ -674,6 +699,7 @@ struct ibv_srq_init_attr_ex { struct ibv_pd *pd; struct ibv_xrcd *xrcd; struct ibv_cq *cq; + struct ibv_tm_cap tm_cap; }; enum ibv_wq_type { diff --git a/contrib/ofed/libmlx5/mlx5.h b/contrib/ofed/libmlx5/mlx5.h index 11fceff1f433..e2e4a882ed54 100644 --- a/contrib/ofed/libmlx5/mlx5.h +++ b/contrib/ofed/libmlx5/mlx5.h @@ -360,6 +360,7 @@ struct mlx5_srq { __be32 *db; uint16_t counter; int wq_sig; + struct ibv_qp *cmd_qp; }; struct wr_list { diff --git a/contrib/ofed/libmlx5/verbs.c b/contrib/ofed/libmlx5/verbs.c index 95a90b253899..450ec5d6bb65 100644 --- a/contrib/ofed/libmlx5/verbs.c +++ b/contrib/ofed/libmlx5/verbs.c @@ -752,6 +752,13 @@ int mlx5_destroy_srq(struct ibv_srq *srq) struct mlx5_srq *msrq = to_msrq(srq); struct mlx5_context *ctx = to_mctx(srq->context); + if (msrq->cmd_qp) { + ret = mlx5_destroy_qp(msrq->cmd_qp); + if (ret) + return ret; + msrq->cmd_qp = NULL; + } + ret = ibv_cmd_destroy_srq(srq); if (ret) return ret; @@ -1816,9 +1823,94 @@ int mlx5_close_xrcd(struct ibv_xrcd *ib_xrcd) return ret; } -static struct ibv_srq * -mlx5_create_xrc_srq(struct ibv_context *context, - struct ibv_srq_init_attr_ex *attr) +static struct ibv_qp * +create_cmd_qp(struct ibv_context *context, + struct ibv_srq_init_attr_ex *srq_attr, + struct ibv_srq *srq) +{ + struct ibv_qp_init_attr_ex init_attr = {}; + FILE *fp = to_mctx(context)->dbg_fp; + struct ibv_port_attr port_attr; + struct ibv_modify_qp qcmd = {}; + struct ibv_qp_attr attr = {}; + struct ibv_query_port pcmd; + struct ibv_qp *qp; + int attr_mask; + int port = 1; + int ret; + + ret = ibv_cmd_query_port(context, port, &port_attr, + &pcmd, sizeof(pcmd)); + if (ret) { + mlx5_dbg(fp, MLX5_DBG_QP, "ret %d\n", ret); + return NULL; + } + + init_attr.qp_type = IBV_QPT_RC; + init_attr.srq = srq; + /* Command QP will be used to pass MLX5_OPCODE_TAG_MATCHING messages + * to add/remove tag matching list entries. + * WQ size is based on max_ops parameter holding max number of + * outstanding list operations. + */ + init_attr.cap.max_send_wr = srq_attr->tm_cap.max_ops; + /* Tag matching list entry will point to a single sge buffer */ + init_attr.cap.max_send_sge = 1; + init_attr.comp_mask = IBV_QP_INIT_ATTR_PD; + init_attr.pd = srq_attr->pd; + init_attr.send_cq = srq_attr->cq; + init_attr.recv_cq = srq_attr->cq; + + qp = create_qp(context, &init_attr); + if (!qp) + return NULL; + + attr.qp_state = IBV_QPS_INIT; + attr.port_num = port; + attr_mask = IBV_QP_STATE | IBV_QP_PKEY_INDEX + | IBV_QP_PORT | IBV_QP_ACCESS_FLAGS; + + ret = ibv_cmd_modify_qp(qp, &attr, attr_mask, &qcmd, sizeof(qcmd)); + if (ret) { + mlx5_dbg(fp, MLX5_DBG_QP, "ret %d\n", ret); + goto err; + } + + attr.qp_state = IBV_QPS_RTR; + attr.path_mtu = IBV_MTU_256; + attr.dest_qp_num = qp->qp_num; /* Loopback */ + attr.ah_attr.dlid = port_attr.lid; + attr.ah_attr.port_num = port; + attr_mask = IBV_QP_STATE | IBV_QP_AV | IBV_QP_PATH_MTU + | IBV_QP_DEST_QPN | IBV_QP_RQ_PSN + | IBV_QP_MAX_DEST_RD_ATOMIC | IBV_QP_MIN_RNR_TIMER; + + ret = ibv_cmd_modify_qp(qp, &attr, attr_mask, &qcmd, sizeof(qcmd)); + if (ret) { + mlx5_dbg(fp, MLX5_DBG_QP, "ret %d\n", ret); + goto err; + } + + attr.qp_state = IBV_QPS_RTS; + attr_mask = IBV_QP_STATE | IBV_QP_TIMEOUT | IBV_QP_RETRY_CNT + | IBV_QP_RNR_RETRY | IBV_QP_SQ_PSN + | IBV_QP_MAX_QP_RD_ATOMIC; + + ret = ibv_cmd_modify_qp(qp, &attr, attr_mask, &qcmd, sizeof(qcmd)); + if (ret) { + mlx5_dbg(fp, MLX5_DBG_QP, "ret %d\n", ret); + goto err; + } + + return qp; + +err: + mlx5_destroy_qp(qp); + return NULL; +} + +struct ibv_srq *mlx5_create_srq_ex(struct ibv_context *context, + struct ibv_srq_init_attr_ex *attr) { int err; struct mlx5_create_srq_ex cmd; @@ -1830,6 +1922,24 @@ mlx5_create_xrc_srq(struct ibv_context *context, int uidx; FILE *fp = ctx->dbg_fp; + if (!(attr->comp_mask & IBV_SRQ_INIT_ATTR_TYPE) || + (attr->srq_type == IBV_SRQT_BASIC)) + return mlx5_create_srq(attr->pd, + (struct ibv_srq_init_attr *)attr); + + if (attr->srq_type != IBV_SRQT_XRC && + attr->srq_type != IBV_SRQT_TM) { + errno = EINVAL; + return NULL; + } + + /* An extended CQ is required to read TM information from */ + if (attr->srq_type == IBV_SRQT_TM && + !(attr->cq && (to_mcq(attr->cq)->flags & MLX5_CQ_FLAGS_EXTENDED))) { + errno = EINVAL; + return NULL; + } + msrq = calloc(1, sizeof(*msrq)); if (!msrq) return NULL; @@ -1908,10 +2018,16 @@ mlx5_create_xrc_srq(struct ibv_context *context, if (err) goto err_free_uidx; + if (attr->srq_type == IBV_SRQT_TM) { + msrq->cmd_qp = create_cmd_qp(context, attr, ibsrq); + if (!msrq->cmd_qp) + goto err_destroy; + } + if (!ctx->cqe_version) { err = mlx5_store_srq(to_mctx(context), resp.srqn, msrq); if (err) - goto err_destroy; + goto err_free_cmd; pthread_mutex_unlock(&ctx->srq_table_mutex); } @@ -1922,6 +2038,9 @@ mlx5_create_xrc_srq(struct ibv_context *context, return ibsrq; +err_free_cmd: + if (msrq->cmd_qp) + mlx5_destroy_qp(msrq->cmd_qp); err_destroy: ibv_cmd_destroy_srq(ibsrq); @@ -1947,19 +2066,6 @@ err: return NULL; } -struct ibv_srq *mlx5_create_srq_ex(struct ibv_context *context, - struct ibv_srq_init_attr_ex *attr) -{ - if (!(attr->comp_mask & IBV_SRQ_INIT_ATTR_TYPE) || - (attr->srq_type == IBV_SRQT_BASIC)) - return mlx5_create_srq(attr->pd, - (struct ibv_srq_init_attr *)attr); - else if (attr->srq_type == IBV_SRQT_XRC) - return mlx5_create_xrc_srq(context, attr); - - return NULL; -} - int mlx5_query_device_ex(struct ibv_context *context, const struct ibv_query_device_ex_input *input, struct ibv_device_attr_ex *attr,