RDMA/core: Add a helper API rdma_free_hw_stats_struct
authorMark Zhang <markzhang@nvidia.com>
Fri, 8 Oct 2021 12:24:30 +0000 (15:24 +0300)
committerJason Gunthorpe <jgg@nvidia.com>
Tue, 12 Oct 2021 15:48:04 +0000 (12:48 -0300)
Add a new API rdma_free_hw_stats_struct to pair with
rdma_alloc_hw_stats_struct (which is also de-inlined).

This will be useful when there are more alloc/free works in following
patches.

Link: https://lore.kernel.org/r/20211008122439.166063-5-markzhang@nvidia.com
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: Mark Zhang <markzhang@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
drivers/infiniband/core/counters.c
drivers/infiniband/core/sysfs.c
drivers/infiniband/core/verbs.c
include/rdma/ib_verbs.h

index df9e6c5..331cd29 100644 (file)
@@ -165,7 +165,7 @@ static struct rdma_counter *alloc_and_bind(struct ib_device *dev, u32 port,
        return counter;
 
 err_mode:
-       kfree(counter->stats);
+       rdma_free_hw_stats_struct(counter->stats);
 err_stats:
        rdma_restrack_put(&counter->res);
        kfree(counter);
@@ -186,7 +186,7 @@ static void rdma_counter_free(struct rdma_counter *counter)
        mutex_unlock(&port_counter->lock);
 
        rdma_restrack_del(&counter->res);
-       kfree(counter->stats);
+       rdma_free_hw_stats_struct(counter->stats);
        kfree(counter);
 }
 
@@ -618,7 +618,7 @@ 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;
-               kfree(port_counter->hstats);
+               rdma_free_hw_stats_struct(port_counter->hstats);
                port_counter->hstats = NULL;
                mutex_destroy(&port_counter->lock);
        }
@@ -631,7 +631,7 @@ void rdma_counter_release(struct ib_device *dev)
 
        rdma_for_each_port(dev, port) {
                port_counter = &dev->port_data[port].port_counter;
-               kfree(port_counter->hstats);
+               rdma_free_hw_stats_struct(port_counter->hstats);
                mutex_destroy(&port_counter->lock);
        }
 }
index c3663cf..8d831d4 100644 (file)
@@ -755,7 +755,7 @@ static void ib_port_release(struct kobject *kobj)
        for (i = 0; i != ARRAY_SIZE(port->groups); i++)
                kfree(port->groups[i].attrs);
        if (port->hw_stats_data)
-               kfree(port->hw_stats_data->stats);
+               rdma_free_hw_stats_struct(port->hw_stats_data->stats);
        kfree(port->hw_stats_data);
        kfree(port);
 }
@@ -919,14 +919,14 @@ alloc_hw_stats_device(struct ib_device *ibdev)
 err_free_data:
        kfree(data);
 err_free_stats:
-       kfree(stats);
+       rdma_free_hw_stats_struct(stats);
        return ERR_PTR(-ENOMEM);
 }
 
 void ib_device_release_hw_stats(struct hw_stats_device_data *data)
 {
        kfree(data->group.attrs);
-       kfree(data->stats);
+       rdma_free_hw_stats_struct(data->stats);
        kfree(data);
 }
 
@@ -1018,7 +1018,7 @@ alloc_hw_stats_port(struct ib_port *port, struct attribute_group *group)
 err_free_data:
        kfree(data);
 err_free_stats:
-       kfree(stats);
+       rdma_free_hw_stats_struct(stats);
        return ERR_PTR(-ENOMEM);
 }
 
index 89a2b21..8e72290 100644 (file)
@@ -2976,3 +2976,38 @@ bool __rdma_block_iter_next(struct ib_block_iter *biter)
        return true;
 }
 EXPORT_SYMBOL(__rdma_block_iter_next);
+
+/**
+ * rdma_alloc_hw_stats_struct - Helper function to allocate dynamic struct
+ *   for the drivers.
+ * @descs: array of static descriptors
+ * @num_counters: number of elements in array
+ * @lifespan: milliseconds between updates
+ */
+struct rdma_hw_stats *rdma_alloc_hw_stats_struct(
+       const struct rdma_stat_desc *descs, int num_counters,
+       unsigned long lifespan)
+{
+       struct rdma_hw_stats *stats;
+
+       stats = kzalloc(struct_size(stats, value, num_counters), GFP_KERNEL);
+       if (!stats)
+               return NULL;
+
+       stats->descs = descs;
+       stats->num_counters = num_counters;
+       stats->lifespan = msecs_to_jiffies(lifespan);
+
+       return stats;
+}
+EXPORT_SYMBOL(rdma_alloc_hw_stats_struct);
+
+/**
+ * rdma_free_hw_stats_struct - Helper function to release rdma_hw_stats
+ * @stats: statistics to release
+ */
+void rdma_free_hw_stats_struct(struct rdma_hw_stats *stats)
+{
+       kfree(stats);
+}
+EXPORT_SYMBOL(rdma_free_hw_stats_struct);
index aa1e102..938c0c0 100644 (file)
@@ -582,31 +582,12 @@ struct rdma_hw_stats {
 };
 
 #define RDMA_HW_STATS_DEFAULT_LIFESPAN 10
-/**
- * rdma_alloc_hw_stats_struct - Helper function to allocate dynamic struct
- *   for drivers.
- * @descs - Array of static descriptors
- * @num_counters - How many elements in array
- * @lifespan - How many milliseconds between updates
- */
-static inline struct rdma_hw_stats *rdma_alloc_hw_stats_struct(
-               const struct rdma_stat_desc *descs, int num_counters,
-               unsigned long lifespan)
-{
-       struct rdma_hw_stats *stats;
 
-       stats = kzalloc(sizeof(*stats) + num_counters * sizeof(u64),
-                       GFP_KERNEL);
-       if (!stats)
-               return NULL;
-
-       stats->descs = descs;
-       stats->num_counters = num_counters;
-       stats->lifespan = msecs_to_jiffies(lifespan);
-
-       return stats;
-}
+struct rdma_hw_stats *rdma_alloc_hw_stats_struct(
+       const struct rdma_stat_desc *descs, int num_counters,
+       unsigned long lifespan);
 
+void rdma_free_hw_stats_struct(struct rdma_hw_stats *stats);
 
 /* Define bits for the various functionality this port needs to be supported by
  * the core.