AI Trajectory


Trajectory: (Expand/Collapse All)
Seq Timestamp Type Name Duration
0/0 2026/10/11 13:43 flow patch-triage
0m Args:
null

Results:
{
  "EnableConfigs": null,
  "FocusSymbols": [],
  "KMSANReasoning": "",
  "NeedsKMSAN": false,
  "Reasoning": "The patch modifies channel deactivation and teardown logic within the Mellanox ConnectX Ethernet driver (mlx5). This driver requires vendor-specific Mellanox PCIe network hardware (e.g., ConnectX series / BlueField) which is not emulated in standard virtualized QEMU or GCE test environments, making the modified code structurally unreachable for syzkaller fuzzing.",
  "WorthFuzzing": false
}

1/1 2026/10/11 13:43 action read-patch-diff
0m Args:
null

Results:
{
  "PatchDiff": "commit dfe5dd924b063198771d6d489f153a31a4b953c8\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate:   Sun Oct 11 13:43:58 2026 +0000\n\n    syz-cluster: applied patch under review\n\ndiff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h\nindex a3945195f454e..1a169fce075af 100644\n--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h\n+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h\n@@ -1103,6 +1103,7 @@ int mlx5e_open_xdpsq(struct mlx5e_channel *c, struct mlx5e_params *params,\n \t\t     struct mlx5e_sq_param *param, struct xsk_buff_pool *xsk_pool,\n \t\t     struct mlx5e_xdpsq *sq, bool is_redirect);\n void mlx5e_close_xdpsq(struct mlx5e_xdpsq *sq);\n+void mlx5e_close_xdpsq_post_sync(struct mlx5e_xdpsq *sq);\n \n struct mlx5e_create_cq_param {\n \tstruct net_device *netdev;\n@@ -1159,8 +1160,10 @@ int mlx5e_ptp_rx_manage_fs_ctx(struct mlx5e_priv *priv, void *ctx);\n int mlx5e_flush_rq(struct mlx5e_rq *rq, int curr_state);\n void mlx5e_activate_rq(struct mlx5e_rq *rq);\n void mlx5e_deactivate_rq(struct mlx5e_rq *rq);\n+void mlx5e_deactivate_rq_pre_sync(struct mlx5e_rq *rq);\n void mlx5e_activate_icosq(struct mlx5e_icosq *icosq);\n void mlx5e_deactivate_icosq(struct mlx5e_icosq *icosq);\n+void mlx5e_deactivate_icosq_pre_sync(struct mlx5e_icosq *icosq);\n \n int mlx5e_modify_sq(struct mlx5_core_dev *mdev, u32 sqn,\n \t\t    struct mlx5e_modify_sq_param *p);\n@@ -1170,6 +1173,8 @@ int mlx5e_open_txqsq(struct mlx5e_channel *c, u32 tisn, int txq_ix,\n \t\t     struct mlx5e_sq_stats *sq_stats);\n void mlx5e_activate_txqsq(struct mlx5e_txqsq *sq);\n void mlx5e_deactivate_txqsq(struct mlx5e_txqsq *sq);\n+void mlx5e_deactivate_txqsq_pre_sync(struct mlx5e_txqsq *sq);\n+void mlx5e_deactivate_txqsq_post_sync(struct mlx5e_txqsq *sq);\n void mlx5e_free_txqsq(struct mlx5e_txqsq *sq);\n void mlx5e_tx_disable_queue(struct netdev_queue *txq);\n int mlx5e_alloc_txqsq_db(struct mlx5e_txqsq *sq, int numa);\ndiff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c\nindex 17084d76209e8..3fa6292288781 100644\n--- a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c\n+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c\n@@ -775,7 +775,7 @@ static int mlx5e_ptp_open_queues(struct mlx5e_ptp *c,\n \treturn err;\n }\n \n-static void mlx5e_ptp_close_queues(struct mlx5e_ptp *c)\n+void mlx5e_ptp_close_queues(struct mlx5e_ptp *c)\n {\n \tif (test_bit(MLX5E_PTP_STATE_RX, c-\u003estate)) {\n \t\tmlx5e_close_rq(\u0026c-\u003erq);\n@@ -932,7 +932,6 @@ void mlx5e_ptp_close(struct mlx5e_ptp *c)\n {\n \tmlx5e_ptp_close_queues(c);\n \tnetif_napi_del_locked(\u0026c-\u003enapi);\n-\n \tkvfree(c);\n }\n \n@@ -954,18 +953,28 @@ void mlx5e_ptp_activate_channel(struct mlx5e_ptp *c)\n \tmlx5e_trigger_napi_sched(\u0026c-\u003enapi);\n }\n \n-void mlx5e_ptp_deactivate_channel(struct mlx5e_ptp *c)\n+void mlx5e_ptp_deactivate_channel_pre_sync(struct mlx5e_ptp *c)\n {\n \tint tc;\n \n \tif (test_bit(MLX5E_PTP_STATE_RX, c-\u003estate)) {\n \t\tnetif_queue_set_napi(c-\u003enetdev, c-\u003erq.ix, NETDEV_QUEUE_TYPE_RX, NULL);\n-\t\tmlx5e_deactivate_rq(\u0026c-\u003erq);\n+\t\tmlx5e_deactivate_rq_pre_sync(\u0026c-\u003erq);\n+\t}\n+\n+\tif (test_bit(MLX5E_PTP_STATE_TX, c-\u003estate)) {\n+\t\tfor (tc = 0; tc \u003c c-\u003enum_tc; tc++)\n+\t\t\tmlx5e_deactivate_txqsq_pre_sync(\u0026c-\u003eptpsq[tc].txqsq);\n \t}\n+}\n+\n+void mlx5e_ptp_deactivate_channel_post_sync(struct mlx5e_ptp *c)\n+{\n+\tint tc;\n \n \tif (test_bit(MLX5E_PTP_STATE_TX, c-\u003estate)) {\n \t\tfor (tc = 0; tc \u003c c-\u003enum_tc; tc++)\n-\t\t\tmlx5e_deactivate_txqsq(\u0026c-\u003eptpsq[tc].txqsq);\n+\t\t\tmlx5e_deactivate_txqsq_post_sync(\u0026c-\u003eptpsq[tc].txqsq);\n \t}\n \n \tnapi_disable_locked(\u0026c-\u003enapi);\ndiff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h\nindex 2a457a2ed7079..b42ce33635a0a 100644\n--- a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h\n+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h\n@@ -129,8 +129,10 @@ static inline bool mlx5e_ptpsq_metadata_freelist_empty(struct mlx5e_ptpsq *ptpsq\n int mlx5e_ptp_open(struct mlx5e_priv *priv, struct mlx5e_params *params,\n \t\t   u8 lag_port, struct mlx5e_ptp **cp);\n void mlx5e_ptp_close(struct mlx5e_ptp *c);\n+void mlx5e_ptp_close_queues(struct mlx5e_ptp *c);\n void mlx5e_ptp_activate_channel(struct mlx5e_ptp *c);\n-void mlx5e_ptp_deactivate_channel(struct mlx5e_ptp *c);\n+void mlx5e_ptp_deactivate_channel_pre_sync(struct mlx5e_ptp *c);\n+void mlx5e_ptp_deactivate_channel_post_sync(struct mlx5e_ptp *c);\n int mlx5e_ptp_get_rqn(struct mlx5e_ptp *c, u32 *rqn);\n int mlx5e_ptp_alloc_rx_fs(struct mlx5e_flow_steering *fs,\n \t\t\t  const struct mlx5e_profile *profile);\ndiff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/qos.c b/drivers/net/ethernet/mellanox/mlx5/core/en/qos.c\nindex ac4979087e0dd..3e59862a0e600 100644\n--- a/drivers/net/ethernet/mellanox/mlx5/core/en/qos.c\n+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/qos.c\n@@ -233,15 +233,20 @@ void mlx5e_close_qos_sq(struct mlx5e_priv *priv, u16 qid)\n \tkfree(sq);\n }\n \n-void mlx5e_qos_close_queues(struct mlx5e_channel *c)\n+static struct mlx5e_txqsq __rcu **\n+mlx5e_qos_unpublish_queues(struct mlx5e_channel *c)\n+{\n+\treturn rcu_replace_pointer(c-\u003eqos_sqs, NULL,\n+\t\t\t\t   lockdep_is_held(\u0026c-\u003epriv-\u003estate_lock));\n+}\n+\n+static void mlx5e_qos_free_queues(struct mlx5e_channel *c,\n+\t\t\t\t  struct mlx5e_txqsq __rcu **qos_sqs)\n {\n-\tstruct mlx5e_txqsq __rcu **qos_sqs;\n \tint i;\n \n-\tqos_sqs = rcu_replace_pointer(c-\u003eqos_sqs, NULL, lockdep_is_held(\u0026c-\u003epriv-\u003estate_lock));\n \tif (!qos_sqs)\n \t\treturn;\n-\tsynchronize_rcu(); /* Sync with NAPI. */\n \n \tfor (i = 0; i \u003c c-\u003eqos_sqs_size; i++) {\n \t\tstruct mlx5e_txqsq *sq;\n@@ -258,6 +263,27 @@ void mlx5e_qos_close_queues(struct mlx5e_channel *c)\n \tkvfree(qos_sqs);\n }\n \n+void mlx5e_qos_close_queues_post_sync(struct mlx5e_channel *c)\n+{\n+\tstruct mlx5e_txqsq __rcu **qos_sqs;\n+\n+\tqos_sqs = mlx5e_qos_unpublish_queues(c);\n+\t/* Caller guarantees that NAPI is stopped or was never enabled. */\n+\tmlx5e_qos_free_queues(c, qos_sqs);\n+}\n+\n+void mlx5e_qos_close_queues(struct mlx5e_channel *c)\n+{\n+\tstruct mlx5e_txqsq __rcu **qos_sqs;\n+\n+\tqos_sqs = mlx5e_qos_unpublish_queues(c);\n+\tif (!qos_sqs)\n+\t\treturn;\n+\n+\tsynchronize_rcu(); /* Sync with NAPI. */\n+\tmlx5e_qos_free_queues(c, qos_sqs);\n+}\n+\n void mlx5e_qos_close_all_queues(struct mlx5e_channels *chs)\n {\n \tint i;\n@@ -326,11 +352,10 @@ void mlx5e_qos_activate_queues(struct mlx5e_priv *priv)\n \tmlx5e_htb_enumerate_leaves(priv-\u003ehtb, mlx5e_activate_qos_sq, priv);\n }\n \n-void mlx5e_qos_deactivate_queues(struct mlx5e_channel *c)\n+void mlx5e_qos_deactivate_queues_pre_sync(struct mlx5e_channel *c)\n {\n \tstruct mlx5e_params *params = \u0026c-\u003epriv-\u003echannels.params;\n \tstruct mlx5e_txqsq __rcu **qos_sqs;\n-\tu16 txq_ix;\n \tint i;\n \n \tqos_sqs = mlx5e_state_dereference(c-\u003epriv, c-\u003eqos_sqs);\n@@ -346,7 +371,30 @@ void mlx5e_qos_deactivate_queues(struct mlx5e_channel *c)\n \t\t\tcontinue;\n \n \t\tqos_dbg(c-\u003emdev, \"Deactivate QoS SQ qid %u\\n\", qid);\n-\t\tmlx5e_deactivate_txqsq(sq);\n+\t\tmlx5e_deactivate_txqsq_pre_sync(sq);\n+\t}\n+}\n+\n+void mlx5e_qos_deactivate_queues_post_sync(struct mlx5e_channel *c)\n+{\n+\tstruct mlx5e_params *params = \u0026c-\u003epriv-\u003echannels.params;\n+\tstruct mlx5e_txqsq __rcu **qos_sqs;\n+\tint i;\n+\n+\tqos_sqs = mlx5e_state_dereference(c-\u003epriv, c-\u003eqos_sqs);\n+\tif (!qos_sqs)\n+\t\treturn;\n+\n+\tfor (i = 0; i \u003c c-\u003eqos_sqs_size; i++) {\n+\t\tu16 qid = params-\u003enum_channels * i + c-\u003eix;\n+\t\tstruct mlx5e_txqsq *sq;\n+\t\tu16 txq_ix;\n+\n+\t\tsq = mlx5e_state_dereference(c-\u003epriv, qos_sqs[i]);\n+\t\tif (!sq)\n+\t\t\tcontinue;\n+\n+\t\tmlx5e_deactivate_txqsq_post_sync(sq);\n \n \t\ttxq_ix = mlx5e_qid_from_qos(\u0026c-\u003epriv-\u003echannels, qid);\n \n@@ -361,7 +409,12 @@ void mlx5e_qos_deactivate_all_queues(struct mlx5e_channels *chs)\n \tint i;\n \n \tfor (i = 0; i \u003c chs-\u003enum; i++)\n-\t\tmlx5e_qos_deactivate_queues(chs-\u003ec[i]);\n+\t\tmlx5e_qos_deactivate_queues_pre_sync(chs-\u003ec[i]);\n+\n+\tsynchronize_net();\n+\n+\tfor (i = 0; i \u003c chs-\u003enum; i++)\n+\t\tmlx5e_qos_deactivate_queues_post_sync(chs-\u003ec[i]);\n }\n \n void mlx5e_reactivate_qos_sq(struct mlx5e_priv *priv, u16 qid, struct netdev_queue *txq)\ndiff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/qos.h b/drivers/net/ethernet/mellanox/mlx5/core/en/qos.h\nindex 4947afa23b732..8d171a1079e95 100644\n--- a/drivers/net/ethernet/mellanox/mlx5/core/en/qos.h\n+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/qos.h\n@@ -28,9 +28,11 @@ void mlx5e_reset_qdisc(struct net_device *dev, u16 qid);\n \n int mlx5e_qos_open_queues(struct mlx5e_priv *priv, struct mlx5e_channels *chs);\n void mlx5e_qos_activate_queues(struct mlx5e_priv *priv);\n-void mlx5e_qos_deactivate_queues(struct mlx5e_channel *c);\n+void mlx5e_qos_deactivate_queues_pre_sync(struct mlx5e_channel *c);\n+void mlx5e_qos_deactivate_queues_post_sync(struct mlx5e_channel *c);\n void mlx5e_qos_deactivate_all_queues(struct mlx5e_channels *chs);\n void mlx5e_qos_close_queues(struct mlx5e_channel *c);\n+void mlx5e_qos_close_queues_post_sync(struct mlx5e_channel *c);\n void mlx5e_qos_close_all_queues(struct mlx5e_channels *chs);\n int mlx5e_qos_alloc_queues(struct mlx5e_priv *priv, struct mlx5e_channels *chs);\n \ndiff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.h b/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.h\nindex 5b8f4094d5530..ea557a8310e56 100644\n--- a/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.h\n+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.h\n@@ -130,14 +130,12 @@ static inline void mlx5e_xdp_tx_enable(struct mlx5e_priv *priv)\n \t\tset_bit(MLX5E_STATE_XDP_ACTIVE, \u0026priv-\u003estate);\n }\n \n-static inline void mlx5e_xdp_tx_disable(struct mlx5e_priv *priv)\n+static inline void mlx5e_xdp_tx_disable_pre_sync(struct mlx5e_priv *priv)\n {\n \tif (priv-\u003echannels.params.xdp_prog)\n \t\tclear_bit(MLX5E_STATE_XDP_ACTIVE, \u0026priv-\u003estate);\n \n \tclear_bit(MLX5E_STATE_XDP_TX_ENABLED, \u0026priv-\u003estate);\n-\t/* Let other device's napi(s) and XSK wakeups see our new state. */\n-\tsynchronize_net();\n }\n \n static inline bool mlx5e_xdp_tx_is_enabled(struct mlx5e_priv *priv)\ndiff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.c b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.c\nindex 11500fd213a55..deb84ef29ca1c 100644\n--- a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.c\n+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.c\n@@ -160,23 +160,35 @@ int mlx5e_open_xsk(struct mlx5e_priv *priv, struct mlx5e_params *params,\n err_close_rx_cq:\n \tmlx5e_close_cq(\u0026c-\u003exskrq.cq);\n \n+\tc-\u003exskrq.xsk_pool = NULL;\n+\tc-\u003exsksq.xsk_pool = NULL;\n+\n \treturn err;\n }\n \n-void mlx5e_close_xsk(struct mlx5e_channel *c)\n+void mlx5e_close_xsk_pre_sync(struct mlx5e_channel *c)\n {\n \tclear_bit(MLX5E_CHANNEL_STATE_XSK, c-\u003estate);\n-\tsynchronize_net(); /* Sync with NAPI. */\n+}\n \n+void mlx5e_close_xsk_post_sync(struct mlx5e_channel *c)\n+{\n \tmlx5e_close_rq(\u0026c-\u003exskrq);\n \tmlx5e_close_cq(\u0026c-\u003exskrq.cq);\n-\tmlx5e_close_xdpsq(\u0026c-\u003exsksq);\n+\tmlx5e_close_xdpsq_post_sync(\u0026c-\u003exsksq);\n \tmlx5e_close_cq(\u0026c-\u003exsksq.cq);\n \n \tmemset(\u0026c-\u003exskrq, 0, sizeof(c-\u003exskrq));\n \tmemset(\u0026c-\u003exsksq, 0, sizeof(c-\u003exsksq));\n }\n \n+void mlx5e_close_xsk(struct mlx5e_channel *c)\n+{\n+\tmlx5e_close_xsk_pre_sync(c);\n+\tsynchronize_net(); /* Sync with XSK wakeup and NAPI. */\n+\tmlx5e_close_xsk_post_sync(c);\n+}\n+\n void mlx5e_activate_xsk(struct mlx5e_channel *c)\n {\n \t/* ICOSQ recovery deactivates RQs. Suspend the recovery to avoid\n@@ -189,7 +201,7 @@ void mlx5e_activate_xsk(struct mlx5e_channel *c)\n \t/* TX queue is created active. */\n }\n \n-void mlx5e_deactivate_xsk(struct mlx5e_channel *c)\n+void mlx5e_deactivate_xsk_pre_sync(struct mlx5e_channel *c)\n {\n \t/* ICOSQ recovery may reactivate XSKRQ if clear_bit is called in the\n \t * middle of recovery. Suspend the recovery to avoid it.\n@@ -197,7 +209,12 @@ void mlx5e_deactivate_xsk(struct mlx5e_channel *c)\n \tmlx5e_reporter_icosq_suspend_recovery(c);\n \tclear_bit(MLX5E_RQ_STATE_ENABLED, \u0026c-\u003exskrq.state);\n \tmlx5e_reporter_icosq_resume_recovery(c);\n-\tsynchronize_net(); /* Sync with NAPI to prevent mlx5e_post_rx_wqes. */\n \n \t/* TX queue is disabled on close. */\n }\n+\n+void mlx5e_deactivate_xsk(struct mlx5e_channel *c)\n+{\n+\tmlx5e_deactivate_xsk_pre_sync(c);\n+\tsynchronize_net(); /* Sync with NAPI to prevent mlx5e_post_rx_wqes. */\n+}\ndiff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.h b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.h\nindex 664ec78192c33..66a0b09452f73 100644\n--- a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.h\n+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.h\n@@ -17,7 +17,10 @@ int mlx5e_open_xsk(struct mlx5e_priv *priv, struct mlx5e_params *params,\n \t\t   struct xsk_buff_pool *pool,\n \t\t   struct mlx5e_channel *c);\n void mlx5e_close_xsk(struct mlx5e_channel *c);\n+void mlx5e_close_xsk_pre_sync(struct mlx5e_channel *c);\n+void mlx5e_close_xsk_post_sync(struct mlx5e_channel *c);\n void mlx5e_activate_xsk(struct mlx5e_channel *c);\n void mlx5e_deactivate_xsk(struct mlx5e_channel *c);\n+void mlx5e_deactivate_xsk_pre_sync(struct mlx5e_channel *c);\n \n #endif /* __MLX5_EN_XSK_SETUP_H__ */\ndiff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c\nindex f90b5a34e0972..58e4874b664f1 100644\n--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c\n+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c\n@@ -1458,9 +1458,14 @@ void mlx5e_activate_rq(struct mlx5e_rq *rq)\n \tset_bit(MLX5E_RQ_STATE_ENABLED, \u0026rq-\u003estate);\n }\n \n-void mlx5e_deactivate_rq(struct mlx5e_rq *rq)\n+void mlx5e_deactivate_rq_pre_sync(struct mlx5e_rq *rq)\n {\n \tclear_bit(MLX5E_RQ_STATE_ENABLED, \u0026rq-\u003estate);\n+}\n+\n+void mlx5e_deactivate_rq(struct mlx5e_rq *rq)\n+{\n+\tmlx5e_deactivate_rq_pre_sync(rq);\n \tsynchronize_net(); /* Sync with NAPI to prevent mlx5e_post_rx_wqes. */\n }\n \n@@ -1954,13 +1959,15 @@ void mlx5e_tx_disable_queue(struct netdev_queue *txq)\n \t__netif_tx_unlock_bh(txq);\n }\n \n-void mlx5e_deactivate_txqsq(struct mlx5e_txqsq *sq)\n+void mlx5e_deactivate_txqsq_pre_sync(struct mlx5e_txqsq *sq)\n {\n-\tstruct mlx5_wq_cyc *wq = \u0026sq-\u003ewq;\n-\n \tnetif_queue_set_napi(sq-\u003enetdev, sq-\u003etxq_ix, NETDEV_QUEUE_TYPE_TX, NULL);\n \tclear_bit(MLX5E_SQ_STATE_ENABLED, \u0026sq-\u003estate);\n-\tsynchronize_net(); /* Sync with NAPI to prevent netif_tx_wake_queue. */\n+}\n+\n+void mlx5e_deactivate_txqsq_post_sync(struct mlx5e_txqsq *sq)\n+{\n+\tstruct mlx5_wq_cyc *wq = \u0026sq-\u003ewq;\n \n \tmlx5e_tx_disable_queue(sq-\u003etxq);\n \n@@ -1978,6 +1985,13 @@ void mlx5e_deactivate_txqsq(struct mlx5e_txqsq *sq)\n \t}\n }\n \n+void mlx5e_deactivate_txqsq(struct mlx5e_txqsq *sq)\n+{\n+\tmlx5e_deactivate_txqsq_pre_sync(sq);\n+\tsynchronize_net(); /* Sync with NAPI to prevent netif_tx_wake_queue. */\n+\tmlx5e_deactivate_txqsq_post_sync(sq);\n+}\n+\n void mlx5e_close_txqsq(struct mlx5e_txqsq *sq)\n {\n \tstruct mlx5_core_dev *mdev = sq-\u003emdev;\n@@ -2089,9 +2103,14 @@ void mlx5e_activate_icosq(struct mlx5e_icosq *icosq)\n \tset_bit(MLX5E_SQ_STATE_ENABLED, \u0026icosq-\u003estate);\n }\n \n-void mlx5e_deactivate_icosq(struct mlx5e_icosq *icosq)\n+void mlx5e_deactivate_icosq_pre_sync(struct mlx5e_icosq *icosq)\n {\n \tclear_bit(MLX5E_SQ_STATE_ENABLED, \u0026icosq-\u003estate);\n+}\n+\n+void mlx5e_deactivate_icosq(struct mlx5e_icosq *icosq)\n+{\n+\tmlx5e_deactivate_icosq_pre_sync(icosq);\n \tsynchronize_net(); /* Sync with NAPI. */\n }\n \n@@ -2141,18 +2160,28 @@ int mlx5e_open_xdpsq(struct mlx5e_channel *c, struct mlx5e_params *params,\n \treturn err;\n }\n \n-void mlx5e_close_xdpsq(struct mlx5e_xdpsq *sq)\n+static void mlx5e_destroy_xdpsq(struct mlx5e_xdpsq *sq)\n {\n \tstruct mlx5e_channel *c = sq-\u003echannel;\n \n-\tclear_bit(MLX5E_SQ_STATE_ENABLED, \u0026sq-\u003estate);\n-\tsynchronize_net(); /* Sync with NAPI. */\n-\n \tmlx5e_destroy_sq(c-\u003emdev, sq-\u003esqn);\n \tmlx5e_free_xdpsq_descs(sq);\n \tmlx5e_free_xdpsq(sq);\n }\n \n+void mlx5e_close_xdpsq_post_sync(struct mlx5e_xdpsq *sq)\n+{\n+\tclear_bit(MLX5E_SQ_STATE_ENABLED, \u0026sq-\u003estate);\n+\tmlx5e_destroy_xdpsq(sq);\n+}\n+\n+void mlx5e_close_xdpsq(struct mlx5e_xdpsq *sq)\n+{\n+\tclear_bit(MLX5E_SQ_STATE_ENABLED, \u0026sq-\u003estate);\n+\tsynchronize_net(); /* Sync with NAPI. */\n+\tmlx5e_destroy_xdpsq(sq);\n+}\n+\n static struct mlx5e_xdpsq *mlx5e_open_xdpredirect_sq(struct mlx5e_channel *c,\n \t\t\t\t\t\t     struct mlx5e_params *params,\n \t\t\t\t\t\t     struct mlx5e_channel_param *cparam,\n@@ -2184,6 +2213,13 @@ static struct mlx5e_xdpsq *mlx5e_open_xdpredirect_sq(struct mlx5e_channel *c,\n \treturn ERR_PTR(err);\n }\n \n+static void mlx5e_close_xdpredirect_sq_post_sync(struct mlx5e_xdpsq *xdpsq)\n+{\n+\tmlx5e_close_xdpsq_post_sync(xdpsq);\n+\tmlx5e_close_cq(\u0026xdpsq-\u003ecq);\n+\tkvfree(xdpsq);\n+}\n+\n static void mlx5e_close_xdpredirect_sq(struct mlx5e_xdpsq *xdpsq)\n {\n \tmlx5e_close_xdpsq(xdpsq);\n@@ -2749,6 +2785,27 @@ static void mlx5e_close_queues(struct mlx5e_channel *c)\n \tmlx5e_close_cq(\u0026c-\u003eicosq.cq);\n }\n \n+static void mlx5e_close_queues_post_sync(struct mlx5e_channel *c)\n+{\n+\tif (c-\u003exdp)\n+\t\tmlx5e_close_xdpsq_post_sync(\u0026c-\u003erq_xdpsq);\n+\t/* The same ICOSQ is used for UMRs for both RQ and XSKRQ. */\n+\tcancel_work_sync(\u0026c-\u003eicosq.recover_work);\n+\tmlx5e_close_rq(\u0026c-\u003erq);\n+\tmlx5e_close_sqs(c);\n+\tmlx5e_close_icosq(\u0026c-\u003eicosq);\n+\tmutex_destroy(\u0026c-\u003eicosq_recovery_lock);\n+\tif (c-\u003easync_icosq)\n+\t\tmlx5e_close_async_icosq(c-\u003easync_icosq);\n+\tif (c-\u003exdp)\n+\t\tmlx5e_close_cq(\u0026c-\u003erq_xdpsq.cq);\n+\tmlx5e_close_cq(\u0026c-\u003erq.cq);\n+\tif (c-\u003exdpsq)\n+\t\tmlx5e_close_xdpredirect_sq_post_sync(c-\u003exdpsq);\n+\tmlx5e_close_tx_cqs(c);\n+\tmlx5e_close_cq(\u0026c-\u003eicosq.cq);\n+}\n+\n static u8 mlx5e_enumerate_lag_port(struct mlx5_core_dev *mdev, int ix)\n {\n \tu16 port_aff_bias = mlx5_core_is_pf(mdev) ? 0 : MLX5_CAP_GEN(mdev, vhca_id);\n@@ -2780,14 +2837,11 @@ static int mlx5e_channel_stats_alloc(struct mlx5e_priv *priv, int ix, int cpu)\n \treturn 0;\n }\n \n-void mlx5e_trigger_napi_icosq(struct mlx5e_channel *c)\n+static void mlx5e_trigger_napi_icosq_post_sync(struct mlx5e_channel *c)\n {\n \tstruct mlx5e_icosq *sq = \u0026c-\u003eicosq;\n \tbool locked;\n \n-\tset_bit(MLX5E_SQ_STATE_LOCK_NEEDED, \u0026sq-\u003estate);\n-\tsynchronize_net();\n-\n \tlocked = mlx5e_icosq_sync_lock(sq);\n \tmlx5e_trigger_irq(sq);\n \tmlx5e_icosq_sync_unlock(sq, locked);\n@@ -2795,6 +2849,13 @@ void mlx5e_trigger_napi_icosq(struct mlx5e_channel *c)\n \tclear_bit(MLX5E_SQ_STATE_LOCK_NEEDED, \u0026sq-\u003estate);\n }\n \n+void mlx5e_trigger_napi_icosq(struct mlx5e_channel *c)\n+{\n+\tset_bit(MLX5E_SQ_STATE_LOCK_NEEDED, \u0026c-\u003eicosq.state);\n+\tsynchronize_net();\n+\tmlx5e_trigger_napi_icosq_post_sync(c);\n+}\n+\n void mlx5e_trigger_napi_async_icosq(struct mlx5e_channel *c)\n {\n \tstruct mlx5e_icosq *sq = c-\u003easync_icosq;\n@@ -2936,35 +2997,56 @@ static void mlx5e_activate_channel(struct mlx5e_channel *c)\n \tnetif_queue_set_napi(c-\u003enetdev, c-\u003eix, NETDEV_QUEUE_TYPE_RX, \u0026c-\u003enapi);\n }\n \n-static void mlx5e_deactivate_channel(struct mlx5e_channel *c)\n+static void mlx5e_deactivate_channel_pre_sync(struct mlx5e_channel *c)\n {\n \tint tc;\n \n \tnetif_queue_set_napi(c-\u003enetdev, c-\u003eix, NETDEV_QUEUE_TYPE_RX, NULL);\n \n \tif (test_bit(MLX5E_CHANNEL_STATE_XSK, c-\u003estate))\n-\t\tmlx5e_deactivate_xsk(c);\n+\t\tmlx5e_deactivate_xsk_pre_sync(c);\n \telse\n-\t\tmlx5e_deactivate_rq(\u0026c-\u003erq);\n+\t\tmlx5e_deactivate_rq_pre_sync(\u0026c-\u003erq);\n \n \tif (c-\u003easync_icosq)\n-\t\tmlx5e_deactivate_icosq(c-\u003easync_icosq);\n-\tmlx5e_deactivate_icosq(\u0026c-\u003eicosq);\n+\t\tmlx5e_deactivate_icosq_pre_sync(c-\u003easync_icosq);\n+\tmlx5e_deactivate_icosq_pre_sync(\u0026c-\u003eicosq);\n+\tfor (tc = 0; tc \u003c c-\u003enum_tc; tc++)\n+\t\tmlx5e_deactivate_txqsq_pre_sync(\u0026c-\u003esq[tc]);\n+\tmlx5e_qos_deactivate_queues_pre_sync(c);\n+}\n+\n+static void mlx5e_deactivate_channel_post_sync(struct mlx5e_channel *c)\n+{\n+\tint tc;\n+\n \tfor (tc = 0; tc \u003c c-\u003enum_tc; tc++)\n-\t\tmlx5e_deactivate_txqsq(\u0026c-\u003esq[tc]);\n-\tmlx5e_qos_deactivate_queues(c);\n+\t\tmlx5e_deactivate_txqsq_post_sync(\u0026c-\u003esq[tc]);\n+\tmlx5e_qos_deactivate_queues_post_sync(c);\n \n \tnapi_disable_locked(\u0026c-\u003enapi);\n }\n \n-static void mlx5e_close_channel(struct mlx5e_channel *c)\n+static void mlx5e_close_channel_pre_sync(struct mlx5e_channel *c)\n {\n \tif (test_bit(MLX5E_CHANNEL_STATE_XSK, c-\u003estate))\n-\t\tmlx5e_close_xsk(c);\n-\tmlx5e_close_queues(c);\n-\tmlx5e_qos_close_queues(c);\n-\tnetif_napi_del_locked(\u0026c-\u003enapi);\n+\t\tmlx5e_close_xsk_pre_sync(c);\n+}\n+\n+static void mlx5e_close_channel_post_sync(struct mlx5e_channel *c)\n+{\n+\tif (c-\u003exskrq.xsk_pool)\n+\t\tmlx5e_close_xsk_post_sync(c);\n+\tmlx5e_close_queues_post_sync(c);\n+\tmlx5e_qos_close_queues_post_sync(c);\n+}\n \n+static void mlx5e_close_channel(struct mlx5e_channel *c)\n+{\n+\tmlx5e_close_channel_pre_sync(c);\n+\tsynchronize_net();\n+\tmlx5e_close_channel_post_sync(c);\n+\tnetif_napi_del_locked(\u0026c-\u003enapi);\n \tkvfree(c);\n }\n \n@@ -3021,6 +3103,19 @@ int mlx5e_open_channels(struct mlx5e_priv *priv,\n \treturn err;\n }\n \n+static void mlx5e_trigger_napi_icosqs(struct mlx5e_channels *chs)\n+{\n+\tint i;\n+\n+\tfor (i = 0; i \u003c chs-\u003enum; i++)\n+\t\tset_bit(MLX5E_SQ_STATE_LOCK_NEEDED, \u0026chs-\u003ec[i]-\u003eicosq.state);\n+\n+\tsynchronize_net();\n+\n+\tfor (i = 0; i \u003c chs-\u003enum; i++)\n+\t\tmlx5e_trigger_napi_icosq_post_sync(chs-\u003ec[i]);\n+}\n+\n static void mlx5e_activate_channels(struct mlx5e_priv *priv, struct mlx5e_channels *chs)\n {\n \tint i;\n@@ -3031,8 +3126,7 @@ static void mlx5e_activate_channels(struct mlx5e_priv *priv, struct mlx5e_channe\n \tif (priv-\u003ehtb)\n \t\tmlx5e_qos_activate_queues(priv);\n \n-\tfor (i = 0; i \u003c chs-\u003enum; i++)\n-\t\tmlx5e_trigger_napi_icosq(chs-\u003ec[i]);\n+\tmlx5e_trigger_napi_icosqs(chs);\n \n \tif (chs-\u003eptp)\n \t\tmlx5e_ptp_activate_channel(chs-\u003eptp);\n@@ -3060,33 +3154,72 @@ static int mlx5e_wait_channels_min_rx_wqes(struct mlx5e_channels *chs)\n \treturn err ? -ETIMEDOUT : 0;\n }\n \n-static void mlx5e_deactivate_channels(struct mlx5e_channels *chs)\n+static void mlx5e_deactivate_channels_pre_sync(struct mlx5e_channels *chs)\n {\n \tint i;\n \n \tif (chs-\u003eptp)\n-\t\tmlx5e_ptp_deactivate_channel(chs-\u003eptp);\n+\t\tmlx5e_ptp_deactivate_channel_pre_sync(chs-\u003eptp);\n \n \tfor (i = 0; i \u003c chs-\u003enum; i++)\n-\t\tmlx5e_deactivate_channel(chs-\u003ec[i]);\n+\t\tmlx5e_deactivate_channel_pre_sync(chs-\u003ec[i]);\n }\n \n-void mlx5e_close_channels(struct mlx5e_channels *chs)\n+static void mlx5e_deactivate_channels_post_sync(struct mlx5e_channels *chs)\n+{\n+\tint i;\n+\n+\tif (chs-\u003eptp)\n+\t\tmlx5e_ptp_deactivate_channel_post_sync(chs-\u003eptp);\n+\n+\tfor (i = 0; i \u003c chs-\u003enum; i++)\n+\t\tmlx5e_deactivate_channel_post_sync(chs-\u003ec[i]);\n+}\n+\n+static void mlx5e_close_channels_pre_sync(struct mlx5e_channels *chs)\n+{\n+\tint i;\n+\n+\tfor (i = 0; i \u003c chs-\u003enum; i++)\n+\t\tmlx5e_close_channel_pre_sync(chs-\u003ec[i]);\n+}\n+\n+static void mlx5e_close_channels_post_sync(struct mlx5e_channels *chs)\n {\n \tint i;\n \n-\tASSERT_RTNL();\n \tif (chs-\u003eptp) {\n-\t\tmlx5e_ptp_close(chs-\u003eptp);\n+\t\tmlx5e_ptp_close_queues(chs-\u003eptp);\n+\t\t__netif_napi_del_locked(\u0026chs-\u003eptp-\u003enapi);\n+\t}\n+\n+\tfor (i = 0; i \u003c chs-\u003enum; i++) {\n+\t\tmlx5e_close_channel_post_sync(chs-\u003ec[i]);\n+\t\t__netif_napi_del_locked(\u0026chs-\u003ec[i]-\u003enapi);\n+\t}\n+\n+\tsynchronize_net();\n+\n+\tif (chs-\u003eptp) {\n+\t\tkvfree(chs-\u003eptp);\n \t\tchs-\u003eptp = NULL;\n \t}\n+\n \tfor (i = 0; i \u003c chs-\u003enum; i++)\n-\t\tmlx5e_close_channel(chs-\u003ec[i]);\n+\t\tkvfree(chs-\u003ec[i]);\n \n \tkfree(chs-\u003ec);\n \tchs-\u003enum = 0;\n }\n \n+void mlx5e_close_channels(struct mlx5e_channels *chs)\n+{\n+\tASSERT_RTNL();\n+\tmlx5e_close_channels_pre_sync(chs);\n+\tsynchronize_net();\n+\tmlx5e_close_channels_post_sync(chs);\n+}\n+\n static int mlx5e_modify_tirs_packet_merge(struct mlx5e_priv *priv)\n {\n \tstruct mlx5e_rx_res *res = priv-\u003erx_res;\n@@ -3376,7 +3509,7 @@ static void mlx5e_cancel_tx_timeout_work(struct mlx5e_priv *priv)\n \t\tcancel_work_sync(\u0026priv-\u003etx_timeout_work);\n }\n \n-void mlx5e_deactivate_priv_channels(struct mlx5e_priv *priv)\n+static void mlx5e_deactivate_priv_channels_pre_sync(struct mlx5e_priv *priv)\n {\n \tif (priv-\u003erx_res)\n \t\tmlx5e_rx_res_channels_deactivate(priv-\u003erx_res);\n@@ -3394,8 +3527,21 @@ void mlx5e_deactivate_priv_channels(struct mlx5e_priv *priv)\n \t */\n \tnetif_tx_disable(priv-\u003enetdev);\n \n-\tmlx5e_xdp_tx_disable(priv);\n-\tmlx5e_deactivate_channels(\u0026priv-\u003echannels);\n+\tmlx5e_xdp_tx_disable_pre_sync(priv);\n+\tmlx5e_deactivate_channels_pre_sync(\u0026priv-\u003echannels);\n+}\n+\n+static void mlx5e_deactivate_priv_channels_post_sync(struct mlx5e_priv *priv)\n+{\n+\tmlx5e_deactivate_channels_post_sync(\u0026priv-\u003echannels);\n+}\n+\n+void mlx5e_deactivate_priv_channels(struct mlx5e_priv *priv)\n+{\n+\tmlx5e_deactivate_priv_channels_pre_sync(priv);\n+\t/* One grace period for XDP, RQ, ICOSQ, TX, QoS, XSK and PTP. */\n+\tsynchronize_net();\n+\tmlx5e_deactivate_priv_channels_post_sync(priv);\n }\n \n static int mlx5e_switch_priv_params(struct mlx5e_priv *priv,\n@@ -3611,8 +3757,14 @@ int mlx5e_close_locked(struct net_device *netdev)\n \tclear_bit(MLX5E_STATE_OPENED, \u0026priv-\u003estate);\n \n \tnetif_carrier_off(priv-\u003enetdev);\n-\tmlx5e_deactivate_priv_channels(priv);\n-\tmlx5e_close_channels(\u0026priv-\u003echannels);\n+\n+\tmlx5e_deactivate_priv_channels_pre_sync(priv);\n+\tmlx5e_close_channels_pre_sync(\u0026priv-\u003echannels);\n+\n+\tsynchronize_net();\n+\n+\tmlx5e_deactivate_priv_channels_post_sync(priv);\n+\tmlx5e_close_channels_post_sync(\u0026priv-\u003echannels);\n \n \treturn 0;\n }\n"
}

