libibverbs: Add common infrastructure for Completion Counters verbs Add kernel ioctl interface, provider ops, command helpers, and public API dispatch to enable providers to implement the Completion Counters verbs introduced in the previous commit. Reviewed-by: Daniel Kinsbursky <dkinsb@amazon.com> Signed-off-by: Michael Margolin <mrgolin@amazon.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt index 06862ae..e1f9ce0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt
@@ -88,7 +88,7 @@ # When this is changed the values in these files need changing too: # debian/control # debian/libibverbs1.symbols -set(IBVERBS_PABI_VERSION "64") +set(IBVERBS_PABI_VERSION "65") set(IBVERBS_PROVIDER_SUFFIX "-rdmav${IBVERBS_PABI_VERSION}.so") #-------------------------
diff --git a/debian/control b/debian/control index b7a731a..736fd1c 100644 --- a/debian/control +++ b/debian/control
@@ -151,7 +151,7 @@ Pre-Depends: ${misc:Pre-Depends} Depends: adduser, ${misc:Depends}, ${shlibs:Depends} Recommends: ibverbs-providers -Breaks: ibverbs-providers (<< 64~) +Breaks: ibverbs-providers (<< 65~) Description: Library for direct userspace use of RDMA (InfiniBand/iWARP) libibverbs is a library that allows userspace processes to use RDMA "verbs" as described in the InfiniBand Architecture Specification and
diff --git a/debian/libibverbs1.symbols b/debian/libibverbs1.symbols index 6f90cff..3b74941 100644 --- a/debian/libibverbs1.symbols +++ b/debian/libibverbs1.symbols
@@ -16,7 +16,8 @@ IBVERBS_1.16@IBVERBS_1.16 62 IBVERBS_1.17@IBVERBS_1.17 64 IBVERBS_1.18@IBVERBS_1.18 65 - (symver)IBVERBS_PRIVATE_64 64 + (symver)IBVERBS_PRIVATE_65 65 + _ibv_query_comp_cntr_caps@IBVERBS_1.18 65 _ibv_query_gid_ex@IBVERBS_1.11 32 _ibv_query_gid_table@IBVERBS_1.11 32 ibv_ack_async_event@IBVERBS_1.0 1.1.6 @@ -39,6 +40,7 @@ ibv_create_ah@IBVERBS_1.1 1.1.6 ibv_create_ah_from_wc@IBVERBS_1.1 1.1.6 ibv_create_comp_channel@IBVERBS_1.0 1.1.6 + ibv_create_comp_cntr@IBVERBS_1.18 65 ibv_create_cq@IBVERBS_1.0 1.1.6 ibv_create_cq@IBVERBS_1.1 1.1.6 ibv_create_qp@IBVERBS_1.0 1.1.6 @@ -53,6 +55,7 @@ ibv_destroy_ah@IBVERBS_1.0 1.1.6 ibv_destroy_ah@IBVERBS_1.1 1.1.6 ibv_destroy_comp_channel@IBVERBS_1.0 1.1.6 + ibv_destroy_comp_cntr@IBVERBS_1.18 65 ibv_destroy_cq@IBVERBS_1.0 1.1.6 ibv_destroy_cq@IBVERBS_1.1 1.1.6 ibv_destroy_qp@IBVERBS_1.0 1.1.6 @@ -87,6 +90,8 @@ ibv_import_dm@IBVERBS_1.13 35 ibv_import_mr@IBVERBS_1.10 31 ibv_import_pd@IBVERBS_1.10 31 + ibv_inc_comp_cntr@IBVERBS_1.18 65 + ibv_inc_err_comp_cntr@IBVERBS_1.18 65 ibv_init_ah_from_wc@IBVERBS_1.1 1.1.6 ibv_is_fork_initialized@IBVERBS_1.13 35 ibv_modify_qp@IBVERBS_1.0 1.1.6 @@ -97,6 +102,7 @@ ibv_open_device@IBVERBS_1.0 1.1.6 ibv_open_device@IBVERBS_1.1 1.1.6 ibv_port_state_str@IBVERBS_1.1 1.1.6 + ibv_qp_attach_comp_cntr@IBVERBS_1.18 65 ibv_qp_to_qp_ex@IBVERBS_1.6 24 ibv_query_device@IBVERBS_1.0 1.1.6 ibv_query_device@IBVERBS_1.1 1.1.6 @@ -115,6 +121,8 @@ ibv_query_srq@IBVERBS_1.1 1.1.6 ibv_rate_to_mbps@IBVERBS_1.1 1.1.8 ibv_rate_to_mult@IBVERBS_1.0 1.1.6 + ibv_read_comp_cntr@IBVERBS_1.18 65 + ibv_read_err_comp_cntr@IBVERBS_1.18 65 ibv_read_sysfs_file@IBVERBS_1.0 1.1.6 ibv_reg_buf_mr@IBVERBS_1.17 64 ibv_reg_dmabuf_mr@IBVERBS_1.12 34 @@ -128,7 +136,9 @@ ibv_resize_cq@IBVERBS_1.0 1.1.6 ibv_resize_cq@IBVERBS_1.1 1.1.6 ibv_resolve_eth_l2_from_gid@IBVERBS_1.1 1.2.0 + ibv_set_comp_cntr@IBVERBS_1.18 65 ibv_set_ece@IBVERBS_1.10 31 + ibv_set_err_comp_cntr@IBVERBS_1.18 65 ibv_unimport_dm@IBVERBS_1.13 35 ibv_unimport_mr@IBVERBS_1.10 31 ibv_unimport_pd@IBVERBS_1.10 31
diff --git a/libibverbs/CMakeLists.txt b/libibverbs/CMakeLists.txt index eaf25a1..6fd823e 100644 --- a/libibverbs/CMakeLists.txt +++ b/libibverbs/CMakeLists.txt
@@ -27,6 +27,7 @@ cmd.c cmd_ah.c cmd_counters.c + cmd_comp_cntr.c cmd_cq.c cmd_device.c cmd_dm.c
diff --git a/libibverbs/cmd_comp_cntr.c b/libibverbs/cmd_comp_cntr.c new file mode 100644 index 0000000..cc989f5 --- /dev/null +++ b/libibverbs/cmd_comp_cntr.c
@@ -0,0 +1,127 @@ +// SPDX-License-Identifier: GPL-2.0 or Linux-OpenIB +/* + * Copyright Amazon.com, Inc. or its affiliates. All rights reserved. + */ + +#include <infiniband/cmd_write.h> + +int ibv_cmd_create_comp_cntr(struct ibv_context *context, + struct ibv_comp_cntr *comp_cntr, + struct ibv_command_buffer *link) +{ + DECLARE_COMMAND_BUFFER_LINK(cmdb, UVERBS_OBJECT_COMP_CNTR, + UVERBS_METHOD_COMP_CNTR_CREATE, 1, link); + struct ib_uverbs_attr *handle; + int ret; + + comp_cntr->context = context; + + handle = fill_attr_out_obj(cmdb, UVERBS_ATTR_CREATE_COMP_CNTR_HANDLE); + + ret = execute_ioctl(context, cmdb); + if (ret) + return errno; + + comp_cntr->handle = read_attr_obj(UVERBS_ATTR_CREATE_COMP_CNTR_HANDLE, handle); + return 0; +} + +int ibv_cmd_destroy_comp_cntr(struct ibv_comp_cntr *comp_cntr) +{ + DECLARE_COMMAND_BUFFER(cmdb, UVERBS_OBJECT_COMP_CNTR, UVERBS_METHOD_COMP_CNTR_DESTROY, 1); + int ret; + + fill_attr_in_obj(cmdb, UVERBS_ATTR_DESTROY_COMP_CNTR_HANDLE, comp_cntr->handle); + + ret = execute_ioctl(comp_cntr->context, cmdb); + if (verbs_is_destroy_err(&ret)) + return ret; + + return 0; +} + +static int ibv_icmd_modify_comp_cntr(struct ibv_comp_cntr *comp_cntr, + uint8_t entry, uint8_t op, uint64_t value) +{ + DECLARE_COMMAND_BUFFER(cmdb, UVERBS_OBJECT_COMP_CNTR, UVERBS_METHOD_COMP_CNTR_MODIFY, 4); + + fill_attr_in_obj(cmdb, UVERBS_ATTR_MODIFY_COMP_CNTR_HANDLE, comp_cntr->handle); + fill_attr_const_in(cmdb, UVERBS_ATTR_MODIFY_COMP_CNTR_ENTRY, entry); + fill_attr_const_in(cmdb, UVERBS_ATTR_MODIFY_COMP_CNTR_OP, op); + fill_attr_in_uint64(cmdb, UVERBS_ATTR_MODIFY_COMP_CNTR_VALUE, value); + + return execute_ioctl(comp_cntr->context, cmdb); +} + +int ibv_cmd_set_comp_cntr(struct ibv_comp_cntr *comp_cntr, uint64_t value) +{ + return ibv_icmd_modify_comp_cntr(comp_cntr, IB_UVERBS_COMP_CNTR_ENTRY_COMP, + IB_UVERBS_COMP_CNTR_MODIFY_OP_SET, value); +} + +int ibv_cmd_set_err_comp_cntr(struct ibv_comp_cntr *comp_cntr, uint64_t value) +{ + return ibv_icmd_modify_comp_cntr(comp_cntr, IB_UVERBS_COMP_CNTR_ENTRY_ERR, + IB_UVERBS_COMP_CNTR_MODIFY_OP_SET, value); +} + +int ibv_cmd_inc_comp_cntr(struct ibv_comp_cntr *comp_cntr, uint64_t amount) +{ + return ibv_icmd_modify_comp_cntr(comp_cntr, IB_UVERBS_COMP_CNTR_ENTRY_COMP, + IB_UVERBS_COMP_CNTR_MODIFY_OP_INC, amount); +} + +int ibv_cmd_inc_err_comp_cntr(struct ibv_comp_cntr *comp_cntr, uint64_t amount) +{ + return ibv_icmd_modify_comp_cntr(comp_cntr, IB_UVERBS_COMP_CNTR_ENTRY_ERR, + IB_UVERBS_COMP_CNTR_MODIFY_OP_INC, amount); +} + +static int ibv_icmd_read_comp_cntr(struct ibv_comp_cntr *comp_cntr, + uint8_t entry, uint64_t *value) +{ + DECLARE_COMMAND_BUFFER(cmdb, UVERBS_OBJECT_COMP_CNTR, UVERBS_METHOD_COMP_CNTR_READ, 3); + + fill_attr_in_obj(cmdb, UVERBS_ATTR_READ_COMP_CNTR_HANDLE, comp_cntr->handle); + fill_attr_const_in(cmdb, UVERBS_ATTR_READ_COMP_CNTR_ENTRY, entry); + fill_attr_out_ptr(cmdb, UVERBS_ATTR_READ_COMP_CNTR_RESP_VALUE, value); + + return execute_ioctl(comp_cntr->context, cmdb); +} + +int ibv_cmd_read_comp_cntr(struct ibv_comp_cntr *comp_cntr, uint64_t *value) +{ + return ibv_icmd_read_comp_cntr(comp_cntr, IB_UVERBS_COMP_CNTR_ENTRY_COMP, value); +} + +int ibv_cmd_read_err_comp_cntr(struct ibv_comp_cntr *comp_cntr, uint64_t *value) +{ + return ibv_icmd_read_comp_cntr(comp_cntr, IB_UVERBS_COMP_CNTR_ENTRY_ERR, value); +} + +int ibv_cmd_qp_attach_comp_cntr(struct ibv_qp *qp, struct ibv_comp_cntr *comp_cntr, + struct ibv_qp_attach_comp_cntr_attr *attr) +{ + DECLARE_COMMAND_BUFFER(cmdb, UVERBS_OBJECT_QP, UVERBS_METHOD_QP_ATTACH_COMP_CNTR, 3); + uint32_t op_mask = 0; + + fill_attr_in_obj(cmdb, UVERBS_ATTR_QP_ATTACH_COMP_CNTR_HANDLE, qp->handle); + fill_attr_in_obj(cmdb, UVERBS_ATTR_QP_ATTACH_COMP_CNTR_CNTR_HANDLE, comp_cntr->handle); + + if (attr->op_mask & IBV_QP_ATTACH_COMP_CNTR_OP_SEND) + op_mask |= IB_UVERBS_QP_ATTACH_COMP_CNTR_OP_SEND; + if (attr->op_mask & IBV_QP_ATTACH_COMP_CNTR_OP_RECV) + op_mask |= IB_UVERBS_QP_ATTACH_COMP_CNTR_OP_RECV; + if (attr->op_mask & IBV_QP_ATTACH_COMP_CNTR_OP_RDMA_READ) + op_mask |= IB_UVERBS_QP_ATTACH_COMP_CNTR_OP_RDMA_READ; + if (attr->op_mask & IBV_QP_ATTACH_COMP_CNTR_OP_REMOTE_RDMA_READ) + op_mask |= IB_UVERBS_QP_ATTACH_COMP_CNTR_OP_REMOTE_RDMA_READ; + if (attr->op_mask & IBV_QP_ATTACH_COMP_CNTR_OP_RDMA_WRITE) + op_mask |= IB_UVERBS_QP_ATTACH_COMP_CNTR_OP_RDMA_WRITE; + if (attr->op_mask & IBV_QP_ATTACH_COMP_CNTR_OP_REMOTE_RDMA_WRITE) + op_mask |= IB_UVERBS_QP_ATTACH_COMP_CNTR_OP_REMOTE_RDMA_WRITE; + + fill_attr_in_uint32(cmdb, UVERBS_ATTR_QP_ATTACH_COMP_CNTR_OP_MASK, op_mask); + + return execute_ioctl(qp->context, cmdb); +}
diff --git a/libibverbs/cmd_device.c b/libibverbs/cmd_device.c index ba22372..a7b4072 100644 --- a/libibverbs/cmd_device.c +++ b/libibverbs/cmd_device.c
@@ -698,3 +698,43 @@ return 0; } + +int ibv_cmd_query_comp_cntr_caps(struct ibv_context *context, + struct ibv_comp_cntr_caps *caps, + size_t caps_size) +{ + DECLARE_COMMAND_BUFFER(cmdb, UVERBS_OBJECT_DEVICE, + UVERBS_METHOD_QUERY_COMP_CNTR_CAPS, 3); + uint32_t supported_qp_attach_ops; + int ret; + + if (caps_size < sizeof(struct ibv_comp_cntr_caps)) + return EINVAL; + + fill_attr_out_ptr(cmdb, UVERBS_ATTR_QUERY_COMP_CNTR_CAPS_MAX_COUNTERS, + &caps->max_counters); + fill_attr_out_ptr(cmdb, UVERBS_ATTR_QUERY_COMP_CNTR_CAPS_MAX_VALUE, + &caps->max_value); + fill_attr_out_ptr(cmdb, UVERBS_ATTR_QUERY_COMP_CNTR_CAPS_SUPPORTED_QP_ATTACH_OPS, + &supported_qp_attach_ops); + + ret = execute_ioctl(context, cmdb); + if (ret) + return ret; + + caps->supported_qp_attach_ops = 0; + if (supported_qp_attach_ops & IB_UVERBS_QP_ATTACH_COMP_CNTR_OP_SEND) + caps->supported_qp_attach_ops |= IBV_QP_ATTACH_COMP_CNTR_OP_SEND; + if (supported_qp_attach_ops & IB_UVERBS_QP_ATTACH_COMP_CNTR_OP_RECV) + caps->supported_qp_attach_ops |= IBV_QP_ATTACH_COMP_CNTR_OP_RECV; + if (supported_qp_attach_ops & IB_UVERBS_QP_ATTACH_COMP_CNTR_OP_RDMA_READ) + caps->supported_qp_attach_ops |= IBV_QP_ATTACH_COMP_CNTR_OP_RDMA_READ; + if (supported_qp_attach_ops & IB_UVERBS_QP_ATTACH_COMP_CNTR_OP_REMOTE_RDMA_READ) + caps->supported_qp_attach_ops |= IBV_QP_ATTACH_COMP_CNTR_OP_REMOTE_RDMA_READ; + if (supported_qp_attach_ops & IB_UVERBS_QP_ATTACH_COMP_CNTR_OP_RDMA_WRITE) + caps->supported_qp_attach_ops |= IBV_QP_ATTACH_COMP_CNTR_OP_RDMA_WRITE; + if (supported_qp_attach_ops & IB_UVERBS_QP_ATTACH_COMP_CNTR_OP_REMOTE_RDMA_WRITE) + caps->supported_qp_attach_ops |= IBV_QP_ATTACH_COMP_CNTR_OP_REMOTE_RDMA_WRITE; + + return 0; +}
diff --git a/libibverbs/driver.h b/libibverbs/driver.h index ec72c77..1f4ca37 100644 --- a/libibverbs/driver.h +++ b/libibverbs/driver.h
@@ -391,6 +391,8 @@ void (*cq_event)(struct ibv_cq *cq); struct ibv_ah *(*create_ah)(struct ibv_pd *pd, struct ibv_ah_attr *attr); + struct ibv_comp_cntr *(*create_comp_cntr)(struct ibv_context *context, + struct ibv_comp_cntr_init_attr *attr); struct ibv_counters *(*create_counters)(struct ibv_context *context, struct ibv_counters_init_attr *init_attr); struct ibv_cq *(*create_cq)(struct ibv_context *context, int cqe, @@ -424,6 +426,7 @@ int (*dealloc_td)(struct ibv_td *td); int (*dereg_mr)(struct verbs_mr *vmr); int (*destroy_ah)(struct ibv_ah *ah); + int (*destroy_comp_cntr)(struct ibv_comp_cntr *comp_cntr); int (*destroy_counters)(struct ibv_counters *counters); int (*destroy_cq)(struct ibv_cq *cq); int (*destroy_flow)(struct ibv_flow *flow); @@ -445,6 +448,9 @@ uint32_t mr_handle); struct ibv_pd *(*import_pd)(struct ibv_context *context, uint32_t pd_handle); + int (*inc_comp_cntr)(struct ibv_comp_cntr *comp_cntr, uint64_t amount); + int (*inc_err_comp_cntr)(struct ibv_comp_cntr *comp_cntr, + uint64_t amount); int (*modify_cq)(struct ibv_cq *cq, struct ibv_modify_cq_attr *attr); int (*modify_flow_action_esp)(struct ibv_flow_action *action, struct ibv_flow_action_esp_attr *attr); @@ -469,6 +475,12 @@ struct ibv_ops_wr **bad_op); int (*post_srq_recv)(struct ibv_srq *srq, struct ibv_recv_wr *recv_wr, struct ibv_recv_wr **bad_recv_wr); + int (*qp_attach_comp_cntr)(struct ibv_qp *qp, + struct ibv_comp_cntr *comp_cntr, + struct ibv_qp_attach_comp_cntr_attr *attr); + int (*query_comp_cntr_caps)(struct ibv_context *context, + struct ibv_comp_cntr_caps *caps, + size_t caps_size); int (*query_device_ex)(struct ibv_context *context, const struct ibv_query_device_ex_input *input, struct ibv_device_attr_ex *attr, @@ -485,10 +497,13 @@ int (*query_rt_values)(struct ibv_context *context, struct ibv_values_ex *values); int (*query_srq)(struct ibv_srq *srq, struct ibv_srq_attr *srq_attr); + int (*read_comp_cntr)(struct ibv_comp_cntr *comp_cntr, uint64_t *value); int (*read_counters)(struct ibv_counters *counters, uint64_t *counters_value, uint32_t ncounters, uint32_t flags); + int (*read_err_comp_cntr)(struct ibv_comp_cntr *comp_cntr, + uint64_t *value); struct ibv_mr *(*reg_dm_mr)(struct ibv_pd *pd, struct ibv_dm *dm, uint64_t dm_offset, size_t length, unsigned int access); @@ -503,7 +518,10 @@ int (*rereg_mr)(struct verbs_mr *vmr, int flags, struct ibv_pd *pd, void *addr, size_t length, int access); int (*resize_cq)(struct ibv_cq *cq, int cqe); + int (*set_comp_cntr)(struct ibv_comp_cntr *comp_cntr, uint64_t value); int (*set_ece)(struct ibv_qp *qp, struct ibv_ece *ece); + int (*set_err_comp_cntr)(struct ibv_comp_cntr *comp_cntr, + uint64_t value); void (*unimport_dm)(struct ibv_dm *dm); void (*unimport_mr)(struct ibv_mr *mr); void (*unimport_pd)(struct ibv_pd *pd); @@ -777,6 +795,24 @@ int ibv_cmd_alloc_dmah(struct ibv_context *ctx, struct verbs_dmah *st, struct ibv_dmah_init_attr *attr); int ibv_cmd_free_dmah(struct verbs_dmah *dmah); + +int ibv_cmd_query_comp_cntr_caps(struct ibv_context *context, + struct ibv_comp_cntr_caps *caps, + size_t caps_size); +int ibv_cmd_create_comp_cntr(struct ibv_context *context, + struct ibv_comp_cntr *comp_cntr, + struct ibv_command_buffer *link); +int ibv_cmd_destroy_comp_cntr(struct ibv_comp_cntr *comp_cntr); +int ibv_cmd_inc_comp_cntr(struct ibv_comp_cntr *comp_cntr, uint64_t amount); +int ibv_cmd_inc_err_comp_cntr(struct ibv_comp_cntr *comp_cntr, uint64_t amount); +int ibv_cmd_read_comp_cntr(struct ibv_comp_cntr *comp_cntr, uint64_t *value); +int ibv_cmd_read_err_comp_cntr(struct ibv_comp_cntr *comp_cntr, uint64_t *value); +int ibv_cmd_set_comp_cntr(struct ibv_comp_cntr *comp_cntr, uint64_t value); +int ibv_cmd_set_err_comp_cntr(struct ibv_comp_cntr *comp_cntr, uint64_t value); +int ibv_cmd_qp_attach_comp_cntr(struct ibv_qp *qp, + struct ibv_comp_cntr *comp_cntr, + struct ibv_qp_attach_comp_cntr_attr *attr); + int ibv_cmd_reg_dm_mr(struct ibv_pd *pd, struct verbs_dm *dm, uint64_t offset, size_t length, unsigned int access, struct verbs_mr *vmr,
diff --git a/libibverbs/dummy_ops.c b/libibverbs/dummy_ops.c index a27e229..3eacff3 100644 --- a/libibverbs/dummy_ops.c +++ b/libibverbs/dummy_ops.c
@@ -161,6 +161,13 @@ return NULL; } +static struct ibv_comp_cntr *create_comp_cntr(struct ibv_context *context, + struct ibv_comp_cntr_init_attr *attr) +{ + errno = EOPNOTSUPP; + return NULL; +} + static struct ibv_counters *create_counters(struct ibv_context *context, struct ibv_counters_init_attr *init_attr) { @@ -271,6 +278,11 @@ return EOPNOTSUPP; } +static int destroy_comp_cntr(struct ibv_comp_cntr *comp_cntr) +{ + return EOPNOTSUPP; +} + static int destroy_counters(struct ibv_counters *counters) { return EOPNOTSUPP; @@ -359,6 +371,16 @@ return NULL; } +static int inc_comp_cntr(struct ibv_comp_cntr *comp_cntr, uint64_t amount) +{ + return EOPNOTSUPP; +} + +static int inc_err_comp_cntr(struct ibv_comp_cntr *comp_cntr, uint64_t amount) +{ + return EOPNOTSUPP; +} + static int modify_cq(struct ibv_cq *cq, struct ibv_modify_cq_attr *attr) { return EOPNOTSUPP; @@ -435,6 +457,20 @@ return EOPNOTSUPP; } +static int qp_attach_comp_cntr(struct ibv_qp *qp, + struct ibv_comp_cntr *comp_cntr, + struct ibv_qp_attach_comp_cntr_attr *attr) +{ + return EOPNOTSUPP; +} + +static int query_comp_cntr_caps(struct ibv_context *context, + struct ibv_comp_cntr_caps *caps, + size_t caps_size) +{ + return EOPNOTSUPP; +} + static int query_device_ex(struct ibv_context *context, const struct ibv_query_device_ex_input *input, struct ibv_device_attr_ex *attr, size_t attr_size) @@ -482,6 +518,11 @@ return EOPNOTSUPP; } +static int read_comp_cntr(struct ibv_comp_cntr *comp_cntr, uint64_t *value) +{ + return EOPNOTSUPP; +} + static int read_counters(struct ibv_counters *counters, uint64_t *counters_value, uint32_t ncounters, @@ -490,6 +531,11 @@ return EOPNOTSUPP; } +static int read_err_comp_cntr(struct ibv_comp_cntr *comp_cntr, uint64_t *value) +{ + return EOPNOTSUPP; +} + static struct ibv_mr *reg_dm_mr(struct ibv_pd *pd, struct ibv_dm *dm, uint64_t dm_offset, size_t length, unsigned int access) @@ -578,11 +624,21 @@ return EOPNOTSUPP; } +static int set_comp_cntr(struct ibv_comp_cntr *comp_cntr, uint64_t value) +{ + return EOPNOTSUPP; +} + static int set_ece(struct ibv_qp *qp, struct ibv_ece *ece) { return EOPNOTSUPP; } +static int set_err_comp_cntr(struct ibv_comp_cntr *comp_cntr, uint64_t value) +{ + return EOPNOTSUPP; +} + static void unimport_dm(struct ibv_dm *dm) { } @@ -623,6 +679,7 @@ close_xrcd, cq_event, create_ah, + create_comp_cntr, create_counters, create_cq, create_cq_ex, @@ -640,6 +697,7 @@ dealloc_td, dereg_mr, destroy_ah, + destroy_comp_cntr, destroy_counters, destroy_cq, destroy_flow, @@ -657,6 +715,8 @@ import_dm, import_mr, import_pd, + inc_comp_cntr, + inc_err_comp_cntr, modify_cq, modify_flow_action_esp, modify_qp, @@ -670,6 +730,8 @@ post_send, post_srq_ops, post_srq_recv, + qp_attach_comp_cntr, + query_comp_cntr_caps, query_device_ex, query_ece, query_port, @@ -678,7 +740,9 @@ query_qp_data_in_order, query_rt_values, query_srq, + read_comp_cntr, read_counters, + read_err_comp_cntr, reg_dm_mr, reg_dmabuf_mr, reg_mr, @@ -686,7 +750,9 @@ req_notify_cq, rereg_mr, resize_cq, + set_comp_cntr, set_ece, + set_err_comp_cntr, unimport_dm, unimport_mr, unimport_pd, @@ -758,6 +824,7 @@ SET_PRIV_OP(ctx, create_ah); SET_PRIV_OP(ctx, create_cq); SET_PRIV_OP_IC(vctx, create_cq_ex); + SET_PRIV_OP_IC(vctx, create_comp_cntr); SET_OP2(vctx, ibv_create_flow, create_flow); SET_OP(vctx, create_flow_action_esp); SET_PRIV_OP(ctx, create_qp); @@ -773,6 +840,7 @@ SET_OP(vctx, destroy_counters); SET_PRIV_OP(ctx, dereg_mr); SET_PRIV_OP(ctx, destroy_ah); + SET_PRIV_OP_IC(vctx, destroy_comp_cntr); SET_PRIV_OP(ctx, destroy_cq); SET_OP2(vctx, ibv_destroy_flow, destroy_flow); SET_OP(vctx, destroy_flow_action); @@ -789,6 +857,8 @@ SET_PRIV_OP_IC(vctx, import_dm); SET_PRIV_OP_IC(vctx, import_mr); SET_PRIV_OP_IC(vctx, import_pd); + SET_PRIV_OP_IC(vctx, inc_comp_cntr); + SET_PRIV_OP_IC(vctx, inc_err_comp_cntr); SET_OP(vctx, modify_cq); SET_OP(vctx, modify_flow_action_esp); SET_PRIV_OP(ctx, modify_qp); @@ -802,6 +872,8 @@ SET_OP(ctx, post_send); SET_OP(vctx, post_srq_ops); SET_OP(ctx, post_srq_recv); + SET_PRIV_OP_IC(vctx, qp_attach_comp_cntr); + SET_PRIV_OP_IC(ctx, query_comp_cntr_caps); SET_OP(vctx, query_device_ex); SET_PRIV_OP_IC(vctx, query_ece); SET_PRIV_OP_IC(ctx, query_port); @@ -809,7 +881,9 @@ SET_PRIV_OP(ctx, query_qp); SET_PRIV_OP_IC(ctx, query_qp_data_in_order); SET_OP(vctx, query_rt_values); + SET_PRIV_OP_IC(vctx, read_comp_cntr); SET_OP(vctx, read_counters); + SET_PRIV_OP_IC(vctx, read_err_comp_cntr); SET_PRIV_OP(ctx, query_srq); SET_OP(vctx, reg_dm_mr); SET_PRIV_OP_IC(vctx, reg_dmabuf_mr); @@ -818,7 +892,9 @@ SET_OP(ctx, req_notify_cq); SET_PRIV_OP(ctx, rereg_mr); SET_PRIV_OP(ctx, resize_cq); + SET_PRIV_OP_IC(vctx, set_comp_cntr); SET_PRIV_OP_IC(vctx, set_ece); + SET_PRIV_OP_IC(vctx, set_err_comp_cntr); SET_PRIV_OP_IC(vctx, unimport_dm); SET_PRIV_OP_IC(vctx, unimport_mr); SET_PRIV_OP_IC(vctx, unimport_pd);
diff --git a/libibverbs/examples/devinfo.c b/libibverbs/examples/devinfo.c index 1892ccd..7202284 100644 --- a/libibverbs/examples/devinfo.c +++ b/libibverbs/examples/devinfo.c
@@ -507,10 +507,28 @@ printf("\t\t\t\t\tDelay drop\n"); } +static void print_comp_cntr_attach_ops(uint32_t ops) +{ + printf("\tcomp_cntr_caps:\n"); + if (ops & IBV_QP_ATTACH_COMP_CNTR_OP_SEND) + printf("\t\t\t\t\tQP_ATTACH_SEND\n"); + if (ops & IBV_QP_ATTACH_COMP_CNTR_OP_RECV) + printf("\t\t\t\t\tQP_ATTACH_RECV\n"); + if (ops & IBV_QP_ATTACH_COMP_CNTR_OP_RDMA_READ) + printf("\t\t\t\t\tQP_ATTACH_RDMA_READ\n"); + if (ops & IBV_QP_ATTACH_COMP_CNTR_OP_REMOTE_RDMA_READ) + printf("\t\t\t\t\tQP_ATTACH_REMOTE_RDMA_READ\n"); + if (ops & IBV_QP_ATTACH_COMP_CNTR_OP_RDMA_WRITE) + printf("\t\t\t\t\tQP_ATTACH_RDMA_WRITE\n"); + if (ops & IBV_QP_ATTACH_COMP_CNTR_OP_REMOTE_RDMA_WRITE) + printf("\t\t\t\t\tQP_ATTACH_REMOTE_RDMA_WRITE\n"); +} + static int print_hca_cap(struct ibv_device *ib_dev, uint8_t ib_port) { struct ibv_context *ctx; struct ibv_device_attr_ex device_attr = {}; + struct ibv_comp_cntr_caps cc_caps = {}; struct ibv_port_attr port_attr; uint64_t port_speed; int rc = 0; @@ -592,6 +610,10 @@ printf("\tmax_srq_sge:\t\t\t%d\n", device_attr.orig_attr.max_srq_sge); } printf("\tmax_pkeys:\t\t\t%d\n", device_attr.orig_attr.max_pkeys); + if (!ibv_query_comp_cntr_caps(ctx, &cc_caps)) { + printf("\tmax_comp_cntr:\t\t\t%d\n", cc_caps.max_counters); + print_comp_cntr_attach_ops(cc_caps.supported_qp_attach_ops); + } printf("\tlocal_ca_ack_delay:\t\t%d\n", device_attr.orig_attr.local_ca_ack_delay); print_odp_caps(&device_attr);
diff --git a/libibverbs/libibverbs.map.in b/libibverbs/libibverbs.map.in index 7329bce..e7a1598 100644 --- a/libibverbs/libibverbs.map.in +++ b/libibverbs/libibverbs.map.in
@@ -186,7 +186,17 @@ IBVERBS_1.18 { global: + _ibv_query_comp_cntr_caps; + ibv_create_comp_cntr; + ibv_destroy_comp_cntr; ibv_export_buf_dmabuf_fd; + ibv_inc_comp_cntr; + ibv_inc_err_comp_cntr; + ibv_qp_attach_comp_cntr; + ibv_read_comp_cntr; + ibv_read_err_comp_cntr; + ibv_set_comp_cntr; + ibv_set_err_comp_cntr; } IBVERBS_1.17; /* If any symbols in this stanza change ABI then the entire staza gets a new symbol @@ -207,6 +217,7 @@ ibv_cmd_attach_mcast; ibv_cmd_close_xrcd; ibv_cmd_create_ah; + ibv_cmd_create_comp_cntr; ibv_cmd_create_counters; ibv_cmd_create_cq; ibv_cmd_create_cq_ex; @@ -224,6 +235,7 @@ ibv_cmd_dealloc_pd; ibv_cmd_dereg_mr; ibv_cmd_destroy_ah; + ibv_cmd_destroy_comp_cntr; ibv_cmd_destroy_counters; ibv_cmd_destroy_cq; ibv_cmd_destroy_flow; @@ -237,6 +249,8 @@ ibv_cmd_free_dm; ibv_cmd_free_dmah; ibv_cmd_get_context; + ibv_cmd_inc_comp_cntr; + ibv_cmd_inc_err_comp_cntr; ibv_cmd_modify_cq; ibv_cmd_modify_flow_action_esp; ibv_cmd_modify_qp; @@ -249,6 +263,8 @@ ibv_cmd_post_recv; ibv_cmd_post_send; ibv_cmd_post_srq_recv; + ibv_cmd_qp_attach_comp_cntr; + ibv_cmd_query_comp_cntr_caps; ibv_cmd_query_context; ibv_cmd_query_device_any; ibv_cmd_query_mr; @@ -256,7 +272,9 @@ ibv_cmd_query_port_speed; ibv_cmd_query_qp; ibv_cmd_query_srq; + ibv_cmd_read_comp_cntr; ibv_cmd_read_counters; + ibv_cmd_read_err_comp_cntr; ibv_cmd_reg_dm_mr; ibv_cmd_reg_dmabuf_mr; ibv_cmd_reg_mr; @@ -264,6 +282,8 @@ ibv_cmd_req_notify_cq; ibv_cmd_rereg_mr; ibv_cmd_resize_cq; + ibv_cmd_set_comp_cntr; + ibv_cmd_set_err_comp_cntr; ibv_dmabuf_heap_alloc; ibv_dmabuf_heap_cc_shared_init; ibv_dmabuf_heap_destroy;
diff --git a/libibverbs/verbs.c b/libibverbs/verbs.c index bb5233b..d91eb42 100644 --- a/libibverbs/verbs.c +++ b/libibverbs/verbs.c
@@ -792,6 +792,54 @@ pthread_mutex_unlock(&cq->mutex); } +int _ibv_query_comp_cntr_caps(struct ibv_context *context, + struct ibv_comp_cntr_caps *caps, size_t caps_size) +{ + memset(caps, 0, caps_size); + return get_ops(context)->query_comp_cntr_caps(context, caps, caps_size); +} + +struct ibv_comp_cntr *ibv_create_comp_cntr(struct ibv_context *context, + struct ibv_comp_cntr_init_attr *cc_attr) +{ + return get_ops(context)->create_comp_cntr(context, cc_attr); +} + +int ibv_destroy_comp_cntr(struct ibv_comp_cntr *comp_cntr) +{ + return get_ops(comp_cntr->context)->destroy_comp_cntr(comp_cntr); +} + +int ibv_set_comp_cntr(struct ibv_comp_cntr *comp_cntr, uint64_t value) +{ + return get_ops(comp_cntr->context)->set_comp_cntr(comp_cntr, value); +} + +int ibv_set_err_comp_cntr(struct ibv_comp_cntr *comp_cntr, uint64_t value) +{ + return get_ops(comp_cntr->context)->set_err_comp_cntr(comp_cntr, value); +} + +int ibv_inc_comp_cntr(struct ibv_comp_cntr *comp_cntr, uint64_t amount) +{ + return get_ops(comp_cntr->context)->inc_comp_cntr(comp_cntr, amount); +} + +int ibv_inc_err_comp_cntr(struct ibv_comp_cntr *comp_cntr, uint64_t amount) +{ + return get_ops(comp_cntr->context)->inc_err_comp_cntr(comp_cntr, amount); +} + +int ibv_read_comp_cntr(struct ibv_comp_cntr *comp_cntr, uint64_t *value) +{ + return get_ops(comp_cntr->context)->read_comp_cntr(comp_cntr, value); +} + +int ibv_read_err_comp_cntr(struct ibv_comp_cntr *comp_cntr, uint64_t *value) +{ + return get_ops(comp_cntr->context)->read_err_comp_cntr(comp_cntr, value); +} + LATEST_SYMVER_FUNC(ibv_create_srq, 1_1, "IBVERBS_1.1", struct ibv_srq *, struct ibv_pd *pd, @@ -919,6 +967,12 @@ return 0; } +int ibv_qp_attach_comp_cntr(struct ibv_qp *qp, struct ibv_comp_cntr *comp_cntr, + struct ibv_qp_attach_comp_cntr_attr *attr) +{ + return get_ops(qp->context)->qp_attach_comp_cntr(qp, comp_cntr, attr); +} + LATEST_SYMVER_FUNC(ibv_destroy_qp, 1_1, "IBVERBS_1.1", int, struct ibv_qp *qp)
diff --git a/libibverbs/verbs.h b/libibverbs/verbs.h index 83c9c90..cad28af 100644 --- a/libibverbs/verbs.h +++ b/libibverbs/verbs.h
@@ -3064,13 +3064,19 @@ return vctx->modify_cq(cq, attr); } +int _ibv_query_comp_cntr_caps(struct ibv_context *context, + struct ibv_comp_cntr_caps *caps, size_t caps_size); + /** * ibv_query_comp_cntr_caps - Query completion counter capabilities * @context: Device context. * @caps: Output capabilities struct. */ -int ibv_query_comp_cntr_caps(struct ibv_context *context, - struct ibv_comp_cntr_caps *caps); +static inline int ibv_query_comp_cntr_caps(struct ibv_context *context, + struct ibv_comp_cntr_caps *caps) +{ + return _ibv_query_comp_cntr_caps(context, caps, sizeof(*caps)); +} /** * ibv_create_comp_cntr - Create a completion counter