FAILED: patch "[PATCH] net/mlx5: Fix deadlock in sync reset flow" failed to apply to 5.10-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 5.10-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From cb7786a76ea39f394f0a059787fe24fa8e340fb6 Mon Sep 17 00:00:00 2001
From: Moshe Shemesh <[email protected]>
Date: Mon, 11 Apr 2022 21:31:06 +0300
Subject: [PATCH] net/mlx5: Fix deadlock in sync reset flow
The sync reset flow can lead to the following deadlock when poll_sync_reset() is called by timer softirq and waiting on del_timer_sync() for the same timer. Fix that by moving the part of the flow that waits for the timer to reset_reload_work.
It fixes the following kernel Trace:
RIP: 0010:del_timer_sync+0x32/0x40 ... Call Trace: <IRQ> mlx5_sync_reset_clear_reset_requested+0x26/0x50 [mlx5_core] poll_sync_reset.cold+0x36/0x52 [mlx5_core] call_timer_fn+0x32/0x130 __run_timers.part.0+0x180/0x280 ? tick_sched_handle+0x33/0x60 ? tick_sched_timer+0x3d/0x80 ? ktime_get+0x3e/0xa0 run_timer_softirq+0x2a/0x50 __do_softirq+0xe1/0x2d6 ? hrtimer_interrupt+0x136/0x220 irq_exit+0xae/0xb0 smp_apic_timer_interrupt+0x7b/0x140 apic_timer_interrupt+0xf/0x20 </IRQ>
drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c +17 -17
@@ -155,22 +155,6 @@ static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev) } } -static void mlx5_sync_reset_reload_work (struct work_struct *work) -{ - struct mlx5_fw_reset *fw_reset = container_of(work, struct mlx5_fw_reset, - reset_reload_work); -struct mlx5_core_dev *dev = fw_reset->dev; -int err; - -mlx5_enter_error_state (dev, true); -mlx5_unload_one (dev); - err =mlx5_health_wait_pci_up (dev); -if (err) -mlx5_core_err (dev,"reset reload flow aborted, PCI reads still not working\n" ); - fw_reset->ret = err; -mlx5_fw_reset_complete_reload (dev); -} -static void mlx5_stop_sync_reset_poll (struct mlx5_core_dev *dev) {struct mlx5_fw_reset *fw_reset = dev->priv.fw_reset;
@@ -188,6 +172,23 @@ static void mlx5_sync_reset_clear_reset_requested(struct mlx5_core_dev *dev, boomlx5_start_health_poll (dev); } +static void mlx5_sync_reset_reload_work (struct work_struct *work) +{ + struct mlx5_fw_reset *fw_reset = container_of(work, struct mlx5_fw_reset, + reset_reload_work); +struct mlx5_core_dev *dev = fw_reset->dev; +int err; + +mlx5_sync_reset_clear_reset_requested (dev, false); +mlx5_enter_error_state (dev, true); +mlx5_unload_one (dev); + err =mlx5_health_wait_pci_up (dev); +if (err) +mlx5_core_err (dev,"reset reload flow aborted, PCI reads still not working\n" ); + fw_reset->ret = err; +mlx5_fw_reset_complete_reload (dev); +} +#define MLX5_RESET_POLL_INTERVAL (HZ / 10)static void poll_sync_reset (struct timer_list *t) {
@@ -202,7 +203,6 @@ static void poll_sync_reset(struct timer_list *t)if (fatal_error) {mlx5_core_warn (dev,"Got Device Reset\n" ); -mlx5_sync_reset_clear_reset_requested (dev, false);queue_work (fw_reset->wq, &fw_reset->reset_reload_work);return ; }