mirror of
https://github.com/torvalds/linux.git
synced 2026-11-06 21:58:01 +01:00
ACPI: extlog: Defer CXL protocol error handling to avoid lock inversion
extlog_print() calls cxl_cper_handle_prot_err() synchronously while the MCE notifier chain rwsem is held, and that path takes the PCI device_lock via guard(device)(). The probe path takes the two in the opposite order, holding device_lock while mce_register_decode_chain() takes the rwsem, so they can deadlock AB-BA. ghes.c already avoids this by posting protocol errors to a kfifo and handling them from a workqueue via cxl_cper_post_prot_err(). Export that function and call it instead. Declare it with the other CONFIG_ACPI_APEI_GHES exports rather than at the end of the header. No #else stub: ACPI_EXTLOG selects ACPI_APEI_GHES, so the only caller cannot exist without it. Reported-by: sashiko-bot@kernel.org Closes: https://lore.kernel.org/linux-cxl/20260709165457.8BA181F000E9@smtp.kernel.org/ Reviewed-by: Alison Schofield <alison.schofield@intel.com> Reviewed-by: Shuai Xue <xueshuai@linux.alibaba.com> Reviewed-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com> Reviewed-by: Hanjun Guo <guohanjun@huawei.com> Signed-off-by: Dave Jiang <dave.jiang@intel.com> Link: https://patch.msgid.link/20260904172337.1409775-5-dave.jiang@intel.com Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
parent
e1fd582a81
commit
179ef6d7f9
|
|
@ -163,23 +163,6 @@ static void extlog_print_pcie(struct cper_sec_pcie *pcie_err,
|
|||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
extlog_cxl_cper_handle_prot_err(struct cxl_cper_sec_prot_err *prot_err,
|
||||
int severity)
|
||||
{
|
||||
#ifdef ACPI_APEI_PCIEAER
|
||||
struct cxl_cper_prot_err_work_data wd;
|
||||
|
||||
if (cxl_cper_sec_prot_err_valid(prot_err))
|
||||
return;
|
||||
|
||||
if (cxl_cper_setup_prot_err_work_data(&wd, prot_err, severity))
|
||||
return;
|
||||
|
||||
cxl_cper_handle_prot_err(&wd);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int extlog_print(struct notifier_block *nb, unsigned long val,
|
||||
void *data)
|
||||
{
|
||||
|
|
@ -244,8 +227,8 @@ static int extlog_print(struct notifier_block *nb, unsigned long val,
|
|||
struct cxl_cper_sec_prot_err *prot_err =
|
||||
acpi_hest_get_payload(gdata);
|
||||
|
||||
extlog_cxl_cper_handle_prot_err(prot_err,
|
||||
gdata->error_severity);
|
||||
cxl_cper_post_prot_err(prot_err,
|
||||
gdata->error_severity);
|
||||
} else if (guid_equal(sec_type, &CPER_SEC_PCIE)) {
|
||||
struct cper_sec_pcie *pcie_err = acpi_hest_get_payload(gdata);
|
||||
|
||||
|
|
|
|||
|
|
@ -752,8 +752,8 @@ static DEFINE_KFIFO(cxl_cper_prot_err_fifo, struct cxl_cper_prot_err_work_data,
|
|||
static DEFINE_RAW_SPINLOCK(cxl_cper_prot_err_work_lock);
|
||||
struct work_struct *cxl_cper_prot_err_work;
|
||||
|
||||
static void cxl_cper_post_prot_err(struct cxl_cper_sec_prot_err *prot_err,
|
||||
int severity)
|
||||
void cxl_cper_post_prot_err(struct cxl_cper_sec_prot_err *prot_err,
|
||||
int severity)
|
||||
{
|
||||
#ifdef CONFIG_ACPI_APEI_PCIEAER
|
||||
struct cxl_cper_prot_err_work_data wd;
|
||||
|
|
@ -777,6 +777,7 @@ static void cxl_cper_post_prot_err(struct cxl_cper_sec_prot_err *prot_err,
|
|||
schedule_work(cxl_cper_prot_err_work);
|
||||
#endif
|
||||
}
|
||||
EXPORT_SYMBOL_FOR_MODULES(cxl_cper_post_prot_err, "acpi_extlog");
|
||||
|
||||
void cxl_cper_register_prot_err_work(struct work_struct *work)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -85,6 +85,10 @@ int devm_ghes_register_vendor_record_notifier(struct device *dev,
|
|||
struct list_head *ghes_get_devices(void);
|
||||
|
||||
void ghes_estatus_pool_region_free(unsigned long addr, u32 size);
|
||||
|
||||
struct cxl_cper_sec_prot_err;
|
||||
void cxl_cper_post_prot_err(struct cxl_cper_sec_prot_err *prot_err,
|
||||
int severity);
|
||||
#else
|
||||
static inline struct list_head *ghes_get_devices(void) { return NULL; }
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user