From: Aharon Landau <aharonl@xxxxxxxxxx> Add an alloc_op_port_stats() API, as well as related structures, to support per-port op_stats allocation during counter module initialization. Signed-off-by: Aharon Landau <aharonl@xxxxxxxxxx> Signed-off-by: Neta Ostrovsky <netao@xxxxxxxxxx> Signed-off-by: Mark Zhang <markzhang@xxxxxxxxxx> --- drivers/infiniband/core/counters.c | 18 ++++++++++++++++++ drivers/infiniband/core/device.c | 1 + include/rdma/ib_verbs.h | 24 ++++++++++++++++++++++++ include/rdma/rdma_counter.h | 1 + 4 files changed, 44 insertions(+) diff --git a/drivers/infiniband/core/counters.c b/drivers/infiniband/core/counters.c index df9e6c5e4ddf..b8b6db98bfdf 100644 --- a/drivers/infiniband/core/counters.c +++ b/drivers/infiniband/core/counters.c @@ -611,6 +611,15 @@ void rdma_counter_init(struct ib_device *dev) port_counter->hstats = dev->ops.alloc_hw_port_stats(dev, port); if (!port_counter->hstats) goto fail; + + if (dev->ops.alloc_op_port_stats) { + port_counter->opstats = + dev->ops.alloc_op_port_stats(dev, port); + if (!port_counter->opstats) + goto fail; + + mutex_init(&port_counter->opstats->lock); + } } return; @@ -618,6 +627,11 @@ void rdma_counter_init(struct ib_device *dev) fail: for (i = port; i >= rdma_start_port(dev); i--) { port_counter = &dev->port_data[port].port_counter; + if (port_counter && port_counter->opstats) { + mutex_destroy(&port_counter->opstats->lock); + kfree(port_counter->opstats); + port_counter->opstats = NULL; + } kfree(port_counter->hstats); port_counter->hstats = NULL; mutex_destroy(&port_counter->lock); @@ -631,6 +645,10 @@ void rdma_counter_release(struct ib_device *dev) rdma_for_each_port(dev, port) { port_counter = &dev->port_data[port].port_counter; + if (port_counter && port_counter->opstats) { + mutex_destroy(&port_counter->opstats->lock); + kfree(port_counter->opstats); + } kfree(port_counter->hstats); mutex_destroy(&port_counter->lock); } diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c index f4814bb7f082..23e1ae50b2e4 100644 --- a/drivers/infiniband/core/device.c +++ b/drivers/infiniband/core/device.c @@ -2597,6 +2597,7 @@ void ib_set_device_ops(struct ib_device *dev, const struct ib_device_ops *ops) SET_DEVICE_OP(dev_ops, alloc_mr); SET_DEVICE_OP(dev_ops, alloc_mr_integrity); SET_DEVICE_OP(dev_ops, alloc_mw); + SET_DEVICE_OP(dev_ops, alloc_op_port_stats); SET_DEVICE_OP(dev_ops, alloc_pd); SET_DEVICE_OP(dev_ops, alloc_rdma_netdev); SET_DEVICE_OP(dev_ops, alloc_ucontext); diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index aa7806335cba..e8763d336df1 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -598,6 +598,28 @@ static inline struct rdma_hw_stats *rdma_alloc_hw_stats_struct( return stats; } +/** + * struct rdma_op_counter + * @name - The name of the counter + * @value - The value of the counter + */ +struct rdma_op_counter { + const char *name; + u64 value; +}; + +/** + * struct rdma_op_stats + * @lock - Mutex to protect parallel write access to opstats of counters + * @num_opcounters - How many optional counters there are + * @opcounters - Array of optional counters that are filled in by the drivers + */ +struct rdma_op_stats { + /* Hold this mutex when accessing optional counter */ + struct mutex lock; + int num_opcounters; + struct rdma_op_counter opcounters[]; +}; /* Define bits for the various functionality this port needs to be supported by * the core. @@ -2568,6 +2590,8 @@ struct ib_device_ops { */ int (*get_hw_stats)(struct ib_device *device, struct rdma_hw_stats *stats, u32 port, int index); + struct rdma_op_stats *(*alloc_op_port_stats)(struct ib_device *device, + u32 port_num); /** * Allows rdma drivers to add their own restrack attributes. diff --git a/include/rdma/rdma_counter.h b/include/rdma/rdma_counter.h index 0295b22cd1cd..3531c5061718 100644 --- a/include/rdma/rdma_counter.h +++ b/include/rdma/rdma_counter.h @@ -29,6 +29,7 @@ struct rdma_port_counter { struct rdma_counter_mode mode; struct rdma_hw_stats *hstats; unsigned int num_counters; + struct rdma_op_stats *opstats; struct mutex lock; }; -- 2.26.2