2/1 2026/10/11 13:44 agent patch-evaluator
0m Model:
core

Args:
null

Results:
{
  "EnableConfigs": null,
  "FocusSymbols": [],
  "Reasoning": "The patch modifies channel deactivation and teardown logic within the Mellanox ConnectX Ethernet driver (mlx5). This driver requires vendor-specific Mellanox PCIe network hardware (e.g., ConnectX series / BlueField) which is not emulated in standard virtualized QEMU or GCE test environments, making the modified code structurally unreachable for syzkaller fuzzing.",
  "WorthFuzzing": false
}

Instruction:
You are an expert Linux kernel maintainer and security engineer.
Your job is to review a provided patch series and evaluate whether it warrants fuzzing with syzkaller.

IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in
your workspace. Do NOT rely on internal assumptions. You must actively use your code access
tools to inspect the actual source code, callers, and surrounding context.

================================================================================
1. CORE TRIAGE PHILOSOPHY
================================================================================
The goal of patch fuzzing is to discover crashes, regressions, exposed latent bugs,
and newly triggered assertions introduced by the patch series.

- REACHABILITY IS THE PRIMARY GATE:
  Fuzzing can only discover bugs in code that can actually execute in standard virtualized
  environments (GCE or QEMU, utilizing software-emulated devices like USB gadgets, netdev, tun/tap).
  If the modified code is structurally unreachable (see Section 2), it MUST NOT be fuzzed,
  regardless of whether it adds assertions or complex logic.

