From b73cf7eaa6ee77f030667531245e1635c1b6fc9a Mon Sep 17 00:00:00 2001 From: Shuai Xue Date: Mon, 12 Jan 2026 11:22:39 +0800 Subject: [PATCH] ACPI: APEI: GHES: Improve ghes_notify_sea() status check Performance testing on ARMv8 systems shows significant overhead in error status handling in SEA error handling. - ghes_peek_estatus(): 8,138.3 ns (21,160 cycles). - ghes_clear_estatus(): 2,038.3 ns (5,300 cycles). Apply the same optimization used in ghes_notify_nmi() to ghes_notify_sea() by checking for active errors before processing, Tested-by: Tony Luck Reviewed-by: Tony Luck Signed-off-by: Shuai Xue Reviewed-by: Hanjun Guo Link: https://patch.msgid.link/20260112032239.30023-4-xueshuai@linux.alibaba.com Signed-off-by: Rafael J. Wysocki --- drivers/acpi/apei/ghes.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 067a58dbcc01a..a2ac282c99cb2 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -1511,6 +1511,9 @@ int ghes_notify_sea(void) static DEFINE_RAW_SPINLOCK(ghes_notify_lock_sea); int rv; + if (!ghes_has_active_errors(&ghes_sea)) + return -ENOENT; + raw_spin_lock(&ghes_notify_lock_sea); rv = ghes_in_nmi_spool_from_list(&ghes_sea, FIX_APEI_GHES_SEA); raw_spin_unlock(&ghes_notify_lock_sea); @@ -1518,11 +1521,19 @@ int ghes_notify_sea(void) return rv; } -static void ghes_sea_add(struct ghes *ghes) +static int ghes_sea_add(struct ghes *ghes) { + int rc; + + rc = ghes_map_error_status(ghes); + if (rc) + return rc; + mutex_lock(&ghes_list_mutex); list_add_rcu(&ghes->list, &ghes_sea); mutex_unlock(&ghes_list_mutex); + + return 0; } static void ghes_sea_remove(struct ghes *ghes) @@ -1530,10 +1541,11 @@ static void ghes_sea_remove(struct ghes *ghes) mutex_lock(&ghes_list_mutex); list_del_rcu(&ghes->list); mutex_unlock(&ghes_list_mutex); + ghes_unmap_error_status(ghes); synchronize_rcu(); } #else /* CONFIG_ACPI_APEI_SEA */ -static inline void ghes_sea_add(struct ghes *ghes) { } +static inline int ghes_sea_add(struct ghes *ghes) { return -EINVAL; } static inline void ghes_sea_remove(struct ghes *ghes) { } #endif /* CONFIG_ACPI_APEI_SEA */ @@ -1765,7 +1777,9 @@ static int ghes_probe(struct platform_device *ghes_dev) break; case ACPI_HEST_NOTIFY_SEA: - ghes_sea_add(ghes); + rc = ghes_sea_add(ghes); + if (rc) + goto err; break; case ACPI_HEST_NOTIFY_NMI: rc = ghes_nmi_add(ghes); -- 2.47.3