]> git.itanic.dy.fi Git - linux-stable/commitdiff
net/mlx5: Allocate command stats with xarray
authorShay Drory <shayd@nvidia.com>
Thu, 19 Jan 2023 07:10:50 +0000 (09:10 +0200)
committerSaeed Mahameed <saeedm@nvidia.com>
Thu, 27 Jul 2023 18:37:29 +0000 (11:37 -0700)
Command stats is an array with more than 2K entries, which amounts to
~180KB. This is way more than actually needed, as only ~190 entries
are being used.

Therefore, replace the array with xarray.

Signed-off-by: Shay Drory <shayd@nvidia.com>
Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
drivers/net/ethernet/mellanox/mlx5/core/cmd.c
drivers/net/ethernet/mellanox/mlx5/core/debugfs.c
include/linux/mlx5/driver.h

index 45edd5a110c8682e5088e3e4f66640011cd50903..afb348579577c533dbb193df134e5c7793c4ed55 100644 (file)
@@ -1225,8 +1225,8 @@ static int mlx5_cmd_invoke(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *in,
                goto out_free;
 
        ds = ent->ts2 - ent->ts1;
-       if (ent->op < MLX5_CMD_OP_MAX) {
-               stats = &cmd->stats[ent->op];
+       stats = xa_load(&cmd->stats, ent->op);
+       if (stats) {
                spin_lock_irq(&stats->lock);
                stats->sum += ds;
                ++stats->n;
@@ -1695,8 +1695,8 @@ static void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool force
 
                        if (ent->callback) {
                                ds = ent->ts2 - ent->ts1;
-                               if (ent->op < MLX5_CMD_OP_MAX) {
-                                       stats = &cmd->stats[ent->op];
+                               stats = xa_load(&cmd->stats, ent->op);
+                               if (stats) {
                                        spin_lock_irqsave(&stats->lock, flags);
                                        stats->sum += ds;
                                        ++stats->n;
@@ -1923,7 +1923,9 @@ static void cmd_status_log(struct mlx5_core_dev *dev, u16 opcode, u8 status,
        if (!err || !(strcmp(namep, "unknown command opcode")))
                return;
 
-       stats = &dev->cmd.stats[opcode];
+       stats = xa_load(&dev->cmd.stats, opcode);
+       if (!stats)
+               return;
        spin_lock_irq(&stats->lock);
        stats->failed++;
        if (err < 0)
@@ -2189,7 +2191,6 @@ int mlx5_cmd_init(struct mlx5_core_dev *dev)
        struct mlx5_cmd *cmd = &dev->cmd;
        u32 cmd_l;
        int err;
-       int i;
 
        cmd->pool = dma_pool_create("mlx5_cmd", mlx5_core_dma_dev(dev), size, align, 0);
        if (!cmd->pool)
@@ -2209,8 +2210,6 @@ int mlx5_cmd_init(struct mlx5_core_dev *dev)
 
        spin_lock_init(&cmd->alloc_lock);
        spin_lock_init(&cmd->token_lock);
-       for (i = 0; i < MLX5_CMD_OP_MAX; i++)
-               spin_lock_init(&cmd->stats[i].lock);
 
        create_msg_cache(dev);
 
index 9a826fb3ca38a8165822305b2e1c0fe2fc019057..09652dc89115476c060626ec653fe227a933a144 100644 (file)
@@ -188,6 +188,24 @@ static const struct file_operations slots_fops = {
        .read   = slots_read,
 };
 
+static struct mlx5_cmd_stats *
+mlx5_cmdif_alloc_stats(struct xarray *stats_xa, int opcode)
+{
+       struct mlx5_cmd_stats *stats = kzalloc(sizeof(*stats), GFP_KERNEL);
+       int err;
+
+       if (!stats)
+               return NULL;
+
+       err = xa_insert(stats_xa, opcode, stats, GFP_KERNEL);
+       if (err) {
+               kfree(stats);
+               return NULL;
+       }
+       spin_lock_init(&stats->lock);
+       return stats;
+}
+
 void mlx5_cmdif_debugfs_init(struct mlx5_core_dev *dev)
 {
        struct mlx5_cmd_stats *stats;
@@ -200,10 +218,14 @@ void mlx5_cmdif_debugfs_init(struct mlx5_core_dev *dev)
 
        debugfs_create_file("slots_inuse", 0400, *cmd, &dev->cmd, &slots_fops);
 
+       xa_init(&dev->cmd.stats);
+
        for (i = 0; i < MLX5_CMD_OP_MAX; i++) {
-               stats = &dev->cmd.stats[i];
                namep = mlx5_command_str(i);
                if (strcmp(namep, "unknown command opcode")) {
+                       stats = mlx5_cmdif_alloc_stats(&dev->cmd.stats, i);
+                       if (!stats)
+                               continue;
                        stats->root = debugfs_create_dir(namep, *cmd);
 
                        debugfs_create_file("average", 0400, stats->root, stats,
@@ -224,7 +246,13 @@ void mlx5_cmdif_debugfs_init(struct mlx5_core_dev *dev)
 
 void mlx5_cmdif_debugfs_cleanup(struct mlx5_core_dev *dev)
 {
+       struct mlx5_cmd_stats *stats;
+       unsigned long i;
+
        debugfs_remove_recursive(dev->priv.dbg.cmdif_debugfs);
+       xa_for_each(&dev->cmd.stats, i, stats)
+               kfree(stats);
+       xa_destroy(&dev->cmd.stats);
 }
 
 void mlx5_cq_debugfs_init(struct mlx5_core_dev *dev)
index 39c5f4087c39d3e9693d9e0bc7668ca8a51cd1bc..f21703fb75fde747aa393d92d407e70f4b0e04a2 100644 (file)
@@ -322,7 +322,7 @@ struct mlx5_cmd {
        struct mlx5_cmd_debug dbg;
        struct cmd_msg_cache cache[MLX5_NUM_COMMAND_CACHES];
        int checksum_disabled;
-       struct mlx5_cmd_stats stats[MLX5_CMD_OP_MAX];
+       struct xarray stats;
 };
 
 struct mlx5_cmd_mailbox {