]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blobdiff - drivers/acpi/processor_driver.c
cpu-hotplug, memory-hotplug: try offlining the node when hotremoving a cpu
[mirror_ubuntu-hirsute-kernel.git] / drivers / acpi / processor_driver.c
index e83311bf1ebdaaaea1adbf2de1351cca907d3465..df34bd04ae62ba88e4acc6735515e41af03aff7d 100644 (file)
@@ -45,6 +45,7 @@
 #include <linux/cpuidle.h>
 #include <linux/slab.h>
 #include <linux/acpi.h>
+#include <linux/memory_hotplug.h>
 
 #include <asm/io.h>
 #include <asm/cpu.h>
@@ -81,7 +82,7 @@ MODULE_DESCRIPTION("ACPI Processor Driver");
 MODULE_LICENSE("GPL");
 
 static int acpi_processor_add(struct acpi_device *device);
-static int acpi_processor_remove(struct acpi_device *device, int type);
+static int acpi_processor_remove(struct acpi_device *device);
 static void acpi_processor_notify(struct acpi_device *device, u32 event);
 static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr);
 static int acpi_processor_handle_eject(struct acpi_processor *pr);
@@ -610,7 +611,7 @@ err_free_pr:
        return result;
 }
 
-static int acpi_processor_remove(struct acpi_device *device, int type)
+static int acpi_processor_remove(struct acpi_device *device)
 {
        struct acpi_processor *pr = NULL;
 
@@ -623,7 +624,7 @@ static int acpi_processor_remove(struct acpi_device *device, int type)
        if (pr->id >= nr_cpu_ids)
                goto free;
 
-       if (type == ACPI_BUS_REMOVAL_EJECT) {
+       if (device->removal_type == ACPI_BUS_REMOVAL_EJECT) {
                if (acpi_processor_handle_eject(pr))
                        return -EINVAL;
        }
@@ -641,6 +642,7 @@ static int acpi_processor_remove(struct acpi_device *device, int type)
 
        per_cpu(processors, pr->id) = NULL;
        per_cpu(processor_device_array, pr->id) = NULL;
+       try_offline_node(cpu_to_node(pr->id));
 
 free:
        free_cpumask_var(pr->throttling.shared_cpu_map);
@@ -677,36 +679,17 @@ static int is_processor_present(acpi_handle handle)
        return 0;
 }
 
-static
-int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device)
-{
-       acpi_handle phandle;
-       struct acpi_device *pdev;
-
-
-       if (acpi_get_parent(handle, &phandle)) {
-               return -ENODEV;
-       }
-
-       if (acpi_bus_get_device(phandle, &pdev)) {
-               return -ENODEV;
-       }
-
-       if (acpi_bus_add(device, pdev, handle, ACPI_BUS_TYPE_PROCESSOR)) {
-               return -ENODEV;
-       }
-
-       return 0;
-}
-
 static void acpi_processor_hotplug_notify(acpi_handle handle,
                                          u32 event, void *data)
 {
        struct acpi_device *device = NULL;
        struct acpi_eject_event *ej_event = NULL;
        u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */
+       acpi_status status;
        int result;
 
+       acpi_scan_lock_acquire();
+
        switch (event) {
        case ACPI_NOTIFY_BUS_CHECK:
        case ACPI_NOTIFY_DEVICE_CHECK:
@@ -721,12 +704,16 @@ static void acpi_processor_hotplug_notify(acpi_handle handle,
                if (!acpi_bus_get_device(handle, &device))
                        break;
 
-               result = acpi_processor_device_add(handle, &device);
+               result = acpi_bus_scan(handle);
                if (result) {
                        acpi_handle_err(handle, "Unable to add the device\n");
                        break;
                }
-
+               result = acpi_bus_get_device(handle, &device);
+               if (result) {
+                       acpi_handle_err(handle, "Missing device object\n");
+                       break;
+               }
                ost_code = ACPI_OST_SC_SUCCESS;
                break;
 
@@ -751,25 +738,32 @@ static void acpi_processor_hotplug_notify(acpi_handle handle,
                        break;
                }
 
-               ej_event->handle = handle;
+               get_device(&device->dev);
+               ej_event->device = device;
                ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
-               acpi_os_hotplug_execute(acpi_bus_hot_remove_device,
-                                       (void *)ej_event);
-
-               /* eject is performed asynchronously */
-               return;
+               /* The eject is carried out asynchronously. */
+               status = acpi_os_hotplug_execute(acpi_bus_hot_remove_device,
+                                                ej_event);
+               if (ACPI_FAILURE(status)) {
+                       put_device(&device->dev);
+                       kfree(ej_event);
+                       break;
+               }
+               goto out;
 
        default:
                ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                                  "Unsupported event [0x%x]\n", event));
 
                /* non-hotplug event; possibly handled by other handler */
-               return;
+               goto out;
        }
 
        /* Inform firmware that the hotplug operation has completed */
        (void) acpi_evaluate_hotplug_ost(handle, event, ost_code, NULL);
-       return;
+
+ out:
+       acpi_scan_lock_release();
 }
 
 static acpi_status is_processor_device(acpi_handle handle)