- DO NOT BLINDLY TRUST "NO FUNCTIONAL CHANGE" (NFCI) OR "REFACTORING" CLAIMS:
  Patch authors routinely label changes as "cleanups", "refactorings", or state
  "No functional change intended". Do NOT take these claims at face value.
  Code refactorings that rearrange logic, introduce helper functions, or alter state management
  in core subsystems frequently introduce subtle semantic shifts or uncover latent kernel bugs.
  If reachable executable code is modified or refactored, it MUST be fuzzed.

- NEW OR MODIFIED ASSERTIONS IN REACHABLE CODE MUST BE FUZZED:
  When a patch introduces or modifies runtime checks or assertions (e.g., WARN_ON*, VM_WARN_ON*,
  BUG_ON*, lockdep_assert*) in reachable code paths, it enforces new or stricter invariants.
  Even if the author believes the invariant always holds, fuzzing is essential to verify whether
  an unusual sequence of operations can violate it.

================================================================================
2. WHEN TO RETURN WorthFuzzing=false (NEGATIVE CRITERIA)
================================================================================
Return WorthFuzzing=false ONLY IF all modified code falls strictly into one or more of these categories:

- Non-kernel and non-executable changes:
  * Modifications to Documentation/, comments, or spelling fixes.
  * User-space directories, self-tests, samples, or scripts (e.g., tools/, samples/, scripts/, usr/)
    that do not affect the compiled kernel image (vmlinux) or kernel modules.
  * Purely decorative logging (e.g., message strings in pr_err, printk, dev_info) or tracepoints
    that do not alter control flow or data structures.
  * Build system or Kconfig changes that do not alter compiled C logic.
