diff mbox

[rdma-core,03/11] verbs: Introduce counters object and its create/destroy verbs

Message ID 1526553577-32273-4-git-send-email-yishaih@mellanox.com (mailing list archive)
State Not Applicable
Headers show

Commit Message

Yishai Hadas May 17, 2018, 10:39 a.m. UTC
From: Raed Salem <raeds@mellanox.com>

Counters instance is allocated on an IB context and belongs to that
context. Upon successful creation the counters can be attached to a
verbs object so that hardware counter instances can be created and read.

Downstream patches in this series will introduce the attach/detach
and the read functionality.

Counters instance can be de-allocated, upon successful destruction the
related hardware resources are released.

Prior to destroy call the user must first make sure that the counters is
not being used by any IB object, e.g. not attached to any of its counted
type.

Signed-off-by: Raed Salem <raeds@mellanox.com>
Signed-off-by: Yishai Hadas <yishaih@mellanox.com>
---
 libibverbs/CMakeLists.txt               |  1 +
 libibverbs/cmd_counters.c               | 71 ++++++++++++++++++++++++
 libibverbs/driver.h                     | 13 +++++
 libibverbs/dummy_ops.c                  | 16 ++++++
 libibverbs/libibverbs.map.in            |  2 +
 libibverbs/man/CMakeLists.txt           |  2 +
 libibverbs/man/ibv_create_counters.3.md | 97 +++++++++++++++++++++++++++++++++
 libibverbs/verbs.h                      | 36 ++++++++++++
 8 files changed, 238 insertions(+)
 create mode 100644 libibverbs/cmd_counters.c
 create mode 100644 libibverbs/man/ibv_create_counters.3.md
diff mbox

Patch

diff --git a/libibverbs/CMakeLists.txt b/libibverbs/CMakeLists.txt
index 4a5832c..6e20c23 100644
--- a/libibverbs/CMakeLists.txt
+++ b/libibverbs/CMakeLists.txt
@@ -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
diff --git a/libibverbs/cmd_counters.c b/libibverbs/cmd_counters.c
new file mode 100644
index 0000000..03e8a8e
--- /dev/null
+++ b/libibverbs/cmd_counters.c
@@ -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);
+}
diff --git a/libibverbs/driver.h b/libibverbs/driver.h
index ca61827..11a6d08 100644
--- a/libibverbs/driver.h
+++ b/libibverbs/driver.h
@@ -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,
diff --git a/libibverbs/dummy_ops.c b/libibverbs/dummy_ops.c
index 2b8b18f..3f4d641 100644
--- a/libibverbs/dummy_ops.c
+++ b/libibverbs/dummy_ops.c
@@ -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);
diff --git a/libibverbs/libibverbs.map.in b/libibverbs/libibverbs.map.in
index 7322fe3..d66a8d3 100644
--- a/libibverbs/libibverbs.map.in
+++ b/libibverbs/libibverbs.map.in
@@ -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;
diff --git a/libibverbs/man/CMakeLists.txt b/libibverbs/man/CMakeLists.txt
index 86dd49d..aa5a07a 100644
--- a/libibverbs/man/CMakeLists.txt
+++ b/libibverbs/man/CMakeLists.txt
@@ -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
diff --git a/libibverbs/man/ibv_create_counters.3.md b/libibverbs/man/ibv_create_counters.3.md
new file mode 100644
index 0000000..d7f062a
--- /dev/null
+++ b/libibverbs/man/ibv_create_counters.3.md
@@ -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>
+
diff --git a/libibverbs/verbs.h b/libibverbs/verbs.h
index eb57824..6eceadc 100644
--- a/libibverbs/verbs.h
+++ b/libibverbs/verbs.h
@@ -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