@@ -29,6 +29,7 @@ rdma_library(ibverbs "${CMAKE_CURRENT_BINARY_DIR}/libibverbs.map"
# See Documentation/versioning.md
1 1.1.${PACKAGE_VERSION}
cmd.c
+ cmd_counters.c
cmd_cq.c
cmd_dm.c
cmd_fallback.c
new file mode 100644
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2018 Mellanox Technologies, Ltd. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <infiniband/cmd_ioctl.h>
+#include <rdma/ib_user_ioctl_cmds.h>
+#include <infiniband/driver.h>
+
+int ibv_cmd_create_counters(struct ibv_context *context,
+ struct ibv_counters_init_attr *init_attr,
+ struct verbs_counters *vcounters,
+ struct ibv_command_buffer *link)
+{
+ DECLARE_COMMAND_BUFFER_LINK(cmd, UVERBS_OBJECT_COUNTERS,
+ UVERBS_METHOD_COUNTERS_CREATE,
+ 1,
+ link);
+ struct ib_uverbs_attr *handle =
+ fill_attr_out_obj(cmd, UVERBS_ATTR_CREATE_COUNTERS_HANDLE);
+ int ret;
+
+ if (!check_comp_mask(init_attr->comp_mask, 0))
+ return EOPNOTSUPP;
+
+ ret = execute_ioctl(context, cmd);
+ if (ret)
+ return ret;
+
+ vcounters->counters.context = context;
+ vcounters->handle = read_attr_obj(UVERBS_ATTR_CREATE_COUNTERS_HANDLE, handle);
+
+ return 0;
+}
+
+int ibv_cmd_destroy_counters(struct verbs_counters *vcounters)
+{
+ DECLARE_COMMAND_BUFFER(cmd, UVERBS_OBJECT_COUNTERS,
+ UVERBS_METHOD_COUNTERS_DESTROY,
+ 1);
+
+ fill_attr_in_obj(cmd, UVERBS_ATTR_DESTROY_COUNTERS_HANDLE, vcounters->handle);
+ return execute_ioctl(vcounters->counters.context, cmd);
+}
@@ -188,6 +188,11 @@ struct verbs_device {
struct verbs_sysfs_dev *sysfs;
};
+struct verbs_counters {
+ struct ibv_counters counters;
+ uint32_t handle;
+};
+
/*
* Must change the PRIVATE IBVERBS_PRIVATE_ symbol if this is changed. This is
* the union of every op the driver can support. If new elements are added to
@@ -214,6 +219,8 @@ struct verbs_context_ops {
void (*cq_event)(struct ibv_cq *cq);
struct ibv_ah *(*create_ah)(struct ibv_pd *pd,
struct ibv_ah_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,
struct ibv_comp_channel *channel,
int comp_vector);
@@ -244,6 +251,7 @@ struct verbs_context_ops {
int (*dealloc_td)(struct ibv_td *td);
int (*dereg_mr)(struct ibv_mr *mr);
int (*destroy_ah)(struct ibv_ah *ah);
+ int (*destroy_counters)(struct ibv_counters *counters);
int (*destroy_cq)(struct ibv_cq *cq);
int (*destroy_flow)(struct ibv_flow *flow);
int (*destroy_flow_action)(struct ibv_flow_action *action);
@@ -526,6 +534,11 @@ int ibv_cmd_create_rwq_ind_table(struct ibv_context *context,
size_t resp_core_size,
size_t resp_size);
int ibv_cmd_destroy_rwq_ind_table(struct ibv_rwq_ind_table *rwq_ind_table);
+int ibv_cmd_create_counters(struct ibv_context *context,
+ struct ibv_counters_init_attr *init_attr,
+ struct verbs_counters *vcounters,
+ struct ibv_command_buffer *link);
+int ibv_cmd_destroy_counters(struct verbs_counters *vcounters);
int ibv_dontfork_range(void *base, size_t size);
int ibv_dofork_range(void *base, size_t size);
int ibv_cmd_alloc_dm(struct ibv_context *ctx,
@@ -98,6 +98,13 @@ static struct ibv_ah *create_ah(struct ibv_pd *pd, struct ibv_ah_attr *attr)
return NULL;
}
+static struct ibv_counters *create_counters(struct ibv_context *context,
+ struct ibv_counters_init_attr *init_attr)
+{
+ errno = ENOSYS;
+ return NULL;
+}
+
static struct ibv_cq *create_cq(struct ibv_context *context, int cqe,
struct ibv_comp_channel *channel,
int comp_vector)
@@ -196,6 +203,11 @@ static int destroy_ah(struct ibv_ah *ah)
return ENOSYS;
}
+static int destroy_counters(struct ibv_counters *counters)
+{
+ return ENOSYS;
+}
+
static int destroy_cq(struct ibv_cq *cq)
{
return ENOSYS;
@@ -414,6 +426,7 @@ const struct verbs_context_ops verbs_dummy_ops = {
close_xrcd,
cq_event,
create_ah,
+ create_counters,
create_cq,
create_cq_ex,
create_flow,
@@ -429,6 +442,7 @@ const struct verbs_context_ops verbs_dummy_ops = {
dealloc_td,
dereg_mr,
destroy_ah,
+ destroy_counters,
destroy_cq,
destroy_flow,
destroy_flow_action,
@@ -498,6 +512,7 @@ void verbs_set_ops(struct verbs_context *vctx,
SET_OP(vctx, close_xrcd);
SET_OP(ctx, cq_event);
SET_OP(ctx, create_ah);
+ SET_OP(vctx, create_counters);
SET_OP(ctx, create_cq);
SET_OP(vctx, create_cq_ex);
SET_OP2(vctx, ibv_create_flow, create_flow);
@@ -513,6 +528,7 @@ void verbs_set_ops(struct verbs_context *vctx,
SET_OP(vctx, dealloc_td);
SET_OP(ctx, dereg_mr);
SET_OP(ctx, destroy_ah);
+ SET_OP(vctx, destroy_counters);
SET_OP(ctx, destroy_cq);
SET_OP2(vctx, ibv_destroy_flow, destroy_flow);
SET_OP(vctx, destroy_flow_action);
@@ -121,6 +121,7 @@ IBVERBS_PRIVATE_@IBVERBS_PABI_VERSION@ {
ibv_cmd_attach_mcast;
ibv_cmd_close_xrcd;
ibv_cmd_create_ah;
+ ibv_cmd_create_counters;
ibv_cmd_create_cq;
ibv_cmd_create_cq_ex;
ibv_cmd_create_flow;
@@ -136,6 +137,7 @@ IBVERBS_PRIVATE_@IBVERBS_PABI_VERSION@ {
ibv_cmd_dealloc_pd;
ibv_cmd_dereg_mr;
ibv_cmd_destroy_ah;
+ ibv_cmd_destroy_counters;
ibv_cmd_destroy_cq;
ibv_cmd_destroy_flow;
ibv_cmd_destroy_flow_action;
@@ -10,6 +10,7 @@ rdma_man_pages(
ibv_create_ah.3
ibv_create_ah_from_wc.3
ibv_create_comp_channel.3
+ ibv_create_counters.3.md
ibv_create_cq.3
ibv_create_cq_ex.3
ibv_modify_cq.3
@@ -76,6 +77,7 @@ rdma_alias_man_pages(
ibv_create_ah.3 ibv_destroy_ah.3
ibv_create_ah_from_wc.3 ibv_init_ah_from_wc.3
ibv_create_comp_channel.3 ibv_destroy_comp_channel.3
+ ibv_create_counters.3 ibv_destroy_counters.3
ibv_create_cq.3 ibv_destroy_cq.3
ibv_create_flow.3 ibv_destroy_flow.3
ibv_create_flow_action.3 ibv_destroy_flow_action.3
new file mode 100644
@@ -0,0 +1,97 @@
+---
+date: 2018-04-02
+footer: libibverbs
+header: "Libibverbs Programmer's Manual"
+layout: page
+license: 'Licensed under the OpenIB.org BSD license (FreeBSD Variant) - See COPYING.md'
+section: 3
+title: IBV_CREATE_COUNTERS
+tagline: Verbs
+---
+
+# NAME
+
+**ibv_create_counters**(3), **ibv_destroy_counters**(3) -- Create or destroy a counters handle
+
+# SYNOPSIS
+
+```c
+#include <infiniband/verbs.h>
+
+struct ibv_counters *
+ibv_create_counters(struct ibv_context *context,
+ struct ibv_counters_init_attr *init_attr);
+
+int ibv_destroy_counters(struct ibv_counters *counters);
+```
+
+# DESCRIPTION
+
+**ibv_create_counters**() creates a new counters handle for the RDMA device
+context.
+
+An ibv_counters handle can be attached to a verbs resource (e.g.: QP, WQ, Flow)
+statically when these are created.
+
+For example attach an ibv_counters statically to a Flow (struct ibv_flow) during
+creation of a new Flow by calling **ibv_create_flow()**.
+
+Counters are cleared upon creation and values will be monotonically increasing.
+
+**ibv_destroy_counters**() releases the counters handle, user should
+detach the counters object before destroying it.
+
+# ARGUMENTS
+
+*context*
+: RDMA device context to create the counters on.
+
+*init_attr*
+: Is an ibv_counters_init_attr struct, as defined in verbs.h.
+
+## *init_attr* Argument
+
+```c
+struct ibv_counters_init_attr {
+ int comp_mask;
+};
+```
+
+*comp_mask*
+: Bitmask specifying what fields in the structure are valid.
+
+# RETURN VALUE
+
+**ibv_create_counters**() returns a pointer to the allocated ibv_counters
+object, or NULL if the request fails (and sets errno to indicate the failure
+reason)
+
+**ibv_destroy_counters**() returns 0 on success, or the value of errno on
+failure (which indicates the failure reason)
+
+# ERRORS
+
+ENOSYS
+: **ibv_create_counters**() is not currently supported on this device
+
+ENOMEM
+: **ibv_create_counters**() could not create ibv_counters object, not enough memory
+
+EINVAL
+: invalid parameter supplied **ibv_destroy_counters**()
+
+# EXAMPLE
+
+An example of use of ibv_counters is shown in **ibv_read_counters**(3)
+
+# SEE ALSO
+
+**ibv_attach_counters_point_flow**(3), **ibv_read_counters**(3),
+**ibv_create_flow**(3)
+
+# AUTHORS
+
+Raed Salem <raeds@mellanox.com>
+
+Alex Rosenbaum <alexr@mellanox.com>
+
@@ -1718,6 +1718,14 @@ struct ibv_parent_domain_init_attr {
uint32_t comp_mask;
};
+struct ibv_counters_init_attr {
+ uint32_t comp_mask;
+};
+
+struct ibv_counters {
+ struct ibv_context *context;
+};
+
enum ibv_values_mask {
IBV_VALUES_MASK_RAW_CLOCK = 1 << 0,
IBV_VALUES_MASK_RESERVED = 1 << 1
@@ -1730,6 +1738,9 @@ struct ibv_values_ex {
struct verbs_context {
/* "grows up" - new fields go here */
+ struct ibv_counters *(*create_counters)(struct ibv_context *context,
+ struct ibv_counters_init_attr *init_attr);
+ int (*destroy_counters)(struct ibv_counters *counters);
struct ibv_mr *(*reg_dm_mr)(struct ibv_pd *pd, struct ibv_dm *dm,
uint64_t dm_offset, size_t length,
unsigned int access);
@@ -2797,6 +2808,31 @@ static inline int ibv_is_qpt_supported(uint32_t caps, enum ibv_qp_type qpt)
return !!(caps & (1 << qpt));
}
+static inline struct ibv_counters *ibv_create_counters(struct ibv_context *context,
+ struct ibv_counters_init_attr *init_attr)
+{
+ struct verbs_context *vctx;
+
+ vctx = verbs_get_ctx_op(context, create_counters);
+ if (!vctx) {
+ errno = ENOSYS;
+ return NULL;
+ }
+
+ return vctx->create_counters(context, init_attr);
+}
+
+static inline int ibv_destroy_counters(struct ibv_counters *counters)
+{
+ struct verbs_context *vctx;
+
+ vctx = verbs_get_ctx_op(counters->context, destroy_counters);
+ if (!vctx)
+ return ENOSYS;
+
+ return vctx->destroy_counters(counters);
+}
+
#ifdef __cplusplus
}
#endif