You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
150 lines
5.3 KiB
150 lines
5.3 KiB
4 years ago
|
From e1a165d97b043db33a647577da3cac42d9653202 Mon Sep 17 00:00:00 2001
|
||
|
From: Alaa Hleihel <ahleihel@redhat.com>
|
||
|
Date: Mon, 1 Jun 2020 15:40:33 -0400
|
||
|
Subject: [PATCH 280/312] [netdrv] net/mlx5: Avoid processing commands before
|
||
|
cmdif is ready
|
||
|
|
||
|
Message-id: <20200601154102.25980-11-ahleihel@redhat.com>
|
||
|
Patchwork-id: 315715
|
||
|
Patchwork-instance: patchwork
|
||
|
O-Subject: [RHEL8.3 BZ 1842258 10/39] net/mlx5: Avoid processing commands before cmdif is ready
|
||
|
Bugzilla: 1842258
|
||
|
RH-Acked-by: Honggang Li <honli@redhat.com>
|
||
|
RH-Acked-by: Kamal Heib <kheib@redhat.com>
|
||
|
RH-Acked-by: Marcelo Leitner <mleitner@redhat.com>
|
||
|
RH-Acked-by: Jarod Wilson <jarod@redhat.com>
|
||
|
|
||
|
Bugzilla: http://bugzilla.redhat.com/1842258
|
||
|
Upstream: v5.7-rc7
|
||
|
|
||
|
commit f7936ddd35d8b849daf0372770c7c9dbe7910fca
|
||
|
Author: Eran Ben Elisha <eranbe@mellanox.com>
|
||
|
Date: Thu Mar 19 21:43:13 2020 +0200
|
||
|
|
||
|
net/mlx5: Avoid processing commands before cmdif is ready
|
||
|
|
||
|
When driver is reloading during recovery flow, it can't get new commands
|
||
|
till command interface is up again. Otherwise we may get to null pointer
|
||
|
trying to access non initialized command structures.
|
||
|
|
||
|
Add cmdif state to avoid processing commands while cmdif is not ready.
|
||
|
|
||
|
Fixes: e126ba97dba9 ("mlx5: Add driver for Mellanox Connect-IB adapters")
|
||
|
Signed-off-by: Eran Ben Elisha <eranbe@mellanox.com>
|
||
|
Signed-off-by: Moshe Shemesh <moshe@mellanox.com>
|
||
|
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
|
||
|
|
||
|
Signed-off-by: Alaa Hleihel <ahleihel@redhat.com>
|
||
|
Signed-off-by: Frantisek Hrbata <fhrbata@redhat.com>
|
||
|
---
|
||
|
drivers/net/ethernet/mellanox/mlx5/core/cmd.c | 10 ++++++++++
|
||
|
drivers/net/ethernet/mellanox/mlx5/core/main.c | 4 ++++
|
||
|
include/linux/mlx5/driver.h | 9 +++++++++
|
||
|
3 files changed, 23 insertions(+)
|
||
|
|
||
|
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
|
||
|
index 2280bb7e748d..3745fcd9a99e 100644
|
||
|
--- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
|
||
|
+++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
|
||
|
@@ -923,6 +923,7 @@ static void cmd_work_handler(struct work_struct *work)
|
||
|
/* Skip sending command to fw if internal error */
|
||
|
if (pci_channel_offline(dev->pdev) ||
|
||
|
dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR ||
|
||
|
+ cmd->state != MLX5_CMDIF_STATE_UP ||
|
||
|
!opcode_allowed(&dev->cmd, ent->op)) {
|
||
|
u8 status = 0;
|
||
|
u32 drv_synd;
|
||
|
@@ -1712,6 +1713,7 @@ static int cmd_exec(struct mlx5_core_dev *dev, void *in, int in_size, void *out,
|
||
|
opcode = MLX5_GET(mbox_in, in, opcode);
|
||
|
if (pci_channel_offline(dev->pdev) ||
|
||
|
dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR ||
|
||
|
+ dev->cmd.state != MLX5_CMDIF_STATE_UP ||
|
||
|
!opcode_allowed(&dev->cmd, opcode)) {
|
||
|
err = mlx5_internal_err_ret_value(dev, opcode, &drv_synd, &status);
|
||
|
MLX5_SET(mbox_out, out, status, status);
|
||
|
@@ -1977,6 +1979,7 @@ int mlx5_cmd_init(struct mlx5_core_dev *dev)
|
||
|
goto err_free_page;
|
||
|
}
|
||
|
|
||
|
+ cmd->state = MLX5_CMDIF_STATE_DOWN;
|
||
|
cmd->checksum_disabled = 1;
|
||
|
cmd->max_reg_cmds = (1 << cmd->log_sz) - 1;
|
||
|
cmd->bitmask = (1UL << cmd->max_reg_cmds) - 1;
|
||
|
@@ -2054,3 +2057,10 @@ void mlx5_cmd_cleanup(struct mlx5_core_dev *dev)
|
||
|
dma_pool_destroy(cmd->pool);
|
||
|
}
|
||
|
EXPORT_SYMBOL(mlx5_cmd_cleanup);
|
||
|
+
|
||
|
+void mlx5_cmd_set_state(struct mlx5_core_dev *dev,
|
||
|
+ enum mlx5_cmdif_state cmdif_state)
|
||
|
+{
|
||
|
+ dev->cmd.state = cmdif_state;
|
||
|
+}
|
||
|
+EXPORT_SYMBOL(mlx5_cmd_set_state);
|
||
|
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
|
||
|
index 880bc53d0b1b..fdc0c0f7da96 100644
|
||
|
--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
|
||
|
+++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
|
||
|
@@ -993,6 +993,8 @@ static int mlx5_function_setup(struct mlx5_core_dev *dev, bool boot)
|
||
|
goto err_cmd_cleanup;
|
||
|
}
|
||
|
|
||
|
+ mlx5_cmd_set_state(dev, MLX5_CMDIF_STATE_UP);
|
||
|
+
|
||
|
err = mlx5_core_enable_hca(dev, 0);
|
||
|
if (err) {
|
||
|
mlx5_core_err(dev, "enable hca failed\n");
|
||
|
@@ -1056,6 +1058,7 @@ static int mlx5_function_setup(struct mlx5_core_dev *dev, bool boot)
|
||
|
err_disable_hca:
|
||
|
mlx5_core_disable_hca(dev, 0);
|
||
|
err_cmd_cleanup:
|
||
|
+ mlx5_cmd_set_state(dev, MLX5_CMDIF_STATE_DOWN);
|
||
|
mlx5_cmd_cleanup(dev);
|
||
|
|
||
|
return err;
|
||
|
@@ -1073,6 +1076,7 @@ static int mlx5_function_teardown(struct mlx5_core_dev *dev, bool boot)
|
||
|
}
|
||
|
mlx5_reclaim_startup_pages(dev);
|
||
|
mlx5_core_disable_hca(dev, 0);
|
||
|
+ mlx5_cmd_set_state(dev, MLX5_CMDIF_STATE_DOWN);
|
||
|
mlx5_cmd_cleanup(dev);
|
||
|
|
||
|
return 0;
|
||
|
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
|
||
|
index c2009064805a..013786924596 100644
|
||
|
--- a/include/linux/mlx5/driver.h
|
||
|
+++ b/include/linux/mlx5/driver.h
|
||
|
@@ -228,6 +228,12 @@ struct mlx5_bfreg_info {
|
||
|
u32 num_dyn_bfregs;
|
||
|
};
|
||
|
|
||
|
+enum mlx5_cmdif_state {
|
||
|
+ MLX5_CMDIF_STATE_UNINITIALIZED,
|
||
|
+ MLX5_CMDIF_STATE_UP,
|
||
|
+ MLX5_CMDIF_STATE_DOWN,
|
||
|
+};
|
||
|
+
|
||
|
struct mlx5_cmd_first {
|
||
|
__be32 data[4];
|
||
|
};
|
||
|
@@ -301,6 +307,7 @@ struct mlx5_cmd {
|
||
|
spinlock_t token_lock;
|
||
|
u8 token;
|
||
|
#ifndef __GENKSYMS__
|
||
|
+ u8 /* enum mlx5_cmdif_state */ state;
|
||
|
u16 allowed_opcode;
|
||
|
#endif
|
||
|
unsigned long bitmask;
|
||
|
@@ -904,6 +911,8 @@ enum {
|
||
|
|
||
|
int mlx5_cmd_init(struct mlx5_core_dev *dev);
|
||
|
void mlx5_cmd_cleanup(struct mlx5_core_dev *dev);
|
||
|
+void mlx5_cmd_set_state(struct mlx5_core_dev *dev,
|
||
|
+ enum mlx5_cmdif_state cmdif_state);
|
||
|
void mlx5_cmd_use_events(struct mlx5_core_dev *dev);
|
||
|
void mlx5_cmd_use_polling(struct mlx5_core_dev *dev);
|
||
|
void mlx5_cmd_allowed_opcode(struct mlx5_core_dev *dev, u16 opcode);
|
||
|
--
|
||
|
2.13.6
|
||
|
|