IB/uverbs: Add read counters support
authorRaed Salem <raeds@mellanox.com>
Thu, 31 May 2018 13:43:34 +0000 (16:43 +0300)
committerLeon Romanovsky <leonro@mellanox.com>
Sat, 2 Jun 2018 04:33:55 +0000 (07:33 +0300)
This patch exposes the read counters verb to user space applications.  By
that verb the user can read the hardware counters which are associated
with the counters object.

The application needs to provide a sufficient memory to hold the
statistics.

Reviewed-by: Yishai Hadas <yishaih@mellanox.com>
Signed-off-by: Raed Salem <raeds@mellanox.com>
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
drivers/infiniband/core/uverbs_std_types_counters.c
include/uapi/rdma/ib_user_ioctl_cmds.h

index 4b6a985aad971888b584fc9f95399d1abb7da2e9..03b182a684a640167d43d19795ae7fdc17f29a48 100644 (file)
@@ -80,6 +80,49 @@ err_create_counters:
        return ret;
 }
 
+static int UVERBS_HANDLER(UVERBS_METHOD_COUNTERS_READ)(struct ib_device *ib_dev,
+                                                      struct ib_uverbs_file *file,
+                                                      struct uverbs_attr_bundle *attrs)
+{
+       struct ib_counters_read_attr read_attr = {};
+       const struct uverbs_attr *uattr;
+       struct ib_counters *counters =
+               uverbs_attr_get_obj(attrs, UVERBS_ATTR_READ_COUNTERS_HANDLE);
+       int ret;
+
+       if (!ib_dev->read_counters)
+               return -EOPNOTSUPP;
+
+       if (!atomic_read(&counters->usecnt))
+               return -EINVAL;
+
+       ret = uverbs_copy_from(&read_attr.flags, attrs,
+                              UVERBS_ATTR_READ_COUNTERS_FLAGS);
+       if (ret)
+               return ret;
+
+       uattr = uverbs_attr_get(attrs, UVERBS_ATTR_READ_COUNTERS_BUFF);
+       read_attr.ncounters = uattr->ptr_attr.len / sizeof(u64);
+       read_attr.counters_buff = kcalloc(read_attr.ncounters,
+                                         sizeof(u64), GFP_KERNEL);
+       if (!read_attr.counters_buff)
+               return -ENOMEM;
+
+       ret = ib_dev->read_counters(counters,
+                                   &read_attr,
+                                   attrs);
+       if (ret)
+               goto err_read;
+
+       ret = uverbs_copy_to(attrs, UVERBS_ATTR_READ_COUNTERS_BUFF,
+                            read_attr.counters_buff,
+                            read_attr.ncounters * sizeof(u64));
+
+err_read:
+       kfree(read_attr.counters_buff);
+       return ret;
+}
+
 static DECLARE_UVERBS_NAMED_METHOD(UVERBS_METHOD_COUNTERS_CREATE,
        &UVERBS_ATTR_IDR(UVERBS_ATTR_CREATE_COUNTERS_HANDLE,
                         UVERBS_OBJECT_COUNTERS,
@@ -93,8 +136,22 @@ static DECLARE_UVERBS_NAMED_METHOD_WITH_HANDLER(UVERBS_METHOD_COUNTERS_DESTROY,
                         UVERBS_ACCESS_DESTROY,
                         UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)));
 
+#define MAX_COUNTERS_BUFF_SIZE USHRT_MAX
+static DECLARE_UVERBS_NAMED_METHOD(UVERBS_METHOD_COUNTERS_READ,
+       &UVERBS_ATTR_IDR(UVERBS_ATTR_READ_COUNTERS_HANDLE,
+                        UVERBS_OBJECT_COUNTERS,
+                        UVERBS_ACCESS_READ,
+                        UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
+       &UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_READ_COUNTERS_BUFF,
+                            UVERBS_ATTR_SIZE(0, MAX_COUNTERS_BUFF_SIZE),
+                            UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
+       &UVERBS_ATTR_PTR_IN(UVERBS_ATTR_READ_COUNTERS_FLAGS,
+                           UVERBS_ATTR_TYPE(__u32),
+                           UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)));
+
 DECLARE_UVERBS_NAMED_OBJECT(UVERBS_OBJECT_COUNTERS,
                            &UVERBS_TYPE_ALLOC_IDR(0, uverbs_free_counters),
                            &UVERBS_METHOD(UVERBS_METHOD_COUNTERS_CREATE),
-                           &UVERBS_METHOD(UVERBS_METHOD_COUNTERS_DESTROY));
+                           &UVERBS_METHOD(UVERBS_METHOD_COUNTERS_DESTROY),
+                           &UVERBS_METHOD(UVERBS_METHOD_COUNTERS_READ));
 
index c28ce62d2e40dd4ddf8892ae5ec9636cfa6a70c2..888ac5975a6c244cd2782b054f1650fbb7c2963a 100644 (file)
@@ -140,9 +140,16 @@ enum uverbs_attrs_destroy_counters_cmd_attr_ids {
        UVERBS_ATTR_DESTROY_COUNTERS_HANDLE,
 };
 
+enum uverbs_attrs_read_counters_cmd_attr_ids {
+       UVERBS_ATTR_READ_COUNTERS_HANDLE,
+       UVERBS_ATTR_READ_COUNTERS_BUFF,
+       UVERBS_ATTR_READ_COUNTERS_FLAGS,
+};
+
 enum uverbs_methods_actions_counters_ops {
        UVERBS_METHOD_COUNTERS_CREATE,
        UVERBS_METHOD_COUNTERS_DESTROY,
+       UVERBS_METHOD_COUNTERS_READ,
 };
 
 #endif