- Structurally unreachable hardware:
  * Vendor-specific PCIe switches, SmartNICs, or GPU drivers (e.g., mlxsw, pds_core, qed,
    ionic, amdgpu) requiring physical ASIC/PCIe cards not emulated in standard QEMU.
- Unreachable execution paths:
  * Driver teardown callbacks (.remove, .shutdown, pci_unregister_driver) executed only during
    physical PCI hot-unplug or manual sysfs driver unbinding.
  * Code paths exclusive to architectures other than the target architecture.

================================================================================
3. WHEN TO RETURN WorthFuzzing=true (POSITIVE CRITERIA)
================================================================================
Return WorthFuzzing=true whenever the patch touches reachable executable code, including:
- Core Subsystems:
  * Any logic modifications in memory management (mm/), synchronization/locking (kernel/locking/),
    BPF, scheduler, core networking, VFS, or syscall handling.
- Refactorings and Code Cleanups:
  * Any restructuring of reachable data structures, helper abstractions, or algorithm flows.
- Runtime Assertions and Defensive Checks:
  * Any introduction or alteration of assertions (WARN_ON*, VM_WARN_ON*, BUG_ON*, etc.) in reachable paths.
- Reachable Drivers and Protocols:
  * Drivers accessible via virtual buses (virtio, USB gadget, loopback, netlink, binder, sockets, etc.).

================================================================================
4. EXTRACTING FocusSymbols (PREVENTING DILUTION)
================================================================================
When WorthFuzzing=true, you must extract specific kernel functions into FocusSymbols to guide the fuzzer:

- AVOID UBIQUITOUS LIFECYCLE HOT-PATHS:
  Do NOT list generic, ubiquitous functions called by almost every program in the corpus
  (including, but not limited to: general memory allocators and deallocators, page fault
  and trap handlers, or core synchronization primitives; this is not an exhaustive list).
  Listing ubiquitous functions causes the fuzzer to classify thousands of unrelated tests as "focused",
  which severely dilutes fuzzing effort away from the actual changes.

- TARGET SPECIFIC FEATURE LOGIC AND ENTRYPOINTS:
  List functions that specifically implement the logic being added or altered, or direct API entrypoints
  for the subsystem feature under review.

