net/mlx5: Set command entry semaphore up once got index free
authorMoshe Shemesh <moshe@nvidia.com>
Sun, 5 Dec 2021 10:07:49 +0000 (12:07 +0200)
committerSaeed Mahameed <saeedm@nvidia.com>
Fri, 7 Jan 2022 00:55:42 +0000 (16:55 -0800)
Avoid a race where command work handler may fail to allocate command
entry index, by holding the command semaphore down till command entry
index is being freed.

Fixes: 410bd754cd73 ("net/mlx5: Add retry mechanism to the command entry index allocation")
Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
Reviewed-by: Eran Ben Elisha <eranbe@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
drivers/net/ethernet/mellanox/mlx5/core/cmd.c

index a46284c..f588503 100644 (file)
@@ -148,8 +148,12 @@ static void cmd_ent_put(struct mlx5_cmd_work_ent *ent)
        if (!refcount_dec_and_test(&ent->refcnt))
                return;
 
-       if (ent->idx >= 0)
-               cmd_free_index(ent->cmd, ent->idx);
+       if (ent->idx >= 0) {
+               struct mlx5_cmd *cmd = ent->cmd;
+
+               cmd_free_index(cmd, ent->idx);
+               up(ent->page_queue ? &cmd->pages_sem : &cmd->sem);
+       }
 
        cmd_free_ent(ent);
 }
@@ -1602,8 +1606,6 @@ static void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool force
        vector = vec & 0xffffffff;
        for (i = 0; i < (1 << cmd->log_sz); i++) {
                if (test_bit(i, &vector)) {
-                       struct semaphore *sem;
-
                        ent = cmd->ent_arr[i];
 
                        /* if we already completed the command, ignore it */
@@ -1626,10 +1628,6 @@ static void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool force
                            dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR)
                                cmd_ent_put(ent);
 
-                       if (ent->page_queue)
-                               sem = &cmd->pages_sem;
-                       else
-                               sem = &cmd->sem;
                        ent->ts2 = ktime_get_ns();
                        memcpy(ent->out->first.data, ent->lay->out, sizeof(ent->lay->out));
                        dump_command(dev, ent, 0);
@@ -1683,7 +1681,6 @@ static void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool force
                                 */
                                complete(&ent->done);
                        }
-                       up(sem);
                }
        }
 }