aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLorenzo Pieralisi <lorenzo.pieralisi@arm.com>2016-08-16 11:59:53 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2016-09-02 16:22:21 -0400
commit5331d9cab32ef640b4cd38a43b0858874fbb7168 (patch)
tree0b97fceaed00589ec8b5a23c5df35dfa31e1cdd6
parent3feab13c919f99b0a17d0ca22ae00cf90f5d3fd1 (diff)
ACPI / drivers: replace acpi_probe_lock spinlock with mutex
Commit e647b532275b ("ACPI: Add early device probing infrastructure") introduced code that allows inserting driver specific struct acpi_probe_entry probe entries into ACPI linker sections (one per-subsystem, eg irqchip, clocksource) that are then walked to retrieve the data and function hooks required to probe the respective kernel components. Probing for all entries in a section is triggered through the __acpi_probe_device_table() function, that in turn, according to the table ID a given probe entry reports parses the table with the function retrieved from the respective section structures (ie struct acpi_probe_entry). Owing to the current ACPI table parsing implementation, the __acpi_probe_device_table() function has to share global variables with the acpi_match_madt() function, so in order to guarantee mutual exclusion locking is required between the two functions. Current kernel code implements the locking through the acpi_probe_lock spinlock; this has the side effect of requiring all code called within the lock (ie struct acpi_probe_entry.probe_{table/subtbl} hooks) not to sleep. However, kernel subsystems that make use of the early probing infrastructure are relying on kernel APIs that may sleep (eg irq_domain_alloc_fwnode(), among others) in the function calls pointed at by struct acpi_probe_entry.{probe_table/subtbl} entries (eg gic_v2_acpi_init()), which is a bug. Since __acpi_probe_device_table() is called from context that is allowed to sleep the acpi_probe_lock spinlock can be replaced with a mutex; this fixes the issue whilst still guaranteeing mutual exclusion. Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Fixes: e647b532275b (ACPI: Add early device probing infrastructure) Cc: 4.4+ <stable@vger.kernel.org> # 4.4+ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/acpi/scan.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index ad9fc84a8601..e878fc799af7 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -2054,7 +2054,7 @@ int __init acpi_scan_init(void)
2054 2054
2055static struct acpi_probe_entry *ape; 2055static struct acpi_probe_entry *ape;
2056static int acpi_probe_count; 2056static int acpi_probe_count;
2057static DEFINE_SPINLOCK(acpi_probe_lock); 2057static DEFINE_MUTEX(acpi_probe_mutex);
2058 2058
2059static int __init acpi_match_madt(struct acpi_subtable_header *header, 2059static int __init acpi_match_madt(struct acpi_subtable_header *header,
2060 const unsigned long end) 2060 const unsigned long end)
@@ -2073,7 +2073,7 @@ int __init __acpi_probe_device_table(struct acpi_probe_entry *ap_head, int nr)
2073 if (acpi_disabled) 2073 if (acpi_disabled)
2074 return 0; 2074 return 0;
2075 2075
2076 spin_lock(&acpi_probe_lock); 2076 mutex_lock(&acpi_probe_mutex);
2077 for (ape = ap_head; nr; ape++, nr--) { 2077 for (ape = ap_head; nr; ape++, nr--) {
2078 if (ACPI_COMPARE_NAME(ACPI_SIG_MADT, ape->id)) { 2078 if (ACPI_COMPARE_NAME(ACPI_SIG_MADT, ape->id)) {
2079 acpi_probe_count = 0; 2079 acpi_probe_count = 0;
@@ -2086,7 +2086,7 @@ int __init __acpi_probe_device_table(struct acpi_probe_entry *ap_head, int nr)
2086 count++; 2086 count++;
2087 } 2087 }
2088 } 2088 }
2089 spin_unlock(&acpi_probe_lock); 2089 mutex_unlock(&acpi_probe_mutex);
2090 2090
2091 return count; 2091 return count;
2092} 2092}