- HANDLING STATIC INLINE FUNCTIONS IN HEADERS (.h):
  Compiler-inlined static functions (such as static inlines in mm/*.h or include/linux/*.h) lack
  distinct symbol addresses in vmlinux and cannot be targeted directly by symbol coverage filters.
  If the changes are primarily in static inline helpers, identify non-static, feature-specific caller
  functions in .c files that exercise them (avoiding ubiquitous lifecycle wrappers).

================================================================================
5. IDENTIFYING EnableConfigs
================================================================================
Identify any specific CONFIG_ options required to properly compile and reach the modified code:
- Inspect Kconfig files and #ifdef guards; do not make assumptions.
- Check "depends on" lines in Kconfig to include any non-standard parent subsystem configs needed.
- Strip any 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4").
Prefer calling several tools at the same time to save round-trips.


Use set-results tool to provide results of the analysis.
It must be called exactly once before the final reply.
Ignore results of this tool.

Prompt:
Target architecture: amd64

For your convenience, here is the diff of the changes:
commit dfe5dd924b063198771d6d489f153a31a4b953c8
Author: syz-cluster <triage@syzkaller.com>
Date:   Sun Oct 11 13:43:58 2026 +0000

    syz-cluster: applied patch under review

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index a3945195f454e..1a169fce075af 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -1103,6 +1103,7 @@ int mlx5e_open_xdpsq(struct mlx5e_channel *c, struct mlx5e_params *params,
 		     struct mlx5e_sq_param *param, struct xsk_buff_pool *xsk_pool,
 		     struct mlx5e_xdpsq *sq, bool is_redirect);
 void mlx5e_close_xdpsq(struct mlx5e_xdpsq *sq);
+void mlx5e_close_xdpsq_post_sync(struct mlx5e_xdpsq *sq);
 
 struct mlx5e_create_cq_param {
 	struct net_device *netdev;
@@ -1159,8 +1160,10 @@ int mlx5e_ptp_rx_manage_fs_ctx(struct mlx5e_priv *priv, void *ctx);
 int mlx5e_flush_rq(struct mlx5e_rq *rq, int curr_state);
 void mlx5e_activate_rq(struct mlx5e_rq *rq);
 void mlx5e_deactivate_rq(struct mlx5e_rq *rq);
+void mlx5e_deactivate_rq_pre_sync(struct mlx5e_rq *rq);
 void mlx5e_activate_icosq(struct mlx5e_icosq *icosq);
 void mlx5e_deactivate_icosq(struct mlx5e_icosq *icosq);
+void mlx5e_deactivate_icosq_pre_sync(struct mlx5e_icosq *icosq);
 
 int mlx5e_modify_sq(struct mlx5_core_dev *mdev, u32 sqn,
 		    struct mlx5e_modify_sq_param *p);
@@ -1170,6 +1173,8 @@ int mlx5e_open_txqsq(struct mlx5e_channel *c, u32 tisn, int txq_ix,
 		     struct mlx5e_sq_stats *sq_stats);
 void mlx5e_activate_txqsq(struct mlx5e_txqsq *sq);
 void mlx5e_deactivate_txqsq(struct mlx5e_txqsq *sq);
+void mlx5e_deactivate_txqsq_pre_sync(struct mlx5e_txqsq *sq);
+void mlx5e_deactivate_txqsq_post_sync(struct mlx5e_txqsq *sq);
 void mlx5e_free_txqsq(struct mlx5e_txqsq *sq);
 void mlx5e_tx_disable_queue(struct netdev_queue *txq);
 int mlx5e_alloc_txqsq_db(struct mlx5e_txqsq *sq, int numa);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c
index 17084d76209e8..3fa6292288781 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c
@@ -775,7 +775,7 @@ static int mlx5e_ptp_open_queues(struct mlx5e_ptp *c,
 	return err;
 }
 
-static void mlx5e_ptp_close_queues(struct mlx5e_ptp *c)
+void mlx5e_ptp_close_queues(struct mlx5e_ptp *c)
 {
 	if (test_bit(MLX5E_PTP_STATE_RX, c->state)) {
 		mlx5e_close_rq(&c->rq);
@@ -932,7 +932,6 @@ void mlx5e_ptp_close(struct mlx5e_ptp *c)
 {
 	mlx5e_ptp_close_queues(c);
 	netif_napi_del_locked(&c->napi);
-
 	kvfree(c);
 }
 
@@ -954,18 +953,28 @@ void mlx5e_ptp_activate_channel(struct mlx5e_ptp *c)
 	mlx5e_trigger_napi_sched(&c->napi);
 }
 
-void mlx5e_ptp_deactivate_channel(struct mlx5e_ptp *c)
+void mlx5e_ptp_deactivate_channel_pre_sync(struct mlx5e_ptp *c)
 {
 	int tc;
 
 	if (test_bit(MLX5E_PTP_STATE_RX, c->state)) {
 		netif_queue_set_napi(c->netdev, c->rq.ix, NETDEV_QUEUE_TYPE_RX, NULL);
-		mlx5e_deactivate_rq(&c->rq);
+		mlx5e_deactivate_rq_pre_sync(&c->rq);
+	}
+
+	if (test_bit(MLX5E_PTP_STATE_TX, c->state)) {
+		for (tc = 0; tc < c->num_tc; tc++)
+			mlx5e_deactivate_txqsq_pre_sync(&c->ptpsq[tc].txqsq);
 	}
+}
+
+void mlx5e_ptp_deactivate_channel_post_sync(struct mlx5e_ptp *c)
+{
+	int tc;
 
 	if (test_bit(MLX5E_PTP_STATE_TX, c->state)) {
 		for (tc = 0; tc < c->num_tc; tc++)
-			mlx5e_deactivate_txqsq(&c->ptpsq[tc].txqsq);
+			mlx5e_deactivate_txqsq_post_sync(&c->ptpsq[tc].txqsq);
 	}
 
 	napi_disable_locked(&c->napi);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h
index 2a457a2ed7079..b42ce33635a0a 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h
@@ -129,8 +129,10 @@ static inline bool mlx5e_ptpsq_metadata_freelist_empty(struct mlx5e_ptpsq *ptpsq
 int mlx5e_ptp_open(struct mlx5e_priv *priv, struct mlx5e_params *params,
 		   u8 lag_port, struct mlx5e_ptp **cp);
 void mlx5e_ptp_close(struct mlx5e_ptp *c);
+void mlx5e_ptp_close_queues(struct mlx5e_ptp *c);
 void mlx5e_ptp_activate_channel(struct mlx5e_ptp *c);
-void mlx5e_ptp_deactivate_channel(struct mlx5e_ptp *c);
+void mlx5e_ptp_deactivate_channel_pre_sync(struct mlx5e_ptp *c);
+void mlx5e_ptp_deactivate_channel_post_sync(struct mlx5e_ptp *c);
 int mlx5e_ptp_get_rqn(struct mlx5e_ptp *c, u32 *rqn);
 int mlx5e_ptp_alloc_rx_fs(struct mlx5e_flow_steering *fs,
 			  const struct mlx5e_profile *profile);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/qos.c b/drivers/net/ethernet/mellanox/mlx5/core/en/qos.c
index ac4979087e0dd..3e59862a0e600 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/qos.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/qos.c
@@ -233,15 +233,20 @@ void mlx5e_close_qos_sq(struct mlx5e_priv *priv, u16 qid)
 	kfree(sq);
 }
 
-void mlx5e_qos_close_queues(struct mlx5e_channel *c)
+static struct mlx5e_txqsq __rcu **
+mlx5e_qos_unpublish_queues(struct mlx5e_channel *c)
+{
+	return rcu_replace_pointer(c->qos_sqs, NULL,
+				   lockdep_is_held(&c->priv->state_lock));
+}
+
+static void mlx5e_qos_free_queues(struct mlx5e_channel *c,
+				  struct mlx5e_txqsq __rcu **qos_sqs)
 {
-	struct mlx5e_txqsq __rcu **qos_sqs;
 	int i;
 
-	qos_sqs = rcu_replace_pointer(c->qos_sqs, NULL, lockdep_is_held(&c->priv->state_lock));
 	if (!qos_sqs)
 		return;
-	synchronize_rcu(); /* Sync with NAPI. */
 
 	for (i = 0; i < c->qos_sqs_size; i++) {
 		struct mlx5e_txqsq *sq;
@@ -258,6 +263,27 @@ void mlx5e_qos_close_queues(struct mlx5e_channel *c)
 	kvfree(qos_sqs);
 }
 
+void mlx5e_qos_close_queues_post_sync(struct mlx5e_channel *c)
+{
+	struct mlx5e_txqsq __rcu **qos_sqs;
+
+	qos_sqs = mlx5e_qos_unpublish_queues(c);
+	/* Caller guarantees that NAPI is stopped or was never enabled. */
+	mlx5e_qos_free_queues(c, qos_sqs);
+}
+
+void mlx5e_qos_close_queues(struct mlx5e_channel *c)
+{
+	struct mlx5e_txqsq __rcu **qos_sqs;
+
+	qos_sqs = mlx5e_qos_unpublish_queues(c);
+	if (!qos_sqs)
+		return;
+
+	synchronize_rcu(); /* Sync with NAPI. */
+	mlx5e_qos_free_queues(c, qos_sqs);
+}
+
 void mlx5e_qos_close_all_queues(struct mlx5e_channels *chs)
 {
 	int i;
@@ -326,11 +352,10 @@ void mlx5e_qos_activate_queues(struct mlx5e_priv *priv)
 	mlx5e_htb_enumerate_leaves(priv->htb, mlx5e_activate_qos_sq, priv);
 }
 
-void mlx5e_qos_deactivate_queues(struct mlx5e_channel *c)
+void mlx5e_qos_deactivate_queues_pre_sync(struct mlx5e_channel *c)
 {
 	struct mlx5e_params *params = &c->priv->channels.params;
 	struct mlx5e_txqsq __rcu **qos_sqs;
-	u16 txq_ix;
 	int i;
 
 	qos_sqs = mlx5e_state_dereference(c->priv, c->qos_sqs);
@@ -346,7 +371,30 @@ void mlx5e_qos_deactivate_queues(struct mlx5e_channel *c)
 			continue;
 
 		qos_dbg(c->mdev, "Deactivate QoS SQ qid %u\n", qid);
-		mlx5e_deactivate_txqsq(sq);
+		mlx5e_deactivate_txqsq_pre_sync(sq);
+	}
+}
+
+void mlx5e_qos_deactivate_queues_post_sync(struct mlx5e_channel *c)
+{
+	struct mlx5e_params *params = &c->priv->channels.params;
+	struct mlx5e_txqsq __rcu **qos_sqs;
+	int i;
+
+	qos_sqs = mlx5e_state_dereference(c->priv, c->qos_sqs);
+	if (!qos_sqs)
+		return;
+
+	for (i = 0; i < c->qos_sqs_size; i++) {
+		u16 qid = params->num_channels * i + c->ix;
+		struct mlx5e_txqsq *sq;
+		u16 txq_ix;
+
+		sq = mlx5e_state_dereference(c->priv, qos_sqs[i]);
+		if (!sq)
+			continue;
+
+		mlx5e_deactivate_txqsq_post_sync(sq);
 
 		txq_ix = mlx5e_qid_from_qos(&c->priv->channels, qid);
 
@@ -361,7 +409,12 @@ void mlx5e_qos_deactivate_all_queues(struct mlx5e_channels *chs)
 	int i;
 
 	for (i = 0; i < chs->num; i++)
-		mlx5e_qos_deactivate_queues(chs->c[i]);
+		mlx5e_qos_deactivate_queues_pre_sync(chs->c[i]);
+
+	synchronize_net();
+
+	for (i = 0; i < chs->num; i++)
+		mlx5e_qos_deactivate_queues_post_sync(chs->c[i]);
 }
 
 void mlx5e_reactivate_qos_sq(struct mlx5e_priv *priv, u16 qid, struct netdev_queue *txq)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/qos.h b/drivers/net/ethernet/mellanox/mlx5/core/en/qos.h
index 4947afa23b732..8d171a1079e95 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/qos.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/qos.h
@@ -28,9 +28,11 @@ void mlx5e_reset_qdisc(struct net_device *dev, u16 qid);
 
 int mlx5e_qos_open_queues(struct mlx5e_priv *priv, struct mlx5e_channels *chs);
 void mlx5e_qos_activate_queues(struct mlx5e_priv *priv);
-void mlx5e_qos_deactivate_queues(struct mlx5e_channel *c);
+void mlx5e_qos_deactivate_queues_pre_sync(struct mlx5e_channel *c);
+void mlx5e_qos_deactivate_queues_post_sync(struct mlx5e_channel *c);
 void mlx5e_qos_deactivate_all_queues(struct mlx5e_channels *chs);
 void mlx5e_qos_close_queues(struct mlx5e_channel *c);
+void mlx5e_qos_close_queues_post_sync(struct mlx5e_channel *c);
 void mlx5e_qos_close_all_queues(struct mlx5e_channels *chs);
 int mlx5e_qos_alloc_queues(struct mlx5e_priv *priv, struct mlx5e_channels *chs);
 
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.h b/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.h
index 5b8f4094d5530..ea557a8310e56 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.h
@@ -130,14 +130,12 @@ static inline void mlx5e_xdp_tx_enable(struct mlx5e_priv *priv)
 		set_bit(MLX5E_STATE_XDP_ACTIVE, &priv->state);
 }
 
