* [ACPIHP PATCH part4 1/9] ACPI/processor: remove dead code from processor_driver.c
2012-11-04 15:23 [ACPIHP PATCH part4 0/9] enhance ACPI processor driver to support new hotplug framework Jiang Liu
@ 2012-11-04 15:23 ` Jiang Liu
2012-11-04 15:23 ` [ACPIHP PATCH part4 2/9] ACPIHP/processor: reorganize ACPI processor driver for new hotplug framework Jiang Liu
` (7 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Jiang Liu @ 2012-11-04 15:23 UTC (permalink / raw)
To: Rafael J . Wysocki, Yinghai Lu, Tony Luck, Yasuaki Ishimatsu,
Wen Congyang, Tang Chen, Taku Izumi, Bjorn Helgaas
Cc: Jiang Liu, Kenji Kaneshige, Huang Ying, Bob Moore, Len Brown,
Srivatsa S . Bhat, Yijing Wang, Hanjun Guo, Jiang Liu,
linux-kernel, linux-acpi, linux-pci, linux-mm
There is some dead code in processor_driver.c, so clean it up.
Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
---
drivers/acpi/processor_driver.c | 9 ---------
1 file changed, 9 deletions(-)
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
index e78c2a5..aa9c43a 100644
--- a/drivers/acpi/processor_driver.c
+++ b/drivers/acpi/processor_driver.c
@@ -61,17 +61,11 @@
#define ACPI_PROCESSOR_CLASS "processor"
#define ACPI_PROCESSOR_DEVICE_NAME "Processor"
-#define ACPI_PROCESSOR_FILE_INFO "info"
-#define ACPI_PROCESSOR_FILE_THROTTLING "throttling"
-#define ACPI_PROCESSOR_FILE_LIMIT "limit"
#define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80
#define ACPI_PROCESSOR_NOTIFY_POWER 0x81
#define ACPI_PROCESSOR_NOTIFY_THROTTLING 0x82
#define ACPI_PROCESSOR_DEVICE_HID "ACPI0007"
-#define ACPI_PROCESSOR_LIMIT_USER 0
-#define ACPI_PROCESSOR_LIMIT_THERMAL 1
-
#define _COMPONENT ACPI_PROCESSOR_COMPONENT
ACPI_MODULE_NAME("processor_driver");
@@ -261,9 +255,6 @@ static int acpi_processor_get_info(struct acpi_device *device)
if (!pr)
return -EINVAL;
- if (num_online_cpus() > 1)
- errata.smp = TRUE;
-
acpi_processor_errata(pr);
/*
--
1.7.9.5
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [ACPIHP PATCH part4 2/9] ACPIHP/processor: reorganize ACPI processor driver for new hotplug framework
2012-11-04 15:23 [ACPIHP PATCH part4 0/9] enhance ACPI processor driver to support new hotplug framework Jiang Liu
2012-11-04 15:23 ` [ACPIHP PATCH part4 1/9] ACPI/processor: remove dead code from processor_driver.c Jiang Liu
@ 2012-11-04 15:23 ` Jiang Liu
2012-11-04 15:23 ` [ACPIHP PATCH part4 3/9] ACPIHP/processor: protect accesses to device->driver_data Jiang Liu
` (6 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Jiang Liu @ 2012-11-04 15:23 UTC (permalink / raw)
To: Rafael J . Wysocki, Yinghai Lu, Tony Luck, Yasuaki Ishimatsu,
Wen Congyang, Tang Chen, Taku Izumi, Bjorn Helgaas
Cc: Jiang Liu, Kenji Kaneshige, Huang Ying, Bob Moore, Len Brown,
Srivatsa S . Bhat, Yijing Wang, Hanjun Guo, Jiang Liu,
linux-kernel, linux-acpi, linux-pci, linux-mm
This patch reorganizes code in processor_driver.c to parepare for
integration with the new hotplug framework. Common code could be
shared among acpi_processor_add(), acpi_processor_remove() and hotplug
has been reorganized as:
acpi_processor_start()
acpi_processor_stop()
acpi_processor_link()
acpi_processor_unlink()
Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
---
drivers/acpi/processor_driver.c | 179 +++++++++++++++++++++++----------------
include/acpi/processor.h | 2 +
2 files changed, 108 insertions(+), 73 deletions(-)
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
index aa9c43a..28add34 100644
--- a/drivers/acpi/processor_driver.c
+++ b/drivers/acpi/processor_driver.c
@@ -105,6 +105,8 @@ static struct acpi_driver acpi_processor_driver = {
#define INSTALL_NOTIFY_HANDLER 1
#define UNINSTALL_NOTIFY_HANDLER 2
+static DEFINE_PER_CPU(void *, processor_device_array);
+
DEFINE_PER_CPU(struct acpi_processor *, processors);
EXPORT_PER_CPU_SYMBOL(processors);
@@ -327,11 +329,11 @@ static int acpi_processor_get_info(struct acpi_device *device)
* \_SB.SCK1.CPU0
* Rename the processor device bus id. And the new bus id will be
* generated as the following format:
- * CPU+CPU ID.
+ * CPU+ACPI ID.
*/
- sprintf(acpi_device_bid(device), "CPU%X", pr->id);
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d:%d]\n", pr->id,
- pr->acpi_id));
+ sprintf(acpi_device_bid(device), "CPU%X", pr->acpi_id);
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d:%d]\n", pr->acpi_id,
+ pr->id));
if (!object.processor.pblk_address)
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No PBLK (NULL address)\n"));
@@ -355,19 +357,67 @@ static int acpi_processor_get_info(struct acpi_device *device)
request_region(pr->throttling.address, 6, "ACPI CPU throttle");
}
+ return 0;
+}
+
+static int acpi_processor_link(struct acpi_device *device,
+ struct acpi_processor *pr)
+{
+ struct device *dev;
+ acpi_status status;
+ unsigned long long value;
+
+ if (pr->flags.device_linked)
+ return 0;
+
/*
* If ACPI describes a slot number for this CPU, we can use it
* ensure we get the right value in the "physical id" field
* of /proc/cpuinfo
*/
- status = acpi_evaluate_object(pr->handle, "_SUN", NULL, &buffer);
+ status = acpi_evaluate_integer(pr->handle, "_SUN", NULL, &value);
if (ACPI_SUCCESS(status))
- arch_fix_phys_package_id(pr->id, object.integer.value);
+ arch_fix_phys_package_id(pr->id, value);
+
+ /*
+ * Buggy BIOS check
+ * ACPI id of processors can be reported wrongly by the BIOS.
+ * Don't trust it blindly
+ */
+ if (per_cpu(processor_device_array, pr->id) != NULL &&
+ per_cpu(processor_device_array, pr->id) != device) {
+ dev_warn(&device->dev,
+ "BIOS reported wrong ACPI id for the processor\n");
+ return -ENODEV;
+ }
+ per_cpu(processor_device_array, pr->id) = device;
+ per_cpu(processors, pr->id) = pr;
+
+ dev = get_cpu_device(pr->id);
+ if (sysfs_create_link(&device->dev.kobj, &dev->kobj, "sysdev")) {
+ /*
+ * processor_device_array is not cleared to allow checks
+ * for buggy BIOS
+ */
+ per_cpu(processors, pr->id) = NULL;
+ return -EFAULT;
+ }
+
+ pr->flags.device_linked = 1;
return 0;
}
-static DEFINE_PER_CPU(void *, processor_device_array);
+static void acpi_processor_unlink(struct acpi_device *device,
+ struct acpi_processor *pr)
+{
+ if (pr->flags.device_linked) {
+ sysfs_remove_link(&device->dev.kobj, "sysdev");
+ per_cpu(processor_device_array, pr->id) = NULL;
+ per_cpu(processors, pr->id) = NULL;
+ pr->flags.device_linked = 0;
+ }
+}
static void acpi_processor_notify(struct acpi_device *device, u32 event)
{
@@ -422,11 +472,11 @@ static int acpi_cpu_soft_notify(struct notifier_block *nfb,
if (pr->flags.need_hotplug_init) {
printk(KERN_INFO "Will online and init hotplugged "
"CPU: %d\n", pr->id);
- WARN(acpi_processor_start(pr), "Failed to start CPU:"
- " %d\n", pr->id);
+ WARN(acpi_processor_start(pr),
+ "Failed to start CPU: %d\n", pr->id);
pr->flags.need_hotplug_init = 0;
/* Normal CPU soft online event */
- } else {
+ } else if (pr->flags.device_started) {
acpi_processor_ppc_has_changed(pr, 0);
acpi_processor_hotplug(pr);
acpi_processor_reevaluate_tstate(pr, action);
@@ -458,6 +508,9 @@ static __ref int acpi_processor_start(struct acpi_processor *pr)
struct acpi_device *device = per_cpu(processor_device_array, pr->id);
int result = 0;
+ if (pr->flags.device_started)
+ return 0;
+
#ifdef CONFIG_CPU_FREQ
acpi_processor_ppc_has_changed(pr, 0);
acpi_processor_load_module(pr);
@@ -493,6 +546,8 @@ static __ref int acpi_processor_start(struct acpi_processor *pr)
goto err_remove_sysfs_thermal;
}
+ pr->flags.device_started = 1;
+
return 0;
err_remove_sysfs_thermal:
@@ -505,6 +560,21 @@ err_power_exit:
return result;
}
+static void acpi_processor_stop(struct acpi_device *device,
+ struct acpi_processor *pr)
+{
+ if (pr->flags.device_started) {
+ acpi_processor_power_exit(pr);
+ if (pr->cdev) {
+ sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
+ sysfs_remove_link(&pr->cdev->device.kobj, "device");
+ thermal_cooling_device_unregister(pr->cdev);
+ pr->cdev = NULL;
+ }
+ pr->flags.device_started = 0;
+ }
+}
+
/*
* Do not put anything in here which needs the core to be online.
* For example MSR access or setting up things which check for cpuinfo_x86
@@ -513,9 +583,8 @@ err_power_exit:
*/
static int __cpuinit acpi_processor_add(struct acpi_device *device)
{
- struct acpi_processor *pr = NULL;
- int result = 0;
- struct device *dev;
+ struct acpi_processor *pr;
+ int result;
pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL);
if (!pr)
@@ -532,60 +601,36 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device)
device->driver_data = pr;
result = acpi_processor_get_info(device);
- if (result) {
- /* Processor is physically not present */
- return 0;
- }
-
-#ifdef CONFIG_SMP
- if (pr->id >= setup_max_cpus && pr->id != 0)
- return 0;
-#endif
-
- BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
-
- /*
- * Buggy BIOS check
- * ACPI id of processors can be reported wrongly by the BIOS.
- * Don't trust it blindly
- */
- if (per_cpu(processor_device_array, pr->id) != NULL &&
- per_cpu(processor_device_array, pr->id) != device) {
- printk(KERN_WARNING "BIOS reported wrong ACPI id "
- "for the processor\n");
- result = -ENODEV;
+ if (result)
goto err_free_cpumask;
- }
- per_cpu(processor_device_array, pr->id) = device;
-
- per_cpu(processors, pr->id) = pr;
-
- dev = get_cpu_device(pr->id);
- if (sysfs_create_link(&device->dev.kobj, &dev->kobj, "sysdev")) {
- result = -EFAULT;
- goto err_clear_processor;
- }
/*
- * Do not start hotplugged CPUs now, but when they
- * are onlined the first time
+ * Delay linking with logical CPU device if:
+ * 1) no CPUID assigned yet
+ * 2) processor won't be boot if CPUID is bigger than setup_max_cpus
+ * They will be handled by CPU hotplug logical later.
*/
- if (pr->flags.need_hotplug_init)
+ if (pr->id == -1)
return 0;
+ if (IS_BUILTIN(CONFIG_SMP) && pr->id >= setup_max_cpus && pr->id != 0)
+ return 0;
+ BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
- result = acpi_processor_start(pr);
+ result = acpi_processor_link(device, pr);
if (result)
- goto err_remove_sysfs;
+ goto err_unlock;
+ if (cpu_online(pr->id)) {
+ result = acpi_processor_start(pr);
+ if (result)
+ goto err_unlink;
+ }
return 0;
-err_remove_sysfs:
- sysfs_remove_link(&device->dev.kobj, "sysdev");
-err_clear_processor:
- /*
- * processor_device_array is not cleared to allow checks for buggy BIOS
- */
- per_cpu(processors, pr->id) = NULL;
+err_unlink:
+ acpi_processor_unlink(device, pr);
+err_unlock:
+ put_online_cpus();
err_free_cpumask:
free_cpumask_var(pr->throttling.shared_cpu_map);
err_free_pr:
@@ -595,14 +640,12 @@ err_free_pr:
static int acpi_processor_remove(struct acpi_device *device, int type)
{
- struct acpi_processor *pr = NULL;
-
+ struct acpi_processor *pr;
if (!device || !acpi_driver_data(device))
return -EINVAL;
pr = acpi_driver_data(device);
-
if (pr->id >= nr_cpu_ids)
goto free;
@@ -611,21 +654,11 @@ static int acpi_processor_remove(struct acpi_device *device, int type)
return -EINVAL;
}
- acpi_processor_power_exit(pr);
-
- sysfs_remove_link(&device->dev.kobj, "sysdev");
-
- if (pr->cdev) {
- sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
- sysfs_remove_link(&pr->cdev->device.kobj, "device");
- thermal_cooling_device_unregister(pr->cdev);
- pr->cdev = NULL;
- }
-
- per_cpu(processors, pr->id) = NULL;
- per_cpu(processor_device_array, pr->id) = NULL;
+ acpi_processor_stop(device, pr);
+ acpi_processor_unlink(device, pr);
free:
+ device->driver_data = NULL;
free_cpumask_var(pr->throttling.shared_cpu_map);
kfree(pr);
diff --git a/include/acpi/processor.h b/include/acpi/processor.h
index 555d033..9e1c980 100644
--- a/include/acpi/processor.h
+++ b/include/acpi/processor.h
@@ -190,6 +190,8 @@ struct acpi_processor_flags {
u8 power_setup_done:1;
u8 bm_rld_set:1;
u8 need_hotplug_init:1;
+ u8 device_linked:1;
+ u8 device_started:1;
};
struct acpi_processor {
--
1.7.9.5
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [ACPIHP PATCH part4 3/9] ACPIHP/processor: protect accesses to device->driver_data
2012-11-04 15:23 [ACPIHP PATCH part4 0/9] enhance ACPI processor driver to support new hotplug framework Jiang Liu
2012-11-04 15:23 ` [ACPIHP PATCH part4 1/9] ACPI/processor: remove dead code from processor_driver.c Jiang Liu
2012-11-04 15:23 ` [ACPIHP PATCH part4 2/9] ACPIHP/processor: reorganize ACPI processor driver for new hotplug framework Jiang Liu
@ 2012-11-04 15:23 ` Jiang Liu
2012-11-04 15:23 ` [ACPIHP PATCH part4 4/9] ACPIHP/processor: enhance processor driver to support new hotplug framework Jiang Liu
` (5 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Jiang Liu @ 2012-11-04 15:23 UTC (permalink / raw)
To: Rafael J . Wysocki, Yinghai Lu, Tony Luck, Yasuaki Ishimatsu,
Wen Congyang, Tang Chen, Taku Izumi, Bjorn Helgaas
Cc: Jiang Liu, Kenji Kaneshige, Huang Ying, Bob Moore, Len Brown,
Srivatsa S . Bhat, Yijing Wang, Hanjun Guo, Jiang Liu,
linux-kernel, linux-acpi, linux-pci, linux-mm
CPU hotplug notification handler acpi_cpu_soft_notify() and driver
unbind method acpi_processor_remove() may be concurrently called.
acpi_cpu_soft_notify() will access device->driver_data, but that
data structure may be destroyed by acpi_processor_remove().
On the other hand, acpi_cpu_soft_notify() is always called under
protection of get_online_cpus(), so use get_online_cpus() to serialize
all accesses and modifications to device->driver_data.
Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
---
drivers/acpi/processor_driver.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
index 28add34..7d6d794 100644
--- a/drivers/acpi/processor_driver.c
+++ b/drivers/acpi/processor_driver.c
@@ -616,6 +616,8 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device)
return 0;
BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
+ /* block CPU online/offline operations */
+ get_online_cpus();
result = acpi_processor_link(device, pr);
if (result)
goto err_unlock;
@@ -624,6 +626,7 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device)
if (result)
goto err_unlink;
}
+ put_online_cpus();
return 0;
@@ -654,8 +657,10 @@ static int acpi_processor_remove(struct acpi_device *device, int type)
return -EINVAL;
}
+ get_online_cpus();
acpi_processor_stop(device, pr);
acpi_processor_unlink(device, pr);
+ put_online_cpus();
free:
device->driver_data = NULL;
--
1.7.9.5
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [ACPIHP PATCH part4 4/9] ACPIHP/processor: enhance processor driver to support new hotplug framework
2012-11-04 15:23 [ACPIHP PATCH part4 0/9] enhance ACPI processor driver to support new hotplug framework Jiang Liu
` (2 preceding siblings ...)
2012-11-04 15:23 ` [ACPIHP PATCH part4 3/9] ACPIHP/processor: protect accesses to device->driver_data Jiang Liu
@ 2012-11-04 15:23 ` Jiang Liu
2012-11-04 15:23 ` [ACPIHP PATCH part4 5/9] CPU: introduce busy flag to temporarily disable CPU online sysfs interface Jiang Liu
` (4 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Jiang Liu @ 2012-11-04 15:23 UTC (permalink / raw)
To: Rafael J . Wysocki, Yinghai Lu, Tony Luck, Yasuaki Ishimatsu,
Wen Congyang, Tang Chen, Taku Izumi, Bjorn Helgaas
Cc: Jiang Liu, Kenji Kaneshige, Huang Ying, Bob Moore, Len Brown,
Srivatsa S . Bhat, Yijing Wang, Hanjun Guo, Jiang Liu,
linux-kernel, linux-acpi, linux-pci, linux-mm
Refine ACPI processor driver to support new ACPI system device hotplug
framework with following changes:
1) Remove code to handle ACPI hotplug events from ACPI processor
driver, now hotplug events will be handled by the framework.
2) Provides callbacks for the framework to add CPU into or remove CPU
from running system.
Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Signed-off-by: Hanjun Guo <guohanjun@huawei.com>
---
drivers/acpi/Kconfig | 11 +-
drivers/acpi/processor_driver.c | 336 +++++++++++++--------------------------
2 files changed, 114 insertions(+), 233 deletions(-)
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 05f0a22..a8f8f75 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -206,12 +206,6 @@ config ACPI_IPMI
To compile this driver as a module, choose M here:
the module will be called as acpi_ipmi.
-config ACPI_HOTPLUG_CPU
- bool
- depends on EXPERIMENTAL && ACPI_PROCESSOR && HOTPLUG_CPU
- select ACPI_CONTAINER
- default y
-
config ACPI_PROCESSOR_AGGREGATOR
tristate "Processor Aggregator"
depends on ACPI_PROCESSOR
@@ -378,6 +372,11 @@ config ACPI_HOTPLUG_DRIVER
To compile this driver as a module, choose M here:
the module will be called acpihp_drv.
+config ACPI_HOTPLUG_CPU
+ bool
+ depends on ACPI_HOTPLUG && ACPI_PROCESSOR && HOTPLUG_CPU
+ default y
+
config ACPI_CONTAINER
tristate "Container and Module Devices (EXPERIMENTAL)"
depends on ACPI_HOTPLUG
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
index 7d6d794..b8c3684 100644
--- a/drivers/acpi/processor_driver.c
+++ b/drivers/acpi/processor_driver.c
@@ -56,6 +56,7 @@
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
#include <acpi/processor.h>
+#include <acpi/acpi_hotplug.h>
#define PREFIX "ACPI: "
@@ -76,9 +77,10 @@ MODULE_LICENSE("GPL");
static int acpi_processor_add(struct acpi_device *device);
static int acpi_processor_remove(struct acpi_device *device, int type);
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);
static int acpi_processor_start(struct acpi_processor *pr);
+#ifdef CONFIG_ACPI_HOTPLUG_CPU
+static struct acpihp_dev_ops acpi_processor_hp_ops;
+#endif
static const struct acpi_device_id processor_device_ids[] = {
{ACPI_PROCESSOR_OBJECT_HID, 0},
@@ -98,13 +100,13 @@ static struct acpi_driver acpi_processor_driver = {
.add = acpi_processor_add,
.remove = acpi_processor_remove,
.notify = acpi_processor_notify,
- },
+#ifdef CONFIG_ACPI_HOTPLUG_CPU
+ .hp_ops = &acpi_processor_hp_ops,
+#endif
+ },
.drv.pm = &acpi_processor_pm,
};
-#define INSTALL_NOTIFY_HANDLER 1
-#define UNINSTALL_NOTIFY_HANDLER 2
-
static DEFINE_PER_CPU(void *, processor_device_array);
DEFINE_PER_CPU(struct acpi_processor *, processors);
@@ -314,15 +316,6 @@ static int acpi_processor_get_info(struct acpi_device *device)
pr->id = cpu_index;
/*
- * Extra Processor objects may be enumerated on MP systems with
- * less than the max # of CPUs. They should be ignored _iff
- * they are physically not present.
- */
- if (pr->id == -1) {
- if (ACPI_FAILURE(acpi_processor_hotadd_init(pr)))
- return -ENODEV;
- }
- /*
* On some boxes several processors use the same processor bus id.
* But they are located in different scope. For example:
* \_SB.SCK0.CPU0
@@ -649,20 +642,12 @@ static int acpi_processor_remove(struct acpi_device *device, int type)
return -EINVAL;
pr = acpi_driver_data(device);
- if (pr->id >= nr_cpu_ids)
- goto free;
-
- if (type == ACPI_BUS_REMOVAL_EJECT) {
- if (acpi_processor_handle_eject(pr))
- return -EINVAL;
- }
get_online_cpus();
acpi_processor_stop(device, pr);
acpi_processor_unlink(device, pr);
put_online_cpus();
-free:
device->driver_data = NULL;
free_cpumask_var(pr->throttling.shared_cpu_map);
kfree(pr);
@@ -675,258 +660,155 @@ free:
* Acpi processor hotplug support *
****************************************************************************/
-static int is_processor_present(acpi_handle handle)
+static void acpi_processor_reset(struct acpi_device *device, struct acpi_processor *pr)
{
- acpi_status status;
- unsigned long long sta = 0;
-
-
- status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
-
- if (ACPI_SUCCESS(status) && (sta & ACPI_STA_DEVICE_PRESENT))
- return 1;
-
- /*
- * _STA is mandatory for a processor that supports hot plug
- */
- if (status == AE_NOT_FOUND)
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Processor does not support hot plug\n"));
- else
- ACPI_EXCEPTION((AE_INFO, status,
- "Processor Device is not present"));
- return 0;
+ get_online_cpus();
+ acpi_processor_unlink(device, pr);
+ put_online_cpus();
+ arch_unregister_cpu(pr->id);
+ acpi_unmap_lsapic(pr->id);
+ pr->id = -1;
}
-static
-int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device)
+static int acpi_processor_get_dev_info(struct acpi_device *device,
+ struct acpihp_dev_info *info)
{
- acpi_handle phandle;
- struct acpi_device *pdev;
-
-
- if (acpi_get_parent(handle, &phandle)) {
- return -ENODEV;
- }
+ struct acpi_processor *pr;
- if (acpi_bus_get_device(phandle, &pdev)) {
- return -ENODEV;
- }
+ if (!device || !acpi_driver_data(device))
+ return -EINVAL;
+ pr = acpi_driver_data(device);
- if (acpi_bus_add(device, pdev, handle, ACPI_BUS_TYPE_PROCESSOR)) {
- return -ENODEV;
- }
+ info->type = ACPIHP_DEV_TYPE_CPU;
+ if (pr->id >= 0)
+ info->status |= ACPIHP_DEV_STATUS_STARTED;
return 0;
}
-static void acpi_processor_hotplug_notify(acpi_handle handle,
- u32 event, void *data)
+static int acpi_processor_pre_configure(struct acpi_device *device,
+ struct acpihp_cancel_context *ctx)
{
- struct acpi_processor *pr;
- struct acpi_device *device = NULL;
- u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */
int result;
+ struct acpi_processor *pr;
- switch (event) {
- case ACPI_NOTIFY_BUS_CHECK:
- case ACPI_NOTIFY_DEVICE_CHECK:
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Processor driver received %s event\n",
- (event == ACPI_NOTIFY_BUS_CHECK) ?
- "ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK"));
-
- if (!is_processor_present(handle))
- break;
-
- if (!acpi_bus_get_device(handle, &device))
- break;
+ if (!device || !acpi_driver_data(device))
+ return -EINVAL;
+ pr = acpi_driver_data(device);
- result = acpi_processor_device_add(handle, &device);
+ /* Generate CPUID for hot-added CPUs */
+ if (pr->id == -1) {
+ result = acpi_map_lsapic(device->handle, &pr->id);
+ if (result)
+ return result;
+ BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
+ result = arch_register_cpu(pr->id);
if (result) {
- printk(KERN_ERR PREFIX "Unable to add the device\n");
- break;
+ acpi_unmap_lsapic(pr->id);
+ pr->id = -1;
+ return result;
}
- ost_code = ACPI_OST_SC_SUCCESS;
- break;
-
- case ACPI_NOTIFY_EJECT_REQUEST:
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "received ACPI_NOTIFY_EJECT_REQUEST\n"));
-
- if (acpi_bus_get_device(handle, &device)) {
- printk(KERN_ERR PREFIX
- "Device don't exist, dropping EJECT\n");
- break;
- }
- pr = acpi_driver_data(device);
- if (!pr) {
- printk(KERN_ERR PREFIX
- "Driver data is NULL, dropping EJECT\n");
- break;
- }
-
- /* REVISIT: update when eject is supported */
- ost_code = ACPI_OST_SC_EJECT_NOT_SUPPORTED;
- break;
-
- default:
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Unsupported event [0x%x]\n", event));
-
- /* non-hotplug event; possibly handled by other handler */
- return;
+ /*
+ * CPU got hot-plugged, but cpu_data is not initialized yet.
+ * Set flag to let acpi_cpu_soft_notify() initialize cpu_data
+ * by calling acpi_processor_start
+ */
+ pr->flags.need_hotplug_init = 1;
+ dev_info(&device->dev, "CPU %d got hotplugged\n", pr->id);
}
- /* Inform firmware that the hotplug operation has completed */
- (void) acpi_evaluate_hotplug_ost(handle, event, ost_code, NULL);
- return;
+ return 0;
}
-static acpi_status is_processor_device(acpi_handle handle)
+static int acpi_processor_configure(struct acpi_device *device,
+ struct acpihp_cancel_context *ctx)
{
- struct acpi_device_info *info;
- char *hid;
- acpi_status status;
-
- status = acpi_get_object_info(handle, &info);
- if (ACPI_FAILURE(status))
- return status;
-
- if (info->type == ACPI_TYPE_PROCESSOR) {
- kfree(info);
- return AE_OK; /* found a processor object */
- }
+ int result;
+ struct acpi_processor *pr;
- if (!(info->valid & ACPI_VALID_HID)) {
- kfree(info);
- return AE_ERROR;
- }
+ if (!device || !acpi_driver_data(device))
+ return -EINVAL;
+ pr = acpi_driver_data(device);
- hid = info->hardware_id.string;
- if ((hid == NULL) || strcmp(hid, ACPI_PROCESSOR_DEVICE_HID)) {
- kfree(info);
- return AE_ERROR;
- }
+ get_online_cpus();
+ result = acpi_processor_link(device, pr);
+ put_online_cpus();
- kfree(info);
- return AE_OK; /* found a processor device object */
+ return result;
}
-static acpi_status
-processor_walk_namespace_cb(acpi_handle handle,
- u32 lvl, void *context, void **rv)
+static void acpi_processor_post_configure(struct acpi_device *device,
+ enum acpihp_dev_post_cmd cmd)
{
- acpi_status status;
- int *action = context;
-
- status = is_processor_device(handle);
- if (ACPI_FAILURE(status))
- return AE_OK; /* not a processor; continue to walk */
-
- switch (*action) {
- case INSTALL_NOTIFY_HANDLER:
- acpi_install_notify_handler(handle,
- ACPI_SYSTEM_NOTIFY,
- acpi_processor_hotplug_notify,
- NULL);
- break;
- case UNINSTALL_NOTIFY_HANDLER:
- acpi_remove_notify_handler(handle,
- ACPI_SYSTEM_NOTIFY,
- acpi_processor_hotplug_notify);
- break;
- default:
- break;
- }
+ struct acpi_processor *pr;
+
+ BUG_ON(!device || !acpi_driver_data(device));
+ pr = acpi_driver_data(device);
- /* found a processor; skip walking underneath */
- return AE_CTRL_DEPTH;
+ if (cmd == ACPIHP_DEV_POST_CMD_COMMIT) {
+ if (!cpu_online(pr->id) && cpu_up(pr->id))
+ dev_warn(&device->dev,
+ "fails to online CPU%d.\n", pr->id);
+ } else if (cmd == ACPIHP_DEV_POST_CMD_ROLLBACK)
+ acpi_processor_reset(device, pr);
}
-static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr)
+static int acpi_processor_release(struct acpi_device *device,
+ struct acpihp_cancel_context *ctx)
{
- acpi_handle handle = pr->handle;
-
- if (!is_processor_present(handle)) {
- return AE_ERROR;
- }
-
- if (acpi_map_lsapic(handle, &pr->id))
- return AE_ERROR;
+ int result = 0;
+ struct acpi_processor *pr;
- if (arch_register_cpu(pr->id)) {
- acpi_unmap_lsapic(pr->id);
- return AE_ERROR;
- }
+ if (!device || !acpi_driver_data(device))
+ return -EINVAL;
+ pr = acpi_driver_data(device);
- /* CPU got hot-plugged, but cpu_data is not initialized yet
- * Set flag to delay cpu_idle/throttling initialization
- * in:
- * acpi_processor_add()
- * acpi_processor_get_info()
- * and do it when the CPU gets online the first time
- * TBD: Cleanup above functions and try to do this more elegant.
- */
- printk(KERN_INFO "CPU %d got hotplugged\n", pr->id);
- pr->flags.need_hotplug_init = 1;
+ if (cpu_online(pr->id))
+ result = cpu_down(pr->id);
- return AE_OK;
+ return result;
}
-static int acpi_processor_handle_eject(struct acpi_processor *pr)
+static void acpi_processor_post_release(struct acpi_device *device,
+ enum acpihp_dev_post_cmd cmd)
{
- if (cpu_online(pr->id))
- cpu_down(pr->id);
+ struct acpi_processor *pr;
- arch_unregister_cpu(pr->id);
- acpi_unmap_lsapic(pr->id);
- return (0);
-}
-#else
-static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr)
-{
- return AE_ERROR;
-}
-static int acpi_processor_handle_eject(struct acpi_processor *pr)
-{
- return (-EINVAL);
-}
-#endif
+ BUG_ON(!device || !acpi_driver_data(device));
+ pr = acpi_driver_data(device);
-static
-void acpi_processor_install_hotplug_notify(void)
-{
-#ifdef CONFIG_ACPI_HOTPLUG_CPU
- int action = INSTALL_NOTIFY_HANDLER;
- acpi_walk_namespace(ACPI_TYPE_ANY,
- ACPI_ROOT_OBJECT,
- ACPI_UINT32_MAX,
- processor_walk_namespace_cb, NULL, &action, NULL);
-#endif
- register_hotcpu_notifier(&acpi_cpu_notifier);
+ if (cmd == ACPIHP_DEV_POST_CMD_ROLLBACK)
+ if (!cpu_online(pr->id))
+ cpu_up(pr->id);
}
-static
-void acpi_processor_uninstall_hotplug_notify(void)
+static void acpi_processor_unconfigure(struct acpi_device *device)
{
-#ifdef CONFIG_ACPI_HOTPLUG_CPU
- int action = UNINSTALL_NOTIFY_HANDLER;
- acpi_walk_namespace(ACPI_TYPE_ANY,
- ACPI_ROOT_OBJECT,
- ACPI_UINT32_MAX,
- processor_walk_namespace_cb, NULL, &action, NULL);
-#endif
- unregister_hotcpu_notifier(&acpi_cpu_notifier);
+ struct acpi_processor *pr;
+
+ BUG_ON(!device || !acpi_driver_data(device));
+ pr = acpi_driver_data(device);
+ acpi_processor_stop(device, pr);
+ acpi_processor_reset(device, pr);
}
+static struct acpihp_dev_ops acpi_processor_hp_ops = {
+ .get_info = &acpi_processor_get_dev_info,
+ .pre_configure = &acpi_processor_pre_configure,
+ .configure = &acpi_processor_configure,
+ .post_configure = &acpi_processor_post_configure,
+ .release = &acpi_processor_release,
+ .post_release = &acpi_processor_post_release,
+ .unconfigure = &acpi_processor_unconfigure,
+};
+#endif /* CONFIG_ACPI_HOTPLUG_CPU */
+
/*
* We keep the driver loaded even when ACPI is not running.
* This is needed for the powernow-k8 driver, that works even without
* ACPI, but needs symbols from this driver
*/
-
static int __init acpi_processor_init(void)
{
int result = 0;
@@ -938,7 +820,7 @@ static int __init acpi_processor_init(void)
if (result < 0)
return result;
- acpi_processor_install_hotplug_notify();
+ register_hotcpu_notifier(&acpi_cpu_notifier);
acpi_thermal_cpufreq_init();
@@ -958,7 +840,7 @@ static void __exit acpi_processor_exit(void)
acpi_thermal_cpufreq_exit();
- acpi_processor_uninstall_hotplug_notify();
+ unregister_hotcpu_notifier(&acpi_cpu_notifier);
acpi_bus_unregister_driver(&acpi_processor_driver);
--
1.7.9.5
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [ACPIHP PATCH part4 5/9] CPU: introduce busy flag to temporarily disable CPU online sysfs interface
2012-11-04 15:23 [ACPIHP PATCH part4 0/9] enhance ACPI processor driver to support new hotplug framework Jiang Liu
` (3 preceding siblings ...)
2012-11-04 15:23 ` [ACPIHP PATCH part4 4/9] ACPIHP/processor: enhance processor driver to support new hotplug framework Jiang Liu
@ 2012-11-04 15:23 ` Jiang Liu
2012-11-04 15:23 ` [ACPIHP PATCH part4 6/9] ACPIHP/processor: reject online/offline requests when doing processor hotplug Jiang Liu
` (3 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Jiang Liu @ 2012-11-04 15:23 UTC (permalink / raw)
To: Rafael J . Wysocki, Yinghai Lu, Tony Luck, Yasuaki Ishimatsu,
Wen Congyang, Tang Chen, Taku Izumi, Bjorn Helgaas
Cc: Jiang Liu, Kenji Kaneshige, Huang Ying, Bob Moore, Len Brown,
Srivatsa S . Bhat, Yijing Wang, Hanjun Guo, Jiang Liu,
linux-kernel, linux-acpi, linux-pci, linux-mm
When doing physical processor hotplug, all affected CPUs need to be
handled in atomic and shouldn't be disturbed by online/offline requests
from CPU device's online sysfs interface. So introduce a busy flag
into struct cpu to temporariliy reject requests from online sysfs
interface.
Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
---
arch/ia64/include/asm/cpu.h | 2 +-
arch/ia64/kernel/topology.c | 10 ++++++----
arch/x86/include/asm/cpu.h | 2 +-
arch/x86/kernel/topology.c | 10 ++++++----
drivers/acpi/processor_driver.c | 3 ++-
drivers/base/cpu.c | 22 ++++++++++++++++++++++
drivers/xen/cpu_hotplug.c | 2 +-
include/linux/cpu.h | 2 ++
8 files changed, 41 insertions(+), 12 deletions(-)
diff --git a/arch/ia64/include/asm/cpu.h b/arch/ia64/include/asm/cpu.h
index fcca30b..192fa2f 100644
--- a/arch/ia64/include/asm/cpu.h
+++ b/arch/ia64/include/asm/cpu.h
@@ -15,7 +15,7 @@ DECLARE_PER_CPU(struct ia64_cpu, cpu_devices);
DECLARE_PER_CPU(int, cpu_state);
#ifdef CONFIG_HOTPLUG_CPU
-extern int arch_register_cpu(int num);
+extern int arch_register_cpu(int num, int busy);
extern void arch_unregister_cpu(int);
#endif
diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c
index c64460b..11d47a4 100644
--- a/arch/ia64/kernel/topology.c
+++ b/arch/ia64/kernel/topology.c
@@ -40,15 +40,17 @@ EXPORT_SYMBOL_GPL(arch_fix_phys_package_id);
#ifdef CONFIG_HOTPLUG_CPU
-int __ref arch_register_cpu(int num)
+int __ref arch_register_cpu(int num, int busy)
{
#ifdef CONFIG_ACPI
/*
* If CPEI can be re-targeted or if this is not
* CPEI target, then it is hotpluggable
*/
- if (can_cpei_retarget() || !is_cpu_cpei_target(num))
+ if (can_cpei_retarget() || !is_cpu_cpei_target(num)) {
sysfs_cpus[num].cpu.hotpluggable = 1;
+ sysfs_cpus[num].cpu.busy = busy;
+ }
map_cpu_to_node(num, node_cpuid[num].nid);
#endif
return register_cpu(&sysfs_cpus[num].cpu, num);
@@ -64,7 +66,7 @@ void __ref arch_unregister_cpu(int num)
}
EXPORT_SYMBOL(arch_unregister_cpu);
#else
-static int __init arch_register_cpu(int num)
+static int __init arch_register_cpu(int num, int busy)
{
return register_cpu(&sysfs_cpus[num].cpu, num);
}
@@ -90,7 +92,7 @@ static int __init topology_init(void)
panic("kzalloc in topology_init failed - NR_CPUS too big?");
for_each_present_cpu(i) {
- if((err = arch_register_cpu(i)))
+ if((err = arch_register_cpu(i, 0)))
goto out;
}
out:
diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h
index 4564c8e..724c777 100644
--- a/arch/x86/include/asm/cpu.h
+++ b/arch/x86/include/asm/cpu.h
@@ -26,7 +26,7 @@ struct x86_cpu {
};
#ifdef CONFIG_HOTPLUG_CPU
-extern int arch_register_cpu(int num);
+extern int arch_register_cpu(int num, int busy);
extern void arch_unregister_cpu(int);
#endif
diff --git a/arch/x86/kernel/topology.c b/arch/x86/kernel/topology.c
index 76ee977..c66ef53 100644
--- a/arch/x86/kernel/topology.c
+++ b/arch/x86/kernel/topology.c
@@ -35,7 +35,7 @@
static DEFINE_PER_CPU(struct x86_cpu, cpu_devices);
#ifdef CONFIG_HOTPLUG_CPU
-int __ref arch_register_cpu(int num)
+int __ref arch_register_cpu(int num, int busy)
{
/*
* CPU0 cannot be offlined due to several
@@ -46,8 +46,10 @@ int __ref arch_register_cpu(int num)
* Also certain PCI quirks require not to enable hotplug control
* for all CPU's.
*/
- if (num)
+ if (num) {
per_cpu(cpu_devices, num).cpu.hotpluggable = 1;
+ per_cpu(cpu_devices, num).cpu.busy = busy;
+ }
return register_cpu(&per_cpu(cpu_devices, num).cpu, num);
}
@@ -60,7 +62,7 @@ void arch_unregister_cpu(int num)
EXPORT_SYMBOL(arch_unregister_cpu);
#else /* CONFIG_HOTPLUG_CPU */
-static int __init arch_register_cpu(int num)
+static int __init arch_register_cpu(int num, int busy)
{
return register_cpu(&per_cpu(cpu_devices, num).cpu, num);
}
@@ -76,7 +78,7 @@ static int __init topology_init(void)
#endif
for_each_present_cpu(i)
- arch_register_cpu(i);
+ arch_register_cpu(i, 0);
return 0;
}
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
index b8c3684..53e364d 100644
--- a/drivers/acpi/processor_driver.c
+++ b/drivers/acpi/processor_driver.c
@@ -702,7 +702,8 @@ static int acpi_processor_pre_configure(struct acpi_device *device,
if (result)
return result;
BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
- result = arch_register_cpu(pr->id);
+
+ result = arch_register_cpu(pr->id, 0);
if (result) {
acpi_unmap_lsapic(pr->id);
pr->id = -1;
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 6345294..dc6246c 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -42,6 +42,11 @@ static ssize_t __ref store_online(struct device *dev,
ssize_t ret;
cpu_hotplug_driver_lock();
+ if (cpu->busy) {
+ ret = -EBUSY;
+ goto out;
+ }
+
switch (buf[0]) {
case '0':
ret = cpu_down(cpu->dev.id);
@@ -56,6 +61,8 @@ static ssize_t __ref store_online(struct device *dev,
default:
ret = -EINVAL;
}
+
+out:
cpu_hotplug_driver_unlock();
if (ret >= 0)
@@ -308,6 +315,21 @@ bool cpu_is_hotpluggable(unsigned cpu)
}
EXPORT_SYMBOL_GPL(cpu_is_hotpluggable);
+int cpu_set_busy(unsigned int id, int busy)
+{
+ int old;
+ struct device *device = get_cpu_device(id);
+ struct cpu *cpu = container_of(device, struct cpu, dev);
+
+ cpu_hotplug_driver_lock();
+ old = cpu->busy;
+ cpu->busy = busy;
+ cpu_hotplug_driver_unlock();
+
+ return old;
+}
+EXPORT_SYMBOL_GPL(cpu_set_busy);
+
#ifdef CONFIG_GENERIC_CPU_DEVICES
static DEFINE_PER_CPU(struct cpu, cpu_devices);
#endif
diff --git a/drivers/xen/cpu_hotplug.c b/drivers/xen/cpu_hotplug.c
index 4dcfced..95bde8a 100644
--- a/drivers/xen/cpu_hotplug.c
+++ b/drivers/xen/cpu_hotplug.c
@@ -9,7 +9,7 @@
static void enable_hotplug_cpu(int cpu)
{
if (!cpu_present(cpu))
- arch_register_cpu(cpu);
+ arch_register_cpu(cpu, 0);
set_cpu_present(cpu, true);
}
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index ce7a074..557501b 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -23,12 +23,14 @@ struct device;
struct cpu {
int node_id; /* The node which contains the CPU */
int hotpluggable; /* creates sysfs control file if hotpluggable */
+ int busy;
struct device dev;
};
extern int register_cpu(struct cpu *cpu, int num);
extern struct device *get_cpu_device(unsigned cpu);
extern bool cpu_is_hotpluggable(unsigned cpu);
+extern int cpu_set_busy(unsigned int cpu, int busy);
extern int cpu_add_dev_attr(struct device_attribute *attr);
extern void cpu_remove_dev_attr(struct device_attribute *attr);
--
1.7.9.5
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [ACPIHP PATCH part4 6/9] ACPIHP/processor: reject online/offline requests when doing processor hotplug
2012-11-04 15:23 [ACPIHP PATCH part4 0/9] enhance ACPI processor driver to support new hotplug framework Jiang Liu
` (4 preceding siblings ...)
2012-11-04 15:23 ` [ACPIHP PATCH part4 5/9] CPU: introduce busy flag to temporarily disable CPU online sysfs interface Jiang Liu
@ 2012-11-04 15:23 ` Jiang Liu
2012-11-04 15:24 ` [ACPIHP PATCH part4 7/9] ACPI/processor: cache parsed APIC ID in processor driver data structure Jiang Liu
` (2 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Jiang Liu @ 2012-11-04 15:23 UTC (permalink / raw)
To: Rafael J . Wysocki, Yinghai Lu, Tony Luck, Yasuaki Ishimatsu,
Wen Congyang, Tang Chen, Taku Izumi, Bjorn Helgaas
Cc: Jiang Liu, Kenji Kaneshige, Huang Ying, Bob Moore, Len Brown,
Srivatsa S . Bhat, Yijing Wang, Hanjun Guo, Jiang Liu,
linux-kernel, linux-acpi, linux-pci, linux-mm
When doing physical processor hotplug, all affected CPUs should be
handled in atomic. In other words, it shouldn't be disturbed by
online/offline requests from CPU device's online sysfs interface.
For example, it's fatal if a CPU is onlined through CPU device's
online sysfs interface between the hotplug driver offlines all affected
CPUs and powers the physical processor off.
So temporarily reject online/offline requests from CPU device's online
sysfs interface by setting the busy flag when doing physical processor
hotplug.
Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
---
drivers/acpi/processor_driver.c | 23 +++++++++++++++++++++--
1 file changed, 21 insertions(+), 2 deletions(-)
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
index 53e364d..22214fc 100644
--- a/drivers/acpi/processor_driver.c
+++ b/drivers/acpi/processor_driver.c
@@ -703,7 +703,7 @@ static int acpi_processor_pre_configure(struct acpi_device *device,
return result;
BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
- result = arch_register_cpu(pr->id, 0);
+ result = arch_register_cpu(pr->id, 1);
if (result) {
acpi_unmap_lsapic(pr->id);
pr->id = -1;
@@ -751,10 +751,26 @@ static void acpi_processor_post_configure(struct acpi_device *device,
if (!cpu_online(pr->id) && cpu_up(pr->id))
dev_warn(&device->dev,
"fails to online CPU%d.\n", pr->id);
+ cpu_set_busy(pr->id, 0);
} else if (cmd == ACPIHP_DEV_POST_CMD_ROLLBACK)
acpi_processor_reset(device, pr);
}
+static int acpi_processor_pre_release(struct acpi_device *device,
+ struct acpihp_cancel_context *ctx)
+{
+ int result;
+ struct acpi_processor *pr;
+
+ if (!device || !acpi_driver_data(device))
+ return -EINVAL;
+ pr = acpi_driver_data(device);
+
+ result = cpu_set_busy(pr->id, 1);
+
+ return result ? -EBUSY : 0;
+}
+
static int acpi_processor_release(struct acpi_device *device,
struct acpihp_cancel_context *ctx)
{
@@ -779,9 +795,11 @@ static void acpi_processor_post_release(struct acpi_device *device,
BUG_ON(!device || !acpi_driver_data(device));
pr = acpi_driver_data(device);
- if (cmd == ACPIHP_DEV_POST_CMD_ROLLBACK)
+ if (cmd == ACPIHP_DEV_POST_CMD_ROLLBACK) {
if (!cpu_online(pr->id))
cpu_up(pr->id);
+ cpu_set_busy(pr->id, 0);
+ }
}
static void acpi_processor_unconfigure(struct acpi_device *device)
@@ -799,6 +817,7 @@ static struct acpihp_dev_ops acpi_processor_hp_ops = {
.pre_configure = &acpi_processor_pre_configure,
.configure = &acpi_processor_configure,
.post_configure = &acpi_processor_post_configure,
+ .pre_release = &acpi_processor_pre_release,
.release = &acpi_processor_release,
.post_release = &acpi_processor_post_release,
.unconfigure = &acpi_processor_unconfigure,
--
1.7.9.5
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [ACPIHP PATCH part4 7/9] ACPI/processor: cache parsed APIC ID in processor driver data structure
2012-11-04 15:23 [ACPIHP PATCH part4 0/9] enhance ACPI processor driver to support new hotplug framework Jiang Liu
` (5 preceding siblings ...)
2012-11-04 15:23 ` [ACPIHP PATCH part4 6/9] ACPIHP/processor: reject online/offline requests when doing processor hotplug Jiang Liu
@ 2012-11-04 15:24 ` Jiang Liu
2012-11-04 15:24 ` [ACPIHP PATCH part4 8/9] ACPI/processor: serialize call to acpi_map/unmap_lsapic Jiang Liu
2012-11-04 15:24 ` [ACPIHP PATCH part4 9/9] x86: simplify _acpi_map_lsapic() implementation Jiang Liu
8 siblings, 0 replies; 10+ messages in thread
From: Jiang Liu @ 2012-11-04 15:24 UTC (permalink / raw)
To: Rafael J . Wysocki, Yinghai Lu, Tony Luck, Yasuaki Ishimatsu,
Wen Congyang, Tang Chen, Taku Izumi, Bjorn Helgaas
Cc: Jiang Liu, Kenji Kaneshige, Huang Ying, Bob Moore, Len Brown,
Srivatsa S . Bhat, Yijing Wang, Hanjun Guo, Jiang Liu,
linux-kernel, linux-acpi, linux-pci, linux-mm
Enhance ACPI processor driver to cache parsed APIC ID in processor
driver data structure, and avoid reparsing again in _acpi_map_lsapic().
This change also makes fake CPU hotplug possible because we have no
dependency on _MAT method anymore.
Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
---
arch/ia64/kernel/acpi.c | 38 ++++----------------------------------
arch/x86/kernel/acpi/boot.c | 38 +++-----------------------------------
drivers/acpi/internal.h | 2 ++
drivers/acpi/processor_core.c | 28 +++++++++++++++++++++++-----
drivers/acpi/processor_driver.c | 11 ++++++++---
include/acpi/processor.h | 1 +
include/linux/acpi.h | 2 +-
7 files changed, 42 insertions(+), 78 deletions(-)
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
index 44057885..f0da941 100644
--- a/arch/ia64/kernel/acpi.c
+++ b/arch/ia64/kernel/acpi.c
@@ -880,40 +880,10 @@ __init void prefill_possible_map(void)
set_cpu_possible(i, true);
}
-static int __cpuinit _acpi_map_lsapic(acpi_handle handle, int *pcpu)
+static int __cpuinit _acpi_map_lsapic(acpi_handle handle, int physid, int *pcpu)
{
- struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
- union acpi_object *obj;
- struct acpi_madt_local_sapic *lsapic;
cpumask_t tmp_map;
- int cpu, physid;
-
- if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer)))
- return -EINVAL;
-
- if (!buffer.length || !buffer.pointer)
- return -EINVAL;
-
- obj = buffer.pointer;
- if (obj->type != ACPI_TYPE_BUFFER)
- {
- kfree(buffer.pointer);
- return -EINVAL;
- }
-
- lsapic = (struct acpi_madt_local_sapic *)obj->buffer.pointer;
-
- if ((lsapic->header.type != ACPI_MADT_TYPE_LOCAL_SAPIC) ||
- (!(lsapic->lapic_flags & ACPI_MADT_ENABLED))) {
- kfree(buffer.pointer);
- return -EINVAL;
- }
-
- physid = ((lsapic->id << 8) | (lsapic->eid));
-
- kfree(buffer.pointer);
- buffer.length = ACPI_ALLOCATE_BUFFER;
- buffer.pointer = NULL;
+ int cpu;
cpumask_complement(&tmp_map, cpu_present_mask);
cpu = cpumask_first(&tmp_map);
@@ -932,9 +902,9 @@ static int __cpuinit _acpi_map_lsapic(acpi_handle handle, int *pcpu)
}
/* wrapper to silence section mismatch warning */
-int __ref acpi_map_lsapic(acpi_handle handle, int *pcpu)
+int __ref acpi_map_lsapic(acpi_handle handle, int physid, int *pcpu)
{
- return _acpi_map_lsapic(handle, pcpu);
+ return _acpi_map_lsapic(handle, physid, pcpu);
}
EXPORT_SYMBOL(acpi_map_lsapic);
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index e651f7a..5e76952 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -608,44 +608,12 @@ static void __cpuinit acpi_map_cpu2node(acpi_handle handle, int cpu, int physid)
#endif
}
-static int __cpuinit _acpi_map_lsapic(acpi_handle handle, int *pcpu)
+static int __cpuinit _acpi_map_lsapic(acpi_handle handle, int physid, int *pcpu)
{
- struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
- union acpi_object *obj;
- struct acpi_madt_local_apic *lapic;
cpumask_var_t tmp_map, new_map;
- u8 physid;
int cpu;
int retval = -ENOMEM;
- if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer)))
- return -EINVAL;
-
- if (!buffer.length || !buffer.pointer)
- return -EINVAL;
-
- obj = buffer.pointer;
- if (obj->type != ACPI_TYPE_BUFFER ||
- obj->buffer.length < sizeof(*lapic)) {
- kfree(buffer.pointer);
- return -EINVAL;
- }
-
- lapic = (struct acpi_madt_local_apic *)obj->buffer.pointer;
-
- if (lapic->header.type != ACPI_MADT_TYPE_LOCAL_APIC ||
- !(lapic->lapic_flags & ACPI_MADT_ENABLED)) {
- kfree(buffer.pointer);
- return -EINVAL;
- }
-
- physid = lapic->id;
-
- kfree(buffer.pointer);
- buffer.length = ACPI_ALLOCATE_BUFFER;
- buffer.pointer = NULL;
- lapic = NULL;
-
if (!alloc_cpumask_var(&tmp_map, GFP_KERNEL))
goto out;
@@ -683,9 +651,9 @@ out:
}
/* wrapper to silence section mismatch warning */
-int __ref acpi_map_lsapic(acpi_handle handle, int *pcpu)
+int __ref acpi_map_lsapic(acpi_handle handle, int physid, int *pcpu)
{
- return _acpi_map_lsapic(handle, pcpu);
+ return _acpi_map_lsapic(handle, physid, pcpu);
}
EXPORT_SYMBOL(acpi_map_lsapic);
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index d2c4d83..19d8555 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -47,6 +47,8 @@ int acpi_bus_init_power(struct acpi_device *device);
int acpi_wakeup_device_init(void);
void acpi_early_processor_set_pdc(void);
+int acpi_get_apicid(acpi_handle handle, int type, u32 acpi_id);
+int acpi_map_cpuid(int apic_id, u32 acpi_id);
/* --------------------------------------------------------------------------
Embedded Controller
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index eff7222..8fd25cc 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -163,16 +163,24 @@ exit:
return apic_id;
}
-int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id)
+int acpi_get_apicid(acpi_handle handle, int type, u32 acpi_id)
{
-#ifdef CONFIG_SMP
- int i;
-#endif
- int apic_id = -1;
+ int apic_id;
apic_id = map_mat_entry(handle, type, acpi_id);
if (apic_id == -1)
apic_id = map_madt_entry(type, acpi_id);
+
+ return apic_id;
+}
+EXPORT_SYMBOL_GPL(acpi_get_apicid);
+
+int acpi_map_cpuid(int apic_id, u32 acpi_id)
+{
+#ifdef CONFIG_SMP
+ int i;
+#endif
+
if (apic_id == -1) {
/*
* On UP processor, there is no _MAT or MADT table.
@@ -212,6 +220,16 @@ int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id)
#endif
return -1;
}
+EXPORT_SYMBOL_GPL(acpi_map_cpuid);
+
+int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id)
+{
+ int apic_id;
+
+ apic_id = acpi_get_apicid(handle, type, acpi_id);
+
+ return acpi_map_cpuid(apic_id, acpi_id);
+}
EXPORT_SYMBOL_GPL(acpi_get_cpuid);
static bool __init processor_physically_present(acpi_handle handle)
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
index 22214fc..9a02210 100644
--- a/drivers/acpi/processor_driver.c
+++ b/drivers/acpi/processor_driver.c
@@ -57,6 +57,7 @@
#include <acpi/acpi_drivers.h>
#include <acpi/processor.h>
#include <acpi/acpi_hotplug.h>
+#include "internal.h"
#define PREFIX "ACPI: "
@@ -303,7 +304,8 @@ static int acpi_processor_get_info(struct acpi_device *device)
device_declaration = 1;
pr->acpi_id = value;
}
- cpu_index = acpi_get_cpuid(pr->handle, device_declaration, pr->acpi_id);
+ pr->apic_id = acpi_get_apicid(pr->handle, device_declaration, pr->acpi_id);
+ cpu_index = acpi_map_cpuid(pr->apic_id, pr->acpi_id);
/* Handle UP system running SMP kernel, with no LAPIC in MADT */
if (!cpu0_initialized && (cpu_index == -1) &&
@@ -689,7 +691,7 @@ static int acpi_processor_get_dev_info(struct acpi_device *device,
static int acpi_processor_pre_configure(struct acpi_device *device,
struct acpihp_cancel_context *ctx)
{
- int result;
+ int result = -EINVAL;
struct acpi_processor *pr;
if (!device || !acpi_driver_data(device))
@@ -698,7 +700,10 @@ static int acpi_processor_pre_configure(struct acpi_device *device,
/* Generate CPUID for hot-added CPUs */
if (pr->id == -1) {
- result = acpi_map_lsapic(device->handle, &pr->id);
+ if (pr->apic_id == -1)
+ return result;
+
+ result = acpi_map_lsapic(device->handle, pr->apic_id, &pr->id);
if (result)
return result;
BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
diff --git a/include/acpi/processor.h b/include/acpi/processor.h
index 9e1c980..e25cc4e 100644
--- a/include/acpi/processor.h
+++ b/include/acpi/processor.h
@@ -197,6 +197,7 @@ struct acpi_processor_flags {
struct acpi_processor {
acpi_handle handle;
u32 acpi_id;
+ int apic_id;
u32 id;
u32 pblk;
int performance_platform_limit;
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 90be989..774ce2b 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -101,7 +101,7 @@ void acpi_numa_arch_fixup(void);
#ifdef CONFIG_ACPI_HOTPLUG_CPU
/* Arch dependent functions for cpu hotplug support */
-int acpi_map_lsapic(acpi_handle handle, int *pcpu);
+int acpi_map_lsapic(acpi_handle handle, int physid, int *pcpu);
int acpi_unmap_lsapic(int cpu);
#endif /* CONFIG_ACPI_HOTPLUG_CPU */
--
1.7.9.5
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [ACPIHP PATCH part4 8/9] ACPI/processor: serialize call to acpi_map/unmap_lsapic
2012-11-04 15:23 [ACPIHP PATCH part4 0/9] enhance ACPI processor driver to support new hotplug framework Jiang Liu
` (6 preceding siblings ...)
2012-11-04 15:24 ` [ACPIHP PATCH part4 7/9] ACPI/processor: cache parsed APIC ID in processor driver data structure Jiang Liu
@ 2012-11-04 15:24 ` Jiang Liu
2012-11-04 15:24 ` [ACPIHP PATCH part4 9/9] x86: simplify _acpi_map_lsapic() implementation Jiang Liu
8 siblings, 0 replies; 10+ messages in thread
From: Jiang Liu @ 2012-11-04 15:24 UTC (permalink / raw)
To: Rafael J . Wysocki, Yinghai Lu, Tony Luck, Yasuaki Ishimatsu,
Wen Congyang, Tang Chen, Taku Izumi, Bjorn Helgaas
Cc: Jiang Liu, Kenji Kaneshige, Huang Ying, Bob Moore, Len Brown,
Srivatsa S . Bhat, Yijing Wang, Hanjun Guo, Jiang Liu,
linux-kernel, linux-acpi, linux-pci, linux-mm
Function acpi_map_lsapic() is used to allocate CPU id for hot-added
CPUs and acpi_unmap_lsapic() is used to free CPU id for hot-removed
CPUs. But currently there's no mechanism to serialze the CPU id
allocation/free process, which may cause wrong CPU id assignment
when handling concurrent CPU online/offline operations. So introuce
a mutex to serialize CPU id allocation/free.
Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
---
drivers/acpi/processor_driver.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
index 9a02210..6dbce2f 100644
--- a/drivers/acpi/processor_driver.c
+++ b/drivers/acpi/processor_driver.c
@@ -108,6 +108,7 @@ static struct acpi_driver acpi_processor_driver = {
.drv.pm = &acpi_processor_pm,
};
+static DEFINE_MUTEX(acpi_processor_mutex);
static DEFINE_PER_CPU(void *, processor_device_array);
DEFINE_PER_CPU(struct acpi_processor *, processors);
@@ -668,7 +669,9 @@ static void acpi_processor_reset(struct acpi_device *device, struct acpi_process
acpi_processor_unlink(device, pr);
put_online_cpus();
arch_unregister_cpu(pr->id);
+ mutex_lock(&acpi_processor_mutex);
acpi_unmap_lsapic(pr->id);
+ mutex_unlock(&acpi_processor_mutex);
pr->id = -1;
}
@@ -703,14 +706,18 @@ static int acpi_processor_pre_configure(struct acpi_device *device,
if (pr->apic_id == -1)
return result;
+ mutex_lock(&acpi_processor_mutex);
result = acpi_map_lsapic(device->handle, pr->apic_id, &pr->id);
+ mutex_unlock(&acpi_processor_mutex);
if (result)
return result;
BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
result = arch_register_cpu(pr->id, 1);
if (result) {
+ mutex_lock(&acpi_processor_mutex);
acpi_unmap_lsapic(pr->id);
+ mutex_unlock(&acpi_processor_mutex);
pr->id = -1;
return result;
}
--
1.7.9.5
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [ACPIHP PATCH part4 9/9] x86: simplify _acpi_map_lsapic() implementation
2012-11-04 15:23 [ACPIHP PATCH part4 0/9] enhance ACPI processor driver to support new hotplug framework Jiang Liu
` (7 preceding siblings ...)
2012-11-04 15:24 ` [ACPIHP PATCH part4 8/9] ACPI/processor: serialize call to acpi_map/unmap_lsapic Jiang Liu
@ 2012-11-04 15:24 ` Jiang Liu
8 siblings, 0 replies; 10+ messages in thread
From: Jiang Liu @ 2012-11-04 15:24 UTC (permalink / raw)
To: Rafael J . Wysocki, Yinghai Lu, Tony Luck, Yasuaki Ishimatsu,
Wen Congyang, Tang Chen, Taku Izumi, Bjorn Helgaas
Cc: Jiang Liu, Kenji Kaneshige, Huang Ying, Bob Moore, Len Brown,
Srivatsa S . Bhat, Yijing Wang, Hanjun Guo, Jiang Liu,
linux-kernel, linux-acpi, linux-pci, linux-mm
Simplify implementation of function _acpi_map_lsapic().
Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
---
arch/x86/include/asm/mpspec.h | 2 +-
arch/x86/kernel/acpi/boot.c | 44 +++++++++--------------------------------
arch/x86/kernel/apic/apic.c | 8 +++++---
3 files changed, 15 insertions(+), 39 deletions(-)
diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h
index 3e2f42a..f1d6487 100644
--- a/arch/x86/include/asm/mpspec.h
+++ b/arch/x86/include/asm/mpspec.h
@@ -94,7 +94,7 @@ static inline void early_reserve_e820_mpc_new(void) { }
#define default_get_smp_config x86_init_uint_noop
#endif
-void __cpuinit generic_processor_info(int apicid, int version);
+int __cpuinit generic_processor_info(int apicid, int version);
#ifdef CONFIG_ACPI
extern void mp_register_ioapic(int id, u32 address, u32 gsi_base);
extern void mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger,
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 5e76952..f354446 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -195,24 +195,24 @@ static int __init acpi_parse_madt(struct acpi_table_header *table)
return 0;
}
-static void __cpuinit acpi_register_lapic(int id, u8 enabled)
+static int __cpuinit acpi_register_lapic(int id, u8 enabled)
{
unsigned int ver = 0;
if (id >= (MAX_LOCAL_APIC-1)) {
printk(KERN_INFO PREFIX "skipped apicid that is too big\n");
- return;
+ return -1;
}
if (!enabled) {
++disabled_cpus;
- return;
+ return -1;
}
if (boot_cpu_physical_apicid != -1U)
ver = apic_version[boot_cpu_physical_apicid];
- generic_processor_info(id, ver);
+ return generic_processor_info(id, ver);
}
static int __init
@@ -610,44 +610,19 @@ static void __cpuinit acpi_map_cpu2node(acpi_handle handle, int cpu, int physid)
static int __cpuinit _acpi_map_lsapic(acpi_handle handle, int physid, int *pcpu)
{
- cpumask_var_t tmp_map, new_map;
int cpu;
- int retval = -ENOMEM;
- if (!alloc_cpumask_var(&tmp_map, GFP_KERNEL))
- goto out;
-
- if (!alloc_cpumask_var(&new_map, GFP_KERNEL))
- goto free_tmp_map;
-
- cpumask_copy(tmp_map, cpu_present_mask);
- acpi_register_lapic(physid, ACPI_MADT_ENABLED);
-
- /*
- * If acpi_register_lapic successfully generates a new logical cpu
- * number, then the following will get us exactly what was mapped
- */
- cpumask_andnot(new_map, cpu_present_mask, tmp_map);
- if (cpumask_empty(new_map)) {
+ cpu = acpi_register_lapic(physid, ACPI_MADT_ENABLED);
+ if (cpu == -1) {
printk ("Unable to map lapic to logical cpu number\n");
- retval = -EINVAL;
- goto free_new_map;
+ return -EINVAL;
}
acpi_processor_set_pdc(handle);
-
- cpu = cpumask_first(new_map);
acpi_map_cpu2node(handle, cpu, physid);
-
*pcpu = cpu;
- retval = 0;
-
-free_new_map:
- free_cpumask_var(new_map);
-free_tmp_map:
- free_cpumask_var(tmp_map);
-out:
- return retval;
+
+ return 0;
}
/* wrapper to silence section mismatch warning */
@@ -665,7 +640,6 @@ int acpi_unmap_lsapic(int cpu)
return (0);
}
-
EXPORT_SYMBOL(acpi_unmap_lsapic);
#endif /* CONFIG_ACPI_HOTPLUG_CPU */
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index b17416e..9fdc293 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -2030,7 +2030,7 @@ void disconnect_bsp_APIC(int virt_wire_setup)
apic_write(APIC_LVT1, value);
}
-void __cpuinit generic_processor_info(int apicid, int version)
+int __cpuinit generic_processor_info(int apicid, int version)
{
int cpu, max = nr_cpu_ids;
bool boot_cpu_detected = physid_isset(boot_cpu_physical_apicid,
@@ -2050,7 +2050,7 @@ void __cpuinit generic_processor_info(int apicid, int version)
" Processor %d/0x%x ignored.\n", max, thiscpu, apicid);
disabled_cpus++;
- return;
+ return -1;
}
if (num_processors >= nr_cpu_ids) {
@@ -2061,7 +2061,7 @@ void __cpuinit generic_processor_info(int apicid, int version)
" Processor %d/0x%x ignored.\n", max, thiscpu, apicid);
disabled_cpus++;
- return;
+ return -1;
}
num_processors++;
@@ -2106,6 +2106,8 @@ void __cpuinit generic_processor_info(int apicid, int version)
#endif
set_cpu_possible(cpu, true);
set_cpu_present(cpu, true);
+
+ return cpu;
}
int hard_smp_processor_id(void)
--
1.7.9.5
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related [flat|nested] 10+ messages in thread