kunpeng inclusion category: bugfix bugzilla: https://atomgit.com/openeuler/kernel/issues/10109 ---------------------------------------- mlx5e_tx_reporter_err_cqe_recover() and mlx5e_tx_reporter_ptpsq_unhealthy_recover() are called synchronously from devlink_health_report() with the devlink lock held, because the recovery is triggered by mlx5e_tx_err_cqe_work()/mlx5e_ptpsq_unhealthy_work(). Channel teardown holds the RTNL and waits for those works with cancel_work_sync() (mlx5e_close_txqsq()/mlx5e_ptp_close_txqsq()), so the blocking rtnl_lock() added to the recovery functions deadlocks: the teardown waits for the work, while the work waits for the RTNL. The deadlock also stalls every devlink operation on the device, since the work holds the devlink lock. Use rtnl_trylock() and give up the recovery when the SQ has been disabled by the teardown, matching the existing mlx5e_tx_timeout_work() pattern. Fixes: fdce06bda7e5 ("net/mlx5e: Acquire RTNL lock before RQs/SQs activation/deactivation") Signed-off-by: Cai Xinchen <caixinchen1@huawei.com> --- .../mellanox/mlx5/core/en/reporter_tx.c | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c index 6e675c1b9244..dc102b31ed32 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c @@ -1,6 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2019 Mellanox Technologies. */ +#include <linux/delay.h> + #include "health.h" #include "en/ptp.h" #include "en/devlink.h" @@ -113,7 +115,17 @@ static int mlx5e_tx_reporter_err_cqe_recover(void *ctx) mlx5e_reset_txqsq_cc_pc(sq); sq->stats->recover++; clear_bit(MLX5E_SQ_STATE_RECOVERING, &sq->state); - rtnl_lock(); + + /* Recovering the SQ means re-enabling NAPI, which needs the RTNL. + * Closing flows hold the RTNL and wait for this work with + * cancel_work_sync(), so do not block here; bail out instead if the + * SQ was disabled while the channel is being torn down. + */ + while (!rtnl_trylock()) { + if (!test_bit(MLX5E_SQ_STATE_ENABLED, &sq->state)) + return 0; + msleep(20); + } mlx5e_activate_txqsq(sq); rtnl_unlock(); @@ -182,7 +194,15 @@ static int mlx5e_tx_reporter_ptpsq_unhealthy_recover(void *ctx) priv = ptpsq->txqsq.priv; - rtnl_lock(); + /* Re-enabling NAPI needs the RTNL, but the closing flows hold it + * while waiting for this work with cancel_work_sync(). Try it and + * give up if the SQ was disabled by the teardown meanwhile. + */ + while (!rtnl_trylock()) { + if (!test_bit(MLX5E_SQ_STATE_ENABLED, &ptpsq->txqsq.state)) + return 0; + msleep(20); + } mutex_lock(&priv->state_lock); chs = &priv->channels; netdev = priv->netdev; -- 2.18.0.huawei.25