-static inline void mlx5e_xdp_tx_disable(struct mlx5e_priv *priv)
+static inline void mlx5e_xdp_tx_disable_pre_sync(struct mlx5e_priv *priv)
 {
 	if (priv->channels.params.xdp_prog)
 		clear_bit(MLX5E_STATE_XDP_ACTIVE, &priv->state);
 
 	clear_bit(MLX5E_STATE_XDP_TX_ENABLED, &priv->state);
-	/* Let other device's napi(s) and XSK wakeups see our new state. */
-	synchronize_net();
 }
 
 static inline bool mlx5e_xdp_tx_is_enabled(struct mlx5e_priv *priv)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.c b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.c
index 11500fd213a55..deb84ef29ca1c 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.c
@@ -160,23 +160,35 @@ int mlx5e_open_xsk(struct mlx5e_priv *priv, struct mlx5e_params *params,
 err_close_rx_cq:
 	mlx5e_close_cq(&c->xskrq.cq);
 
+	c->xskrq.xsk_pool = NULL;
+	c->xsksq.xsk_pool = NULL;
+
 	return err;
 }
 
-void mlx5e_close_xsk(struct mlx5e_channel *c)
+void mlx5e_close_xsk_pre_sync(struct mlx5e_channel *c)
 {
 	clear_bit(MLX5E_CHANNEL_STATE_XSK, c->state);
-	synchronize_net(); /* Sync with NAPI. */
+}
 
+void mlx5e_close_xsk_post_sync(struct mlx5e_channel *c)
+{
 	mlx5e_close_rq(&c->xskrq);
 	mlx5e_close_cq(&c->xskrq.cq);
-	mlx5e_close_xdpsq(&c->xsksq);
+	mlx5e_close_xdpsq_post_sync(&c->xsksq);
 	mlx5e_close_cq(&c->xsksq.cq);
 
 	memset(&c->xskrq, 0, sizeof(c->xskrq));
 	memset(&c->xsksq, 0, sizeof(c->xsksq));
 }
 
+void mlx5e_close_xsk(struct mlx5e_channel *c)
+{
+	mlx5e_close_xsk_pre_sync(c);
+	synchronize_net(); /* Sync with XSK wakeup and NAPI. */
+	mlx5e_close_xsk_post_sync(c);
+}
+
 void mlx5e_activate_xsk(struct mlx5e_channel *c)
 {
 	/* ICOSQ recovery deactivates RQs. Suspend the recovery to avoid
@@ -189,7 +201,7 @@ void mlx5e_activate_xsk(struct mlx5e_channel *c)
 	/* TX queue is created active. */
 }
 
-void mlx5e_deactivate_xsk(struct mlx5e_channel *c)
+void mlx5e_deactivate_xsk_pre_sync(struct mlx5e_channel *c)
 {
 	/* ICOSQ recovery may reactivate XSKRQ if clear_bit is called in the
 	 * middle of recovery. Suspend the recovery to avoid it.
@@ -197,7 +209,12 @@ void mlx5e_deactivate_xsk(struct mlx5e_channel *c)
 	mlx5e_reporter_icosq_suspend_recovery(c);
 	clear_bit(MLX5E_RQ_STATE_ENABLED, &c->xskrq.state);
 	mlx5e_reporter_icosq_resume_recovery(c);
-	synchronize_net(); /* Sync with NAPI to prevent mlx5e_post_rx_wqes. */
 
 	/* TX queue is disabled on close. */
 }
+
+void mlx5e_deactivate_xsk(struct mlx5e_channel *c)
+{
+	mlx5e_deactivate_xsk_pre_sync(c);
+	synchronize_net(); /* Sync with NAPI to prevent mlx5e_post_rx_wqes. */
+}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.h b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.h
index 664ec78192c33..66a0b09452f73 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.h
@@ -17,7 +17,10 @@ int mlx5e_open_xsk(struct mlx5e_priv *priv, struct mlx5e_params *params,
 		   struct xsk_buff_pool *pool,
 		   struct mlx5e_channel *c);
 void mlx5e_close_xsk(struct mlx5e_channel *c);
+void mlx5e_close_xsk_pre_sync(struct mlx5e_channel *c);
+void mlx5e_close_xsk_post_sync(struct mlx5e_channel *c);
 void mlx5e_activate_xsk(struct mlx5e_channel *c);
 void mlx5e_deactivate_xsk(struct mlx5e_channel *c);
+void mlx5e_deactivate_xsk_pre_sync(struct mlx5e_channel *c);
 
 #endif /* __MLX5_EN_XSK_SETUP_H__ */
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index f90b5a34e0972..58e4874b664f1 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -1458,9 +1458,14 @@ void mlx5e_activate_rq(struct mlx5e_rq *rq)
 	set_bit(MLX5E_RQ_STATE_ENABLED, &rq->state);
 }
 
-void mlx5e_deactivate_rq(struct mlx5e_rq *rq)
+void mlx5e_deactivate_rq_pre_sync(struct mlx5e_rq *rq)
 {
 	clear_bit(MLX5E_RQ_STATE_ENABLED, &rq->state);
+}
+
+void mlx5e_deactivate_rq(struct mlx5e_rq *rq)
+{
+	mlx5e_deactivate_rq_pre_sync(rq);
 	synchronize_net(); /* Sync with NAPI to prevent mlx5e_post_rx_wqes. */
 }
 
@@ -1954,13 +1959,15 @@ void mlx5e_tx_disable_queue(struct netdev_queue *txq)
 	__netif_tx_unlock_bh(txq);
 }
 
-void mlx5e_deactivate_txqsq(struct mlx5e_txqsq *sq)
+void mlx5e_deactivate_txqsq_pre_sync(struct mlx5e_txqsq *sq)
 {
-	struct mlx5_wq_cyc *wq = &sq->wq;
-
 	netif_queue_set_napi(sq->netdev, sq->txq_ix, NETDEV_QUEUE_TYPE_TX, NULL);
 	clear_bit(MLX5E_SQ_STATE_ENABLED, &sq->state);
-	synchronize_net(); /* Sync with NAPI to prevent netif_tx_wake_queue. */
+}
+
+void mlx5e_deactivate_txqsq_post_sync(struct mlx5e_txqsq *sq)
+{
+	struct mlx5_wq_cyc *wq = &sq->wq;
 
 	mlx5e_tx_disable_queue(sq->txq);
 
@@ -1978,6 +1985,13 @@ void mlx5e_deactivate_txqsq(struct mlx5e_txqsq *sq)
 	}
 }
 
+void mlx5e_deactivate_txqsq(struct mlx5e_txqsq *sq)
+{
+	mlx5e_deactivate_txqsq_pre_sync(sq);
+	synchronize_net(); /* Sync with NAPI to prevent netif_tx_wake_queue. */
+	mlx5e_deactivate_txqsq_post_sync(sq);
+}
+
 void mlx5e_close_txqsq(struct mlx5e_txqsq *sq)
 {
 	struct mlx5_core_dev *mdev = sq->mdev;
@@ -2089,9 +2103,14 @@ void mlx5e_activate_icosq(struct mlx5e_icosq *icosq)
 	set_bit(MLX5E_SQ_STATE_ENABLED, &icosq->state);
 }
 
-void mlx5e_deactivate_icosq(struct mlx5e_icosq *icosq)
+void mlx5e_deactivate_icosq_pre_sync(struct mlx5e_icosq *icosq)
 {
 	clear_bit(MLX5E_SQ_STATE_ENABLED, &icosq->state);
+}
+
+void mlx5e_deactivate_icosq(struct mlx5e_icosq *icosq)
+{
+	mlx5e_deactivate_icosq_pre_sync(icosq);
 	synchronize_net(); /* Sync with NAPI. */
 }
 
@@ -2141,18 +2160,28 @@ int mlx5e_open_xdpsq(struct mlx5e_channel *c, struct mlx5e_params *params,
 	return err;
 }
 
-void mlx5e_close_xdpsq(struct mlx5e_xdpsq *sq)
+static void mlx5e_destroy_xdpsq(struct mlx5e_xdpsq *sq)
 {
 	struct mlx5e_channel *c = sq->channel;
 
-	clear_bit(MLX5E_SQ_STATE_ENABLED, &sq->state);
-	synchronize_net(); /* Sync with NAPI. */
-
 	mlx5e_destroy_sq(c->mdev, sq->sqn);
 	mlx5e_free_xdpsq_descs(sq);
 	mlx5e_free_xdpsq(sq);
 }
 
