@@ -339,6 +339,16 @@ static int print_hca_cap(struct ibv_device *ib_dev, uint8_t ib_port)
printf("\tlocal_ca_ack_delay:\t\t%d\n", device_attr.orig_attr.local_ca_ack_delay);
print_odp_caps(&device_attr.odp_caps);
+ if (device_attr.completion_timestamp_mask)
+ printf("\tcompletion timestamp_mask:\t\t\t0x%016lx\n",
+ device_attr.completion_timestamp_mask);
+ else
+ printf("\tcompletion_timestamp_mask not supported\n");
+
+ if (device_attr.hca_core_clock)
+ printf("\thca_core_clock:\t\t\t%lukHZ\n", device_attr.hca_core_clock);
+ else
+ printf("\tcore clock not supported\n");
}
for (port = 1; port <= device_attr.orig_attr.phys_port_cnt; ++port) {
@@ -267,6 +267,8 @@ struct ibv_query_device_resp_ex {
__u32 comp_mask;
__u32 response_length;
struct ibv_odp_caps_resp odp_caps;
+ __u64 timestamp_mask;
+ __u64 hca_core_clock;
};
struct ibv_query_port {
@@ -204,6 +204,8 @@ struct ibv_device_attr_ex {
struct ibv_device_attr orig_attr;
uint32_t comp_mask;
struct ibv_odp_caps odp_caps;
+ uint64_t completion_timestamp_mask;
+ uint64_t hca_core_clock;
};
enum ibv_mtu {
@@ -378,6 +380,19 @@ struct ibv_wc {
uint8_t dlid_path_bits;
};
+enum ibv_wc_flags_ex {
+ IBV_WC_EX_GRH = 1 << 0,
+ IBV_WC_EX_IMM = 1 << 1,
+ IBV_WC_EX_WITH_BYTE_LEN = 1 << 2,
+ IBV_WC_EX_WITH_IMM = 1 << 3,
+ IBV_WC_EX_WITH_QP_NUM = 1 << 4,
+ IBV_WC_EX_WITH_SRC_QP = 1 << 5,
+ IBV_WC_EX_WITH_PKEY_INDEX = 1 << 6,
+ IBV_WC_EX_WITH_SLID = 1 << 7,
+ IBV_WC_EX_WITH_SL = 1 << 8,
+ IBV_WC_EX_WITH_DLID_PATH_BITS = 1 << 9,
+};
+
enum {
IBV_WC_FEATURE_FLAGS = IBV_WC_EX_GRH | IBV_WC_EX_IMM
};
@@ -393,19 +408,6 @@ enum {
IBV_WC_EX_WITH_DLID_PATH_BITS
};
-enum ibv_wc_flags_ex {
- IBV_WC_EX_GRH = 1 << 0,
- IBV_WC_EX_IMM = 1 << 1,
- IBV_WC_EX_WITH_BYTE_LEN = 1 << 2,
- IBV_WC_EX_WITH_IMM = 1 << 3,
- IBV_WC_EX_WITH_QP_NUM = 1 << 4,
- IBV_WC_EX_WITH_SRC_QP = 1 << 5,
- IBV_WC_EX_WITH_PKEY_INDEX = 1 << 6,
- IBV_WC_EX_WITH_SLID = 1 << 7,
- IBV_WC_EX_WITH_SL = 1 << 8,
- IBV_WC_EX_WITH_DLID_PATH_BITS = 1 << 9,
-};
-
/* fields order in wc_ex
* uint32_t byte_len,
* uint32_t imm_data; // in network byte order
@@ -22,8 +22,10 @@ is a pointer to an ibv_device_attr_ex struct, as defined in <infiniband/verbs.h>
struct ibv_device_attr_ex {
.in +8
struct ibv_device_attr orig_attr;
-uint32_t comp_mask; /* Compatibility mask that defines which of the following variables are valid */
-struct ibv_odp_caps odp_caps; /* On-Demand Paging capabilities */
+uint32_t comp_mask; /* Compatibility mask that defines which of the following variables are valid */
+struct ibv_odp_caps odp_caps; /* On-Demand Paging capabilities */
+uint64_t completion_timestamp_mask; /* Completion timestamp mask (0 = unsupported) */
+uint64_t hca_core_clock; /* The frequency (in kHZ) of the HCA (0 = unsupported) */
.in -8
};
@@ -189,6 +189,27 @@ int ibv_cmd_query_device_ex(struct ibv_context *context,
}
}
+ if (attr_size >= offsetof(struct ibv_device_attr_ex,
+ completion_timestamp_mask) +
+ sizeof(attr->completion_timestamp_mask)) {
+ if (IBV_IS_FIELD_IN_RESP(resp, resp_core_size, timestamp_mask))
+ attr->completion_timestamp_mask = resp->timestamp_mask;
+ else
+ attr->completion_timestamp_mask = 0;
+ }
+
+ if (attr_size >= offsetof(struct ibv_device_attr_ex, hca_core_clock) +
+ sizeof(attr->hca_core_clock)) {
+ if (IBV_IS_FIELD_IN_RESP(resp, resp_core_size, hca_core_clock))
+ attr->hca_core_clock = resp->hca_core_clock;
+ else
+ attr->hca_core_clock = 0;
+ }
+
+ if (attr_size > sizeof(*attr))
+ memset((void *)attr + sizeof(*attr), 0,
+ attr_size - sizeof(*attr));
+
return 0;
}
@@ -131,4 +131,11 @@ HIDDEN int ibverbs_init(struct ibv_device ***list);
#define IBV_INIT_CMD_EX(cmd, size, opcode) \
IBV_INIT_CMD_RESP_EX_V(cmd, sizeof(*(cmd)), size, opcode, NULL, 0, 0)
+#define _FILED_SZ_IN_STRUCT(resp, field) \
+ (((void *)(&(resp)->field) - (void *)(resp)) + sizeof((resp)->field))
+
+#define IBV_IS_FIELD_IN_RESP(resp, resp_len, field) \
+ ((resp_len) >= _FILED_SZ_IN_STRUCT(resp, field) && \
+ (resp)->response_length >= _FILED_SZ_IN_STRUCT(resp, field))
+
#endif /* IB_VERBS_H */
The fields timestamp_mask and hca_core_clock were added to the extended version of ibv_query_device verb. timestamp_mask represents the allowed mask of the timestamp. Users could infer the accuracy of the reported possible timestamp. hca_core_clock represents the frequency of the HCA (in HZ). Since timestamp and reading the HCA's core clock is given in hardware cycles, knowing the frequency is mandatory in order to convert this number into seconds. Signed-off-by: Matan Barak <matanb@mellanox.com> --- examples/devinfo.c | 10 ++++++++++ include/infiniband/kern-abi.h | 2 ++ include/infiniband/verbs.h | 28 +++++++++++++++------------- man/ibv_query_device_ex.3 | 6 ++++-- src/cmd.c | 21 +++++++++++++++++++++ src/ibverbs.h | 7 +++++++ 6 files changed, 59 insertions(+), 15 deletions(-)