aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/xen
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-11-22 15:54:37 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-11-22 15:54:37 -0500
commit202317a573b20d77a9abb7c16a3fd5b40cef3d9d (patch)
tree2429aae549168cea780ac759939e1818b3487696 /drivers/xen
parentd783156ea38431b20af0d4f910a6f9f9054d33b9 (diff)
ACPI / scan: Add acpi_device objects for all device nodes in the namespace
Modify the ACPI namespace scanning code to register a struct acpi_device object for every namespace node representing a device, processor and so on, even if the device represented by that namespace node is reported to be not present and not functional by _STA. There are multiple reasons to do that. First of all, it avoids quite a lot of overhead when struct acpi_device objects are deleted every time acpi_bus_trim() is run and then added again by a subsequent acpi_bus_scan() for the same scope, although the namespace objects they correspond to stay in memory all the time (which always is the case on a vast majority of systems). Second, it will allow user space to see that there are namespace nodes representing devices that are not present at the moment and may be added to the system. It will also allow user space to evaluate _SUN for those nodes to check what physical slots the "missing" devices may be put into and it will make sense to add a sysfs attribute for _STA evaluation after this change (that will be useful for thermal management on some systems). Next, it will help to consolidate the ACPI hotplug handling among subsystems by making it possible to store hotplug-related information in struct acpi_device objects in a standard common way. Finally, it will help to avoid a race condition related to the deletion of ACPI namespace nodes. Namely, namespace nodes may be deleted as a result of a table unload triggered by _EJ0 or _DCK. If a hotplug notification for one of those nodes is triggered right before the deletion and it executes a hotplug callback via acpi_hotplug_execute(), the ACPI handle passed to that callback may be stale when the callback actually runs. One way to work around that is to always pass struct acpi_device pointers to hotplug callbacks after doing a get_device() on the objects in question which eliminates the use-after-free possibility (the ACPI handles in those objects are invalidated by acpi_scan_drop_device(), so they will trigger ACPICA errors on attempts to use them). Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Diffstat (limited to 'drivers/xen')
-rw-r--r--drivers/xen/xen-acpi-cpuhotplug.c8
-rw-r--r--drivers/xen/xen-acpi-memhotplug.c7
2 files changed, 9 insertions, 6 deletions
diff --git a/drivers/xen/xen-acpi-cpuhotplug.c b/drivers/xen/xen-acpi-cpuhotplug.c
index 8dae6c13063a..73496c3d18ae 100644
--- a/drivers/xen/xen-acpi-cpuhotplug.c
+++ b/drivers/xen/xen-acpi-cpuhotplug.c
@@ -269,7 +269,8 @@ static void acpi_processor_hotplug_notify(acpi_handle handle,
269 if (!is_processor_present(handle)) 269 if (!is_processor_present(handle))
270 break; 270 break;
271 271
272 if (!acpi_bus_get_device(handle, &device)) 272 acpi_bus_get_device(handle, &device);
273 if (acpi_device_enumerated(device))
273 break; 274 break;
274 275
275 result = acpi_bus_scan(handle); 276 result = acpi_bus_scan(handle);
@@ -277,8 +278,9 @@ static void acpi_processor_hotplug_notify(acpi_handle handle,
277 pr_err(PREFIX "Unable to add the device\n"); 278 pr_err(PREFIX "Unable to add the device\n");
278 break; 279 break;
279 } 280 }
280 result = acpi_bus_get_device(handle, &device); 281 device = NULL;
281 if (result) { 282 acpi_bus_get_device(handle, &device);
283 if (!acpi_device_enumerated(device)) {
282 pr_err(PREFIX "Missing device object\n"); 284 pr_err(PREFIX "Missing device object\n");
283 break; 285 break;
284 } 286 }
diff --git a/drivers/xen/xen-acpi-memhotplug.c b/drivers/xen/xen-acpi-memhotplug.c
index 9083f1e474f8..9b056f06691f 100644
--- a/drivers/xen/xen-acpi-memhotplug.c
+++ b/drivers/xen/xen-acpi-memhotplug.c
@@ -169,7 +169,7 @@ static int acpi_memory_get_device(acpi_handle handle,
169 acpi_scan_lock_acquire(); 169 acpi_scan_lock_acquire();
170 170
171 acpi_bus_get_device(handle, &device); 171 acpi_bus_get_device(handle, &device);
172 if (device) 172 if (acpi_device_enumerated(device))
173 goto end; 173 goto end;
174 174
175 /* 175 /*
@@ -182,8 +182,9 @@ static int acpi_memory_get_device(acpi_handle handle,
182 result = -EINVAL; 182 result = -EINVAL;
183 goto out; 183 goto out;
184 } 184 }
185 result = acpi_bus_get_device(handle, &device); 185 device = NULL;
186 if (result) { 186 acpi_bus_get_device(handle, &device);
187 if (!acpi_device_enumerated(device)) {
187 pr_warn(PREFIX "Missing device object\n"); 188 pr_warn(PREFIX "Missing device object\n");
188 result = -EINVAL; 189 result = -EINVAL;
189 goto out; 190 goto out;