diff options
author | Daniel Jurgens <danielj@mellanox.com> | 2018-03-26 14:35:29 -0400 |
---|---|---|
committer | Saeed Mahameed <saeedm@mellanox.com> | 2018-05-10 19:10:03 -0400 |
commit | 1ef903bf795be01c91c10c93a0f9d9d6f2f7921b (patch) | |
tree | d2303d8599725a092a75d4c45772a8faf4846fd0 | |
parent | ca3943c4aaff083bc25419f04e549e293590258e (diff) |
net/mlx5: Free IRQs in shutdown path
Some platforms require IRQs to be free'd in the shutdown path. Otherwise
they will fail to be reallocated after a kexec.
Fixes: 8812c24d28f4 ("net/mlx5: Add fast unload support in shutdown flow")
Signed-off-by: Daniel Jurgens <danielj@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/eq.c | 28 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/main.c | 8 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h | 2 |
3 files changed, 38 insertions, 0 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eq.c b/drivers/net/ethernet/mellanox/mlx5/core/eq.c index c1c94974e16b..1814f803bd2c 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eq.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eq.c | |||
@@ -34,6 +34,9 @@ | |||
34 | #include <linux/module.h> | 34 | #include <linux/module.h> |
35 | #include <linux/mlx5/driver.h> | 35 | #include <linux/mlx5/driver.h> |
36 | #include <linux/mlx5/cmd.h> | 36 | #include <linux/mlx5/cmd.h> |
37 | #ifdef CONFIG_RFS_ACCEL | ||
38 | #include <linux/cpu_rmap.h> | ||
39 | #endif | ||
37 | #include "mlx5_core.h" | 40 | #include "mlx5_core.h" |
38 | #include "fpga/core.h" | 41 | #include "fpga/core.h" |
39 | #include "eswitch.h" | 42 | #include "eswitch.h" |
@@ -923,3 +926,28 @@ int mlx5_core_eq_query(struct mlx5_core_dev *dev, struct mlx5_eq *eq, | |||
923 | MLX5_SET(query_eq_in, in, eq_number, eq->eqn); | 926 | MLX5_SET(query_eq_in, in, eq_number, eq->eqn); |
924 | return mlx5_cmd_exec(dev, in, sizeof(in), out, outlen); | 927 | return mlx5_cmd_exec(dev, in, sizeof(in), out, outlen); |
925 | } | 928 | } |
929 | |||
930 | /* This function should only be called after mlx5_cmd_force_teardown_hca */ | ||
931 | void mlx5_core_eq_free_irqs(struct mlx5_core_dev *dev) | ||
932 | { | ||
933 | struct mlx5_eq_table *table = &dev->priv.eq_table; | ||
934 | struct mlx5_eq *eq; | ||
935 | |||
936 | #ifdef CONFIG_RFS_ACCEL | ||
937 | if (dev->rmap) { | ||
938 | free_irq_cpu_rmap(dev->rmap); | ||
939 | dev->rmap = NULL; | ||
940 | } | ||
941 | #endif | ||
942 | list_for_each_entry(eq, &table->comp_eqs_list, list) | ||
943 | free_irq(eq->irqn, eq); | ||
944 | |||
945 | free_irq(table->pages_eq.irqn, &table->pages_eq); | ||
946 | free_irq(table->async_eq.irqn, &table->async_eq); | ||
947 | free_irq(table->cmd_eq.irqn, &table->cmd_eq); | ||
948 | #ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING | ||
949 | if (MLX5_CAP_GEN(dev, pg)) | ||
950 | free_irq(table->pfault_eq.irqn, &table->pfault_eq); | ||
951 | #endif | ||
952 | pci_free_irq_vectors(dev->pdev); | ||
953 | } | ||
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index 63a8ea31601c..e2c465b0b3f8 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c | |||
@@ -1587,6 +1587,14 @@ static int mlx5_try_fast_unload(struct mlx5_core_dev *dev) | |||
1587 | 1587 | ||
1588 | mlx5_enter_error_state(dev, true); | 1588 | mlx5_enter_error_state(dev, true); |
1589 | 1589 | ||
1590 | /* Some platforms requiring freeing the IRQ's in the shutdown | ||
1591 | * flow. If they aren't freed they can't be allocated after | ||
1592 | * kexec. There is no need to cleanup the mlx5_core software | ||
1593 | * contexts. | ||
1594 | */ | ||
1595 | mlx5_irq_clear_affinity_hints(dev); | ||
1596 | mlx5_core_eq_free_irqs(dev); | ||
1597 | |||
1590 | return 0; | 1598 | return 0; |
1591 | } | 1599 | } |
1592 | 1600 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h index 7d001fe6e631..023882d9a22e 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h | |||
@@ -128,6 +128,8 @@ int mlx5_core_eq_query(struct mlx5_core_dev *dev, struct mlx5_eq *eq, | |||
128 | u32 *out, int outlen); | 128 | u32 *out, int outlen); |
129 | int mlx5_start_eqs(struct mlx5_core_dev *dev); | 129 | int mlx5_start_eqs(struct mlx5_core_dev *dev); |
130 | void mlx5_stop_eqs(struct mlx5_core_dev *dev); | 130 | void mlx5_stop_eqs(struct mlx5_core_dev *dev); |
131 | /* This function should only be called after mlx5_cmd_force_teardown_hca */ | ||
132 | void mlx5_core_eq_free_irqs(struct mlx5_core_dev *dev); | ||
131 | struct mlx5_eq *mlx5_eqn2eq(struct mlx5_core_dev *dev, int eqn); | 133 | struct mlx5_eq *mlx5_eqn2eq(struct mlx5_core_dev *dev, int eqn); |
132 | u32 mlx5_eq_poll_irq_disabled(struct mlx5_eq *eq); | 134 | u32 mlx5_eq_poll_irq_disabled(struct mlx5_eq *eq); |
133 | void mlx5_cq_tasklet_cb(unsigned long data); | 135 | void mlx5_cq_tasklet_cb(unsigned long data); |