+void mlx5e_close_xdpsq_post_sync(struct mlx5e_xdpsq *sq)
+{
+	clear_bit(MLX5E_SQ_STATE_ENABLED, &sq->state);
+	mlx5e_destroy_xdpsq(sq);
+}
+
+void mlx5e_close_xdpsq(struct mlx5e_xdpsq *sq)
+{
+	clear_bit(MLX5E_SQ_STATE_ENABLED, &sq->state);
+	synchronize_net(); /* Sync with NAPI. */
+	mlx5e_destroy_xdpsq(sq);
+}
+
 static struct mlx5e_xdpsq *mlx5e_open_xdpredirect_sq(struct mlx5e_channel *c,
 						     struct mlx5e_params *params,
 						     struct mlx5e_channel_param *cparam,
@@ -2184,6 +2213,13 @@ static struct mlx5e_xdpsq *mlx5e_open_xdpredirect_sq(struct mlx5e_channel *c,
 	return ERR_PTR(err);
 }
 
+static void mlx5e_close_xdpredirect_sq_post_sync(struct mlx5e_xdpsq *xdpsq)
+{
+	mlx5e_close_xdpsq_post_sync(xdpsq);
+	mlx5e_close_cq(&xdpsq->cq);
+	kvfree(xdpsq);
+}
+
 static void mlx5e_close_xdpredirect_sq(struct mlx5e_xdpsq *xdpsq)
 {
 	mlx5e_close_xdpsq(xdpsq);
@@ -2749,6 +2785,27 @@ static void mlx5e_close_queues(struct mlx5e_channel *c)
 	mlx5e_close_cq(&c->icosq.cq);
 }
 
+static void mlx5e_close_queues_post_sync(struct mlx5e_channel *c)
+{
+	if (c->xdp)
+		mlx5e_close_xdpsq_post_sync(&c->rq_xdpsq);
+	/* The same ICOSQ is used for UMRs for both RQ and XSKRQ. */
+	cancel_work_sync(&c->icosq.recover_work);
+	mlx5e_close_rq(&c->rq);
+	mlx5e_close_sqs(c);
+	mlx5e_close_icosq(&c->icosq);
+	mutex_destroy(&c->icosq_recovery_lock);
+	if (c->async_icosq)
+		mlx5e_close_async_icosq(c->async_icosq);
+	if (c->xdp)
+		mlx5e_close_cq(&c->rq_xdpsq.cq);
+	mlx5e_close_cq(&c->rq.cq);
+	if (c->xdpsq)
+		mlx5e_close_xdpredirect_sq_post_sync(c->xdpsq);
+	mlx5e_close_tx_cqs(c);
+	mlx5e_close_cq(&c->icosq.cq);
+}
+
 static u8 mlx5e_enumerate_lag_port(struct mlx5_core_dev *mdev, int ix)
 {
 	u16 port_aff_bias = mlx5_core_is_pf(mdev) ? 0 : MLX5_CAP_GEN(mdev, vhca_id);
@@ -2780,14 +2837,11 @@ static int mlx5e_channel_stats_alloc(struct mlx5e_priv *priv, int ix, int cpu)
 	return 0;
 }
 
-void mlx5e_trigger_napi_icosq(struct mlx5e_channel *c)
+static void mlx5e_trigger_napi_icosq_post_sync(struct mlx5e_channel *c)
 {
 	struct mlx5e_icosq *sq = &c->icosq;
 	bool locked;
 
-	set_bit(MLX5E_SQ_STATE_LOCK_NEEDED, &sq->state);
-	synchronize_net();
-
 	locked = mlx5e_icosq_sync_lock(sq);
 	mlx5e_trigger_irq(sq);
 	mlx5e_icosq_sync_unlock(sq, locked);
@@ -2795,6 +2849,13 @@ void mlx5e_trigger_napi_icosq(struct mlx5e_channel *c)
 	clear_bit(MLX5E_SQ_STATE_LOCK_NEEDED, &sq->state);
 }
 
+void mlx5e_trigger_napi_icosq(struct mlx5e_channel *c)
+{
+	set_bit(MLX5E_SQ_STATE_LOCK_NEEDED, &c->icosq.state);
+	synchronize_net();
+	mlx5e_trigger_napi_icosq_post_sync(c);
+}
+
 void mlx5e_trigger_napi_async_icosq(struct mlx5e_channel *c)
 {
 	struct mlx5e_icosq *sq = c->async_icosq;
@@ -2936,35 +2997,56 @@ static void mlx5e_activate_channel(struct mlx5e_channel *c)
 	netif_queue_set_napi(c->netdev, c->ix, NETDEV_QUEUE_TYPE_RX, &c->napi);
 }
 
-static void mlx5e_deactivate_channel(struct mlx5e_channel *c)
+static void mlx5e_deactivate_channel_pre_sync(struct mlx5e_channel *c)
 {
 	int tc;
 
 	netif_queue_set_napi(c->netdev, c->ix, NETDEV_QUEUE_TYPE_RX, NULL);
 
 	if (test_bit(MLX5E_CHANNEL_STATE_XSK, c->state))
-		mlx5e_deactivate_xsk(c);
+		mlx5e_deactivate_xsk_pre_sync(c);
 	else
-		mlx5e_deactivate_rq(&c->rq);
+		mlx5e_deactivate_rq_pre_sync(&c->rq);
 
 	if (c->async_icosq)
-		mlx5e_deactivate_icosq(c->async_icosq);
-	mlx5e_deactivate_icosq(&c->icosq);
+		mlx5e_deactivate_icosq_pre_sync(c->async_icosq);
+	mlx5e_deactivate_icosq_pre_sync(&c->icosq);
+	for (tc = 0; tc < c->num_tc; tc++)
+		mlx5e_deactivate_txqsq_pre_sync(&c->sq[tc]);
+	mlx5e_qos_deactivate_queues_pre_sync(c);
+}
+
+static void mlx5e_deactivate_channel_post_sync(struct mlx5e_channel *c)
+{
+	int tc;
+
 	for (tc = 0; tc < c->num_tc; tc++)
-		mlx5e_deactivate_txqsq(&c->sq[tc]);
-	mlx5e_qos_deactivate_queues(c);
+		mlx5e_deactivate_txqsq_post_sync(&c->sq[tc]);
+	mlx5e_qos_deactivate_queues_post_sync(c);
 
 	napi_disable_locked(&c->napi);
 }
 
-static void mlx5e_close_channel(struct mlx5e_channel *c)
+static void mlx5e_close_channel_pre_sync(struct mlx5e_channel *c)
 {
 	if (test_bit(MLX5E_CHANNEL_STATE_XSK, c->state))
-		mlx5e_close_xsk(c);
-	mlx5e_close_queues(c);
-	mlx5e_qos_close_queues(c);
-	netif_napi_del_locked(&c->napi);
+		mlx5e_close_xsk_pre_sync(c);
+}
+
+static void mlx5e_close_channel_post_sync(struct mlx5e_channel *c)
+{
+	if (c->xskrq.xsk_pool)
+		mlx5e_close_xsk_post_sync(c);
+	mlx5e_close_queues_post_sync(c);
+	mlx5e_qos_close_queues_post_sync(c);
+}
 
+static void mlx5e_close_channel(struct mlx5e_channel *c)
+{
+	mlx5e_close_channel_pre_sync(c);
+	synchronize_net();
+	mlx5e_close_channel_post_sync(c);
+	netif_napi_del_locked(&c->napi);
 	kvfree(c);
 }
 
@@ -3021,6 +3103,19 @@ int mlx5e_open_channels(struct mlx5e_priv *priv,
 	return err;
 }
 
+static void mlx5e_trigger_napi_icosqs(struct mlx5e_channels *chs)
+{
+	int i;
+
+	for (i = 0; i < chs->num; i++)
+		set_bit(MLX5E_SQ_STATE_LOCK_NEEDED, &chs->c[i]->icosq.state);
+
+	synchronize_net();
+
+	for (i = 0; i < chs->num; i++)
+		mlx5e_trigger_napi_icosq_post_sync(chs->c[i]);
+}
+
 static void mlx5e_activate_channels(struct mlx5e_priv *priv, struct mlx5e_channels *chs)
 {
 	int i;
@@ -3031,8 +3126,7 @@ static void mlx5e_activate_channels(struct mlx5e_priv *priv, struct mlx5e_channe
 	if (priv->htb)
 		mlx5e_qos_activate_queues(priv);
 
-	for (i = 0; i < chs->num; i++)
-		mlx5e_trigger_napi_icosq(chs->c[i]);
+	mlx5e_trigger_napi_icosqs(chs);
 
 	if (chs->ptp)
 		mlx5e_ptp_activate_channel(chs->ptp);
@@ -3060,33 +3154,72 @@ static int mlx5e_wait_channels_min_rx_wqes(struct mlx5e_channels *chs)
 	return err ? -ETIMEDOUT : 0;
 }
 
-static void mlx5e_deactivate_channels(struct mlx5e_channels *chs)
+static void mlx5e_deactivate_channels_pre_sync(struct mlx5e_channels *chs)
 {
 	int i;
 
 	if (chs->ptp)
-		mlx5e_ptp_deactivate_channel(chs->ptp);
+		mlx5e_ptp_deactivate_channel_pre_sync(chs->ptp);
 
 	for (i = 0; i < chs->num; i++)
-		mlx5e_deactivate_channel(chs->c[i]);
+		mlx5e_deactivate_channel_pre_sync(chs->c[i]);
 }
 
-void mlx5e_close_channels(struct mlx5e_channels *chs)
+static void mlx5e_deactivate_channels_post_sync(struct mlx5e_channels *chs)
+{
+	int i;
+
+	if (chs->ptp)
+		mlx5e_ptp_deactivate_channel_post_sync(chs->ptp);
+
+	for (i = 0; i < chs->num; i++)
+		mlx5e_deactivate_channel_post_sync(chs->c[i]);
+}
+
+static void mlx5e_close_channels_pre_sync(struct mlx5e_channels *chs)
+{
+	int i;
+
+	for (i = 0; i < chs->num; i++)
+		mlx5e_close_channel_pre_sync(chs->c[i]);
+}
+
+static void mlx5e_close_channels_post_sync(struct mlx5e_channels *chs)
 {
 	int i;
 
-	ASSERT_RTNL();
 	if (chs->ptp) {
-		mlx5e_ptp_close(chs->ptp);
+		mlx5e_ptp_close_queues(chs->ptp);
+		__netif_napi_del_locked(&chs->ptp->napi);
+	}
+
+	for (i = 0; i < chs->num; i++) {
+		mlx5e_close_channel_post_sync(chs->c[i]);
+		__netif_napi_del_locked(&chs->c[i]->napi);
+	}
+
+	synchronize_net();
+
+	if (chs->ptp) {
+		kvfree(chs->ptp);
 		chs->ptp = NULL;
 	}
+
 	for (i = 0; i < chs->num; i++)
-		mlx5e_close_channel(chs->c[i]);
+		kvfree(chs->c[i]);
 
 	kfree(chs->c);
 	chs->num = 0;
 }
 
+void mlx5e_close_channels(struct mlx5e_channels *chs)
+{
+	ASSERT_RTNL();
+	mlx5e_close_channels_pre_sync(chs);
+	synchronize_net();
+	mlx5e_close_channels_post_sync(chs);
+}
+
 static int mlx5e_modify_tirs_packet_merge(struct mlx5e_priv *priv)
 {
 	struct mlx5e_rx_res *res = priv->rx_res;
@@ -3376,7 +3509,7 @@ static void mlx5e_cancel_tx_timeout_work(struct mlx5e_priv *priv)
 		cancel_work_sync(&priv->tx_timeout_work);
 }
 
-void mlx5e_deactivate_priv_channels(struct mlx5e_priv *priv)
+static void mlx5e_deactivate_priv_channels_pre_sync(struct mlx5e_priv *priv)
 {
 	if (priv->rx_res)
 		mlx5e_rx_res_channels_deactivate(priv->rx_res);
@@ -3394,8 +3527,21 @@ void mlx5e_deactivate_priv_channels(struct mlx5e_priv *priv)
 	 */
 	netif_tx_disable(priv->netdev);
 
-	mlx5e_xdp_tx_disable(priv);
-	mlx5e_deactivate_channels(&priv->channels);
+	mlx5e_xdp_tx_disable_pre_sync(priv);
+	mlx5e_deactivate_channels_pre_sync(&priv->channels);
+}
+
+static void mlx5e_deactivate_priv_channels_post_sync(struct mlx5e_priv *priv)
+{
+	mlx5e_deactivate_channels_post_sync(&priv->channels);
+}
+
+void mlx5e_deactivate_priv_channels(struct mlx5e_priv *priv)
+{
+	mlx5e_deactivate_priv_channels_pre_sync(priv);
+	/* One grace period for XDP, RQ, ICOSQ, TX, QoS, XSK and PTP. */
+	synchronize_net();
+	mlx5e_deactivate_priv_channels_post_sync(priv);
 }
 
 static int mlx5e_switch_priv_params(struct mlx5e_priv *priv,
@@ -3611,8 +3757,14 @@ int mlx5e_close_locked(struct net_device *netdev)
 	clear_bit(MLX5E_STATE_OPENED, &priv->state);
 
 	netif_carrier_off(priv->netdev);
-	mlx5e_deactivate_priv_channels(priv);
-	mlx5e_close_channels(&priv->channels);
+
+	mlx5e_deactivate_priv_channels_pre_sync(priv);
+	mlx5e_close_channels_pre_sync(&priv->channels);
+
+	synchronize_net();
+
+	mlx5e_deactivate_priv_channels_post_sync(priv);
+	mlx5e_close_channels_post_sync(&priv->channels);
 
 	return 0;
 }

3/2 2026/10/11 13:44 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 14546
							output: 23
							thoughts: 504
						

Thoughts:
**Evaluating a Kernel Commit for Syzkaller Fuzzing Potential**

Okay, let's dive into this commit and figure out if it's a good candidate for syzkaller. I need to assess whether fuzzing it is even feasible. First, I need to see what files are touched: `drivers/net/ethernet/mellanox/mlx5/core/en.h`, `drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c`, `drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h`, `drivers/net/ethernet/mellanox/mlx5/core/en/qos.c`, `drivers/net/ethernet/mellanox/mlx5/core/en/qos.h`, `drivers/net/ethernet/mellanox/mlx5/core/en/xdp.h`, `drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.c`, `drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.h`, and `drivers/net/ethernet/mellanox/mlx5/core/en_main.c`. Seems like a lot of Mellanox networking code.

But wait a minute...Mellanox! My first thought is whether syzkaller can even reach this. I remember reading something about hardware dependencies in the syzkaller documentation. Let me double-check the instructions. Ah, here it is: "Structurally unreachable hardware: * Vendor-specific PCIe switches, SmartNICs, or GPU drivers (e.g., mlxsw, pds_core, qed, ionic, amdgpu) requiring physical ASIC/PCIe cards not emulated in standard QEMU."

Shoot, "mlxsw" is in there... and mlx5 is *very* similar. Okay, so is Mellanox mlx5 a vendor-specific PCIe hardware thing? That's the key question. It’s Mellanox ConnectX-4, ConnectX-5, ConnectX-6 etc. adapter. Right, that's Ethernet / InfiniBand. Definitely hardware! Now, does QEMU emulate that? Nope. QEMU does *not* emulate this type of hardware.

So... is there *any* kind of virtual device, mock driver, anything that allows it to be tested without the actual PCI hardware? If it’s *purely* physical PCI hardware, then we're dead in the water, and this is a no-go for syzkaller. Time to dig into the kernel source and verify. I need to confirm if it *requires* a physical PCI device.



4/2 2026/10/11 13:44 tool grepper
0m Args:
{
  "Expression": "pci_register_driver.*mlx5"
}

Results:
{
  "Output": "drivers/net/ethernet/mellanox/mlx5/core/data_direct.c=392=int mlx5_data_direct_driver_register(void)\ndrivers/net/ethernet/mellanox/mlx5/core/data_direct.c-393-{\ndrivers/net/ethernet/mellanox/mlx5/core/data_direct.c:394:\treturn pci_register_driver(\u0026mlx5_data_direct_driver);\ndrivers/net/ethernet/mellanox/mlx5/core/data_direct.c-395-}\n--\ndrivers/net/ethernet/mellanox/mlx5/core/main.c=2350=static int __init mlx5_init(void)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/main.c-2373-\ndrivers/net/ethernet/mellanox/mlx5/core/main.c:2374:\terr = pci_register_driver(\u0026mlx5_core_driver);\ndrivers/net/ethernet/mellanox/mlx5/core/main.c-2375-\tif (err)\n"
}

5/2 2026/10/11 13:44 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 15960
							output: 26
							thoughts: 12
						

Thoughts:
Okay, here's my take on those thoughts, tailored for an expert audience, presented in the first person:

**Diving into `mlx5_core_driver`**

Alright, let's get down to brass tacks. My initial thought is to zoom in on the `mlx5_core_driver`. I need to understand its behavior and contribution to the system's performance, especially considering the nuances of high-speed interconnects. My mind immediately starts running through key areas: what kind of performance metrics am I expecting from it? Are there any obvious bottlenecks or potential areas for optimization that I can start to explore? I'm thinking about RDMA, of course, and whether the implementation is taking full advantage of the hardware's capabilities. I'm wondering about the driver's interaction with the kernel, specifically how efficiently it manages resources and handles interrupts. Are there any known issues I should be aware of, perhaps related to specific firmware versions or hardware revisions? This is the starting point to thoroughly analyze.



6/2 2026/10/11 13:44 tool grepper
0m Args:
{
  "Expression": "struct pci_driver mlx5_core_driver"
}

Results:
{
  "Output": "drivers/net/ethernet/mellanox/mlx5/core/main.c=2272=int mlx5_recover_device(struct mlx5_core_dev *dev)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/main.c-2282-\ndrivers/net/ethernet/mellanox/mlx5/core/main.c:2283:static struct pci_driver mlx5_core_driver = {\ndrivers/net/ethernet/mellanox/mlx5/core/main.c-2284-\t.name           = KBUILD_MODNAME,\n"
}

7/2 2026/10/11 13:44 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 16373
							output: 43
							thoughts: 37
						

Thoughts:
Here's my take on the thought process:

**Diving into the mlx5 Core PCI Configuration**

Okay, I need to investigate something related to the `mlx5` driver, and it's likely linked to the PCI configuration. Let's start by zeroing in on the `mlx5_core_pci_table`. That table is usually where the driver associates specific PCI device IDs with corresponding driver structures, so that's a logical first stop. I'll need to open up `drivers/net/ethernet/mellanox/mlx5/core/main.c` to find that table and see what's defined. Hopefully, there's enough information there to point me in the right direction. This should give me a solid foundation for understanding the context of the issue I'm working on.



8/2 2026/10/11 13:44 tool grepper
0m Args:
{
  "Expression": "mlx5_core_pci_table",
  "PathPrefixes": [
    "drivers/net/ethernet/mellanox/mlx5"
  ]
}

Results:
{
  "Output": "drivers/net/ethernet/mellanox/mlx5/core/main.c=2220=static int mlx5_resume(struct pci_dev *pdev)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/main.c-2226-\ndrivers/net/ethernet/mellanox/mlx5/core/main.c:2227:static const struct pci_device_id mlx5_core_pci_table[] = {\ndrivers/net/ethernet/mellanox/mlx5/core/main.c-2228-\t{ PCI_VDEVICE(MELLANOX, PCI_DEVICE_ID_MELLANOX_CONNECTIB) },\n--\ndrivers/net/ethernet/mellanox/mlx5/core/main.c-2263-\ndrivers/net/ethernet/mellanox/mlx5/core/main.c:2264:MODULE_DEVICE_TABLE(pci, mlx5_core_pci_table);\ndrivers/net/ethernet/mellanox/mlx5/core/main.c-2265-\n--\ndrivers/net/ethernet/mellanox/mlx5/core/main.c=2283=static struct pci_driver mlx5_core_driver = {\ndrivers/net/ethernet/mellanox/mlx5/core/main.c-2284-\t.name           = KBUILD_MODNAME,\ndrivers/net/ethernet/mellanox/mlx5/core/main.c:2285:\t.id_table       = mlx5_core_pci_table,\ndrivers/net/ethernet/mellanox/mlx5/core/main.c-2286-\t.probe          = probe_one,\n"
}

9/2 2026/10/11 13:44 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 17070
							output: 109
							thoughts: 974
						

Thoughts:
**Mellanox mlx5 Driver Analysis for Fuzzing Suitability**

Okay, let's break this down. My analysis indicates that the `mlx5` driver, located in `drivers/net/ethernet/mellanox/mlx5/core/`, is specifically designed to interact with Mellanox ConnectX-4, ConnectX-5, ConnectX-6, and BlueField PCIe devices.  This is a *physical* hardware dependency, confirmed by the PCI device ID checks it performs. It's explicitly tied to hardware, and, importantly, QEMU and Google Compute Engine (GCE) don't emulate this hardware.

The negative criteria in the original prompt are key here: things like `mlxsw`, `qed`, etc. that are vendor-specific and need a physical ASIC or PCIe card are *specifically* excluded. My initial understanding is that `mlx5` fits squarely into *this* exclusion, as it is a SmartNIC driver requiring dedicated Mellanox hardware. `mlxsw` is a Mellanox *switch* driver. `mlx5` is the Mellanox ConnectX *NIC* driver - and therefore fits the same category of excluded drivers as those examples.

I've examined the code touched by the patch, looking at `en.h`, `ptp.c`, `qos.c`, `xdp.h`, `xsk/setup.c`, and `en_main.c`. The changes are all centered around queue/channel management within the `mlx5e` part (the Ethernet driver) of `mlx5_core`. Specifically, I see functions that are triggered by things like netdev going down, parameter changes, channel closing, or queue deactivation, like `mlx5e_deactivate_rq_pre_sync`, `mlx5e_close_xdpsq_post_sync`, and other similar functions. These all operate on the network device *after* a Mellanox ConnectX PCIe device has been probed.

There's no indication of any virtualized interfaces or functionality that bypasses the need for the physical hardware.  Without a Mellanox ConnectX NIC present and probed, there's no way this code path gets exercised in a standard QEMU or GCE environment that syzkaller likely uses. It's structurally unreachable in that context.

Therefore, `WorthFuzzing` should be `false`. The reasoning is clear: the changes are internal to the Mellanox ConnectX Ethernet driver (`mlx5_core`), which *requires* specific Mellanox PCIe hardware, and that hardware isn't emulated in the fuzzing environments syzkaller likely uses. No special configuration is needed to make the code reachable, because it is not. The `EnableConfigs` and `FocusSymbols` arrays should be empty because there's nothing relevant to configure or focus on.



10/2 2026/10/11 13:44 tool set-results
0m Args:
{
  "EnableConfigs": [],
  "FocusSymbols": [],
  "Reasoning": "The patch modifies channel deactivation and teardown logic within the Mellanox ConnectX Ethernet driver (mlx5). This driver requires vendor-specific Mellanox PCIe network hardware (e.g., ConnectX series / BlueField) which is not emulated in standard virtualized QEMU or GCE test environments, making the modified code structurally unreachable for syzkaller fuzzing.",
  "WorthFuzzing": false
}

Results:
{
  "EnableConfigs": null,
  "FocusSymbols": [],
  "Reasoning": "The patch modifies channel deactivation and teardown logic within the Mellanox ConnectX Ethernet driver (mlx5). This driver requires vendor-specific Mellanox PCIe network hardware (e.g., ConnectX series / BlueField) which is not emulated in standard virtualized QEMU or GCE test environments, making the modified code structurally unreachable for syzkaller fuzzing.",
  "WorthFuzzing": false
}

11/1 2026/10/11 13:44 action If
0m Args:
{
  "WorthFuzzing": false
}

Results:
null

LLM Calls Summary:
Total Calls Total Tokens Avg Tokens Total Duration (Seconds) Avg Duration (Seconds)
Tool Calls Summary:
Total Calls Total Duration (Seconds) Avg Duration (Seconds)