From nobody Tue Apr 7 01:17:44 2026 Received: from outbound.baidu.com (mx15.baidu.com [111.202.115.100]) by smtp.subspace.kernel.org (Postfix) with SMTP id D634720C012; Tue, 17 Mar 2026 00:35:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=111.202.115.100 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773707766; cv=none; b=XYn2pcSHSywCjvPptdbf0cnVkAsw3x3IwsMSCvCiUxMrwhtE/F0QSTwDLxHDQYYOLtT0k8uL6TCG+r9dWkG0o4YQyX7rFWs87MyJ+jBbjU9hrtE7f89Gi3HBFOJ8nDIsJzqwzAUnGRp1fIuCX+RaPhdRomDRNlnrX7x8AHdzUcY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773707766; c=relaxed/simple; bh=JGjqeZTdlr33dtOhAGjHtxR6SyjH3lyit3YVGymEvXg=; h=From:To:CC:Subject:Date:Message-ID:MIME-Version:Content-Type; b=dDdH0uxZjaqJPQo2AIIgvOd1locBFLvSLjaOkLCa15nxuV3rtxTs68MkPEv+1ScOFA1qDEiDtXyzxEcbprCd9WMXhh928TnUqmpUakONbYOxjyZ+dnCER3ULeo09Xelx2pKBuwYecf/G6rBqty3Jv6fUaBGYhdQnmjliRa2ow4o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=baidu.com; spf=pass smtp.mailfrom=baidu.com; dkim=pass (2048-bit key) header.d=baidu.com header.i=@baidu.com header.b=mUYmornL; arc=none smtp.client-ip=111.202.115.100 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=baidu.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baidu.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baidu.com header.i=@baidu.com header.b="mUYmornL" X-MD-Sfrom: lirongqing@baidu.com X-MD-SrcIP: 172.31.50.47 From: lirongqing To: Saeed Mahameed , Leon Romanovsky , Tariq Toukan , Mark Bloch , Andrew Lunn , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Li RongQing , "Paul E . McKenney" , Frederic Weisbecker , , , , Andrew Morton CC: liyongkang Subject: [PATCH][net-next v2] net/mlx5: Expedite notifier unregistration during device teardown Date: Mon, 16 Mar 2026 20:35:44 -0400 Message-ID: <20260317003544.2583-1-lirongqing@baidu.com> X-Mailer: git-send-email 2.17.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: bjkjy-exc3.internal.baidu.com (172.31.50.47) To bjkjy-exc3.internal.baidu.com (172.31.50.47) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baidu.com; s=selector1; t=1773707758; bh=gRO5j431xX28a4RYWB1D3tcE+WVpePvtAeGMMBX8AlY=; h=From:To:CC:Subject:Date:Message-ID:Content-Type; b=mUYmornL4p0Fjt9evF1Ug+m4BR8Q43JqgVTbj1cpc+8HmlSlvwm3w8+rtUluzWKfW gwTkP8prV5BZmGua1k2ANUqHNRU3hO1qd1Qg2W1tMkMomdcD7u87GV3l/wG9sgXlU9 X3ZIlF8FbKs7jw9aXNrOlMoefoTTDLEx18S7VXW3EA/428/7Y0+24jKRTZtt5oFXTl +qmqvfm4hcOVJqG9ApdKGUfGUhWxPDgdQG36ihp2hRsjOJ9vFST/f1QkyX9MhnTZ5x WH4uyK8bSjZXuueyoHnOXZlo7s3MBnjBrhknB/czDwIOCjkK5dv85N6Z5OBcCQEsh1 nvaEx9zDA4Daw== Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Li RongQing During device hot-unplug, the mlx5 driver expects quickly unregister notification chains. The standard atomic_notifier_chain_unregister() calls synchronize_rcu(), which introduces significant latency and can become a bottleneck during mass resource cleanup. Introduce atomic_notifier_chain_unregister_expedited() to leverage synchronize_rcu_expedited(), and use it significantly reducing wait times in the following paths: - Event Queue (EQ) notifier chain - Firmware event notifier chain - IRQ notifier chain On x86-64 with HZ=3D1000, 64 networking channels: - Average teardown time: 3.59s -> 1.9s (47% reduction) On x86-64 with HZ=3D250, 64 networking channels: - Average teardown time: 5.5s -> 1.9s (65% reduction) Co-developed-by: liyongkang Signed-off-by: liyongkang Signed-off-by: Li RongQing --- Diff with v1: fix doc warning and add detailed example drivers/net/ethernet/mellanox/mlx5/core/eq.c | 2 +- drivers/net/ethernet/mellanox/mlx5/core/events.c | 2 +- drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c | 2 +- include/linux/notifier.h | 2 ++ kernel/notifier.c | 24 +++++++++++++++++++= ++++ 5 files changed, 29 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eq.c b/drivers/net/eth= ernet/mellanox/mlx5/core/eq.c index 22a6371..03ae6ed 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eq.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eq.c @@ -1244,6 +1244,6 @@ int mlx5_eq_notifier_unregister(struct mlx5_core_dev = *dev, struct mlx5_nb *nb) { struct mlx5_eq_table *eqt =3D dev->priv.eq_table; =20 - return atomic_notifier_chain_unregister(&eqt->nh[nb->event_type], &nb->nb= ); + return atomic_notifier_chain_unregister_expedited(&eqt->nh[nb->event_type= ], &nb->nb); } EXPORT_SYMBOL(mlx5_eq_notifier_unregister); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/events.c b/drivers/net= /ethernet/mellanox/mlx5/core/events.c index 4d7f35b..753cb15 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/events.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/events.c @@ -436,7 +436,7 @@ int mlx5_notifier_unregister(struct mlx5_core_dev *dev,= struct notifier_block *n { struct mlx5_events *events =3D dev->priv.events; =20 - return atomic_notifier_chain_unregister(&events->fw_nh, nb); + return atomic_notifier_chain_unregister_expedited(&events->fw_nh, nb); } EXPORT_SYMBOL(mlx5_notifier_unregister); =20 diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c b/drivers/ne= t/ethernet/mellanox/mlx5/core/pci_irq.c index e051b9a..826685d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c @@ -356,7 +356,7 @@ int mlx5_irq_detach_nb(struct mlx5_irq *irq, struct not= ifier_block *nb) { int err =3D 0; =20 - err =3D atomic_notifier_chain_unregister(&irq->nh, nb); + err =3D atomic_notifier_chain_unregister_expedited(&irq->nh, nb); mlx5_irq_put(irq); return err; } diff --git a/include/linux/notifier.h b/include/linux/notifier.h index 01b6c9d..156d958 100644 --- a/include/linux/notifier.h +++ b/include/linux/notifier.h @@ -159,6 +159,8 @@ extern int blocking_notifier_chain_register_unique_prio( =20 extern int atomic_notifier_chain_unregister(struct atomic_notifier_head *n= h, struct notifier_block *nb); +extern int atomic_notifier_chain_unregister_expedited(struct atomic_notifi= er_head *nh, + struct notifier_block *nb); extern int blocking_notifier_chain_unregister(struct blocking_notifier_hea= d *nh, struct notifier_block *nb); extern int raw_notifier_chain_unregister(struct raw_notifier_head *nh, diff --git a/kernel/notifier.c b/kernel/notifier.c index 2f9fe7c..9b35822 100644 --- a/kernel/notifier.c +++ b/kernel/notifier.c @@ -198,6 +198,30 @@ int atomic_notifier_chain_unregister(struct atomic_not= ifier_head *nh, EXPORT_SYMBOL_GPL(atomic_notifier_chain_unregister); =20 /** + * atomic_notifier_chain_unregister_expedited - Remove notifier from an at= omic notifier chain + * @nh: Pointer to head of the atomic notifier chain + * @n: Entry to remove from notifier chain + * + * Removes a notifier from an atomic notifier chain and forcefully + * accelerates the RCU grace period. + * + * Return: 0 on success, or -ENOENT on failure. + */ +int atomic_notifier_chain_unregister_expedited(struct atomic_notifier_head= *nh, + struct notifier_block *n) +{ + unsigned long flags; + int ret; + + spin_lock_irqsave(&nh->lock, flags); + ret =3D notifier_chain_unregister(&nh->head, n); + spin_unlock_irqrestore(&nh->lock, flags); + synchronize_rcu_expedited(); + return ret; +} +EXPORT_SYMBOL_GPL(atomic_notifier_chain_unregister_expedited); + +/** * atomic_notifier_call_chain - Call functions in an atomic notifier chain * @nh: Pointer to head of the atomic notifier chain * @val: Value passed unmodified to notifier function --=20 2.9.4