@@ -130,3 +130,17 @@ achieved by reporting to HW the number of unexpected messages handled by SW
(with respect to the current posted tags). When the SW and HW are in synch, tag
matching resumes normally.
+## Tag Matching Verbs
+
+### Capabilities
+
+Tag matching capabilities are queried by ibv_query_device_ex(), and report the
+following attributes:
+
+* **max_rndv_hdr_size** - Max size of rendezvous request header
+* **max_num_tags** - Max number of tagged buffers in a TM-SRQ matching list
+* **max_ops** - Max number of outstanding tag matching list operations
+* **max_sge** - Max number of SGEs in a tagged buffer
+* **flags** - the following flags are currently defined:
+ - IBV_TM_CAP_RC - Support tag matching on RC transport
+
@@ -238,6 +238,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;
}
@@ -340,6 +340,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 |
@@ -521,6 +537,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) {
@@ -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 {
@@ -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()
@@ -266,6 +266,23 @@ enum ibv_raw_packet_caps {
IBV_RAW_PACKET_CAP_DELAY_DROP = 1 << 3,
};
+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;
@@ -278,6 +295,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 {