acpi : cpu hot-remove returns error when cpu_down() fails
Subsystems (3)
PATCH v3 1/3 acpi : cpu hot-remove returns error when cpu_down() fails
Even if cpu_down() fails, acpi_processor_remove() continues to remove the cpu. But in this case, it should return error number since some process may run on the cpu. If the cpu has a running process and the cpu is turned the power off, the system may not work well.
--- drivers/acpi/processor_driver.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
drivers/acpi/processor_driver.c +12 -6
@@ -610,7 +610,7 @@ err_free_pr:static int acpi_processor_remove (struct acpi_device *device,int type) {struct acpi_processor *pr =NULL ; - +int ret;if (!device || !acpi_driver_data (device))return -EINVAL ;
@@ -621,8 +621,9 @@ static int acpi_processor_remove(struct goto free;if (type ==ACPI_BUS_REMOVAL_EJECT ) { -if (acpi_processor_handle_eject (pr)) -return -EINVAL ; + ret =acpi_processor_handle_eject (pr); +if (ret) +return ret; }acpi_processor_power_exit (pr, device);
@@ -841,12 +842,17 @@ static acpi_status acpi_processor_hotaddstatic int acpi_processor_handle_eject (struct acpi_processor *pr) { -if (cpu_online (pr->id)) -cpu_down (pr->id); +int ret; + +if (cpu_online (pr->id)) { + ret =cpu_down (pr->id); +if (ret) +return ret; + }arch_unregister_cpu (pr->id);acpi_unmap_lsapic (pr->id); -return (0 ); +return ret; }#else static acpi_status acpi_processor_hotadd_init (struct acpi_processor *pr)
PATCH v3 2/3 acpi : prevent cpu from becoming online
Even if acpi_processor_handle_eject() offlines cpu, there is a chance to online the cpu after that. So the patch closes the window by using get/put_online_cpus().
Why does the patch change _cpu_up() logic?
The patch cares the race of hot-remove cpu and _cpu_up(). If the patch does not change it, there is the following race.
hot-remove cpu | _cpu_up()
------------------------------------- ------------------------------------
call acpi_processor_handle_eject() |
call cpu_down() |
call get_online_cpus() |
| call cpu_hotplug_begin() and stop here
call arch_unregister_cpu() |
call acpi_unmap_lsapic() |
call put_online_cpus() |
| start and continue _cpu_up()
return acpi_processor_remove() |
continue hot-remove the cpu |So _cpu_up() can continue to itself. And hot-remove cpu can also continue itself. If the patch changes _cpu_up() logic, the race disappears as below:
hot-remove cpu | _cpu_up()
-----------------------------------------------------------------------
call acpi_processor_handle_eject() |
call cpu_down() |
call get_online_cpus() |
| call cpu_hotplug_begin() and stop here
call arch_unregister_cpu() |
call acpi_unmap_lsapic() |
cpu's cpu_present is set |
to false by set_cpu_present()|
call put_online_cpus() |
| start _cpu_up()
| check cpu_present() and return -EINVAL
return acpi_processor_remove() |
continue hot-remove the cpu |--- drivers/acpi/processor_driver.c | 14 ++++++++++++++ kernel/cpu.c | 8 +++++--- 2 files changed, 19 insertions(+), 3 deletions(-)
drivers/acpi/processor_driver.c +14 -0
@@ -850,8 +850,22 @@ static int acpi_processor_handle_eject(s return ret; } +get_online_cpus (); +/* +* The cpu might become online again at this point. So we check whether +* the cpu has been onlined or not. If the cpu became online, it means +* that someone wants to use the cpu. So acpi_processor_handle_eject() +* returns -EAGAIN. +*/ +if (unlikely (cpu_online (pr->id))) { +put_online_cpus (); +printk ("Failed to remove CPU %d, since someone onlines it\n" + , pr->id); +return -EAGAIN ; + }arch_unregister_cpu (pr->id);acpi_unmap_lsapic (pr->id); +put_online_cpus ();return ret; }#else
kernel/cpu.c +5 -3
@@ -343,11 +343,13 @@ static int __cpuinit _cpu_up(unsigned inunsigned long mod = tasks_frozen ?CPU_TASKS_FROZEN :0 ;struct task_struct *idle; -if (cpu_online (cpu) || !cpu_present (cpu)) -return -EINVAL ; -cpu_hotplug_begin (); +if (cpu_online (cpu) || !cpu_present (cpu)) { + ret = -EINVAL ; + goto out; + } + idle =idle_thread_get (cpu);if (IS_ERR (idle)) { ret =PTR_ERR (idle);
PATCH RESEND v3 2/3 acpi : prevent cpu from becoming online
Even if acpi_processor_handle_eject() offlines cpu, there is a chance to online the cpu after that. So the patch closes the window by using get/put_online_cpus().
Why does the patch change _cpu_up() logic?
The patch cares the race of hot-remove cpu and _cpu_up(). If the patch does not change it, there is the following race.
hot-remove cpu | _cpu_up()
------------------------------------- ------------------------------------
call acpi_processor_handle_eject() |
call cpu_down() |
call get_online_cpus() |
| call cpu_hotplug_begin() and stop here
call arch_unregister_cpu() |
call acpi_unmap_lsapic() |
call put_online_cpus() |
| start and continue _cpu_up()
return acpi_processor_remove() |
continue hot-remove the cpu |So _cpu_up() can continue to itself. And hot-remove cpu can also continue itself. If the patch changes _cpu_up() logic, the race disappears as below:
hot-remove cpu | _cpu_up()
-----------------------------------------------------------------------
call acpi_processor_handle_eject() |
call cpu_down() |
call get_online_cpus() |
| call cpu_hotplug_begin() and stop here
call arch_unregister_cpu() |
call acpi_unmap_lsapic() |
cpu's cpu_present is set |
to false by set_cpu_present()|
call put_online_cpus() |
| start _cpu_up()
| check cpu_present() and return -EINVAL
return acpi_processor_remove() |
continue hot-remove the cpu |--- drivers/acpi/processor_driver.c | 14 ++++++++++++++ kernel/cpu.c | 8 +++++--- 2 files changed, 19 insertions(+), 3 deletions(-)
drivers/acpi/processor_driver.c +14 -0
@@ -850,8 +850,22 @@ static int acpi_processor_handle_eject(s return ret; } +get_online_cpus (); +/* +* The cpu might become online again at this point. So we check whether +* the cpu has been onlined or not. If the cpu became online, it means +* that someone wants to use the cpu. So acpi_processor_handle_eject() +* returns -EAGAIN. +*/ +if (unlikely (cpu_online (pr->id))) { +put_online_cpus (); +printk (KERN_WARNING "Failed to remove CPU %d, " +"since someone onlines the cpu\n" , pr->id); +return -EAGAIN ; + }arch_unregister_cpu (pr->id);acpi_unmap_lsapic (pr->id); +put_online_cpus ();return ret; }#else
kernel/cpu.c +5 -3
@@ -343,11 +343,13 @@ static int __cpuinit _cpu_up(unsigned inunsigned long mod = tasks_frozen ?CPU_TASKS_FROZEN :0 ;struct task_struct *idle; -if (cpu_online (cpu) || !cpu_present (cpu)) -return -EINVAL ; -cpu_hotplug_begin (); +if (cpu_online (cpu) || !cpu_present (cpu)) { + ret = -EINVAL ; + goto out; + } + idle =idle_thread_get (cpu);if (IS_ERR (idle)) { ret =PTR_ERR (idle);
Re: [PATCH v3 2/3 RESEND] acpi : prevent cpu from becoming online
Quoted 41 lines · Yasuaki Ishimatsu
Even if
acpi_processor_handle_eject()offlines cpu, there is a chance to online the cpu after that. So the patch closes the window by using get/put_online_cpus().Why does the patch change
_cpu_up()logic?The patch cares the race of hot-remove cpu and
_cpu_up(). If the patch does not change it, there is the following race.hot-remove cpu |
_cpu_up()
------------------------------------- ------------------------------------call acpi_processor_handle_eject() | call cpu_down() | call get_online_cpus() | | call cpu_hotplug_begin() and stop here call arch_unregister_cpu() | call acpi_unmap_lsapic() | call put_online_cpus() | | start and continue _cpu_up() return acpi_processor_remove() | continue hot-remove the cpu |So
_cpu_up()can continue to itself. And hot-remove cpu can also continue itself. If the patch changes_cpu_up()logic, the race disappears as below:hot-remove cpu |
_cpu_up()
-----------------------------------------------------------------------call acpi_processor_handle_eject() | call cpu_down() | call get_online_cpus() | | call cpu_hotplug_begin() and stop here call arch_unregister_cpu() | call acpi_unmap_lsapic() | cpu's cpu_present is set | to false by set_cpu_present()| call put_online_cpus() | | start _cpu_up() | check cpu_present() and return -EINVAL return acpi_processor_remove() | continue hot-remove the cpu |
Quoted 2 lines
Signed-off-by Yasuaki Ishimatsu <[email protected]>
Please consider fixing the grammar issue below (since it is a user-visible print statement). Other than that, everything looks fine.
Quoted 14 lines
--- drivers/acpi/processor_driver.c | 14 ++++++++++++++ kernel/cpu.c | 8 +++++--- 2 files changed, 19 insertions(+), 3 deletions(-)Index:
linux-3.5-rc6/drivers/acpi/processor_driver.c
===================================================================drivers/acpi/processor_driver.c +1
-0@@ -850,8 +850,22 @@ static int acpi_processor_handle_eject(sreturn ret; } +get_online_cpus ();
drivers/acpi/processor_driver.c static int acpi_processor_handle_eject(s · line 863
Quoted 10 lines
drivers/acpi/processor_driver.c +10
-0+/* +* The cpu might become online again at this point. So we check whether +* the cpu has been onlined or not. If the cpu became online, it means +* that someone wants to use the cpu. So acpi_processor_handle_eject() +* returns -EAGAIN. +*/ +if (unlikely (cpu_online (pr->id))) { +put_online_cpus (); +printk (KERN_WARNING "Failed to remove CPU %d, " +"since someone onlines the cpu\n" , pr->id);
How about:
"Failed to remove CPU %d, because some other task brought the CPU back online\n"
Regards,
Srivatsa S. Bhat
Quoted 30 lines
drivers/acpi/processor_driver.c +3
-0+ return -EAGAIN; + }arch_unregister_cpu (pr->id);acpi_unmap_lsapic (pr->id); +put_online_cpus ();return ret; }#else Index:
linux-3.5-rc6/kernel/cpu.c
===================================================================kernel/cpu.c +5
-3@@ -343,11 +343,13 @@ static int __cpuinit _cpu_up(unsigned inunsigned long mod = tasks_frozen ?CPU_TASKS_FROZEN :0 ;struct task_struct *idle; -if (cpu_online (cpu) || !cpu_present (cpu)) -return -EINVAL ; -cpu_hotplug_begin (); +if (cpu_online (cpu) || !cpu_present (cpu)) { + ret = -EINVAL ; + goto out; + } + idle =idle_thread_get (cpu);if (IS_ERR (idle)) { ret =PTR_ERR (idle);
Re: [PATCH v3 2/3 RESEND] acpi : prevent cpu from becoming online
Quoted 63 lines · Srivatsa S. Bhat
Quoted 39 lines · Yasuaki Ishimatsu
Even if
acpi_processor_handle_eject()offlines cpu, there is a chance to online the cpu after that. So the patch closes the window by using get/put_online_cpus().Why does the patch change
_cpu_up()logic?The patch cares the race of hot-remove cpu and
_cpu_up(). If the patch does not change it, there is the following race.hot-remove cpu |
_cpu_up()
------------------------------------- ------------------------------------
callacpi_processor_handle_eject()|call cpu_down() | call get_online_cpus() | | call cpu_hotplug_begin() and stop here call arch_unregister_cpu() | call acpi_unmap_lsapic() | call put_online_cpus() | | start and continue _cpu_up() return acpi_processor_remove() |continue hot-remove the cpu |
So
_cpu_up()can continue to itself. And hot-remove cpu can also continue itself. If the patch changes_cpu_up()logic, the race disappears as below:hot-remove cpu |
_cpu_up()
-----------------------------------------------------------------------
callacpi_processor_handle_eject()|call cpu_down() | call get_online_cpus() | | call cpu_hotplug_begin() and stop here call arch_unregister_cpu() | call acpi_unmap_lsapic() | cpu's cpu_present is set | to false by set_cpu_present()| call put_online_cpus() | | start _cpu_up() | check cpu_present() and return -EINVAL return acpi_processor_remove() |Quoted 4 lines
continue hot-remove the cpu |
Signed-off-by Yasuaki Ishimatsu <[email protected]>Please consider fixing the grammar issue below (since it is a user-visible print statement). Other than that, everything looks fine.
Reviewed-by Srivatsa S. Bhat <[email protected]>Quoted 13 lines
--- drivers/acpi/processor_driver.c | 14 ++++++++++++++ kernel/cpu.c | 8 +++++--- 2 files changed, 19 insertions(+), 3 deletions(-)Index:
linux-3.5-rc6/drivers/acpi/processor_driver.c
===================================================================drivers/acpi/processor_driver.c +0
-0@@ -850,8 +850,22 @@ static int acpi_processor_handle_eject(sreturn ret; }
Quoted 14 lines
drivers/acpi/processor_driver.c static int acpi_processor_handle_eject(s · line 863
Quoted 11 lines
drivers/acpi/processor_driver.c +11
-0+get_online_cpus (); +/* +* The cpu might become online again at this point. So we check whether +* the cpu has been onlined or not. If the cpu became online, it means +* that someone wants to use the cpu. So acpi_processor_handle_eject() +* returns -EAGAIN. +*/ +if (unlikely (cpu_online (pr->id))) { +put_online_cpus (); +printk (KERN_WARNING "Failed to remove CPU %d, " +"since someone onlines the cpu\n" , pr->id);How about:
"Failed to remove CPU %d, because some other task brought the CPU back online\n"
Looks good to me. I'll update it.
Thanks,
Yasuaki Ishimatsu
Quoted 40 lines
Regards,
Srivatsa S. BhatQuoted 20 lines
drivers/acpi/processor_driver.c +3
-0+ return -EAGAIN; + }arch_unregister_cpu (pr->id);acpi_unmap_lsapic (pr->id); +put_online_cpus ();return ret; }#else Index:
linux-3.5-rc6/kernel/cpu.c
===================================================================kernel/cpu.c +0
-3@@ -343,11 +343,13 @@ static int __cpuinit _cpu_up(unsigned inunsigned long mod = tasks_frozen ?CPU_TASKS_FROZEN :0 ;struct task_struct *idle; -if (cpu_online (cpu) || !cpu_present (cpu)) -return -EINVAL ; -kernel/cpu.c static int __cpuinit _cpu_up(unsigned in · line 355
Quoted 10 lines
kernel/cpu.c +5
-0cpu_hotplug_begin (); +if (cpu_online (cpu) || !cpu_present (cpu)) { + ret = -EINVAL ; + goto out; + } + idle =idle_thread_get (cpu);if (IS_ERR (idle)) { ret =PTR_ERR (idle);--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 2/3 RESEND] acpi : prevent cpu from becoming online
In reply to Yasuaki IshimatsuQuoted 57 lines · Yasuaki Ishimatsu
Even if
acpi_processor_handle_eject()offlines cpu, there is a chance to online the cpu after that. So the patch closes the window by using get/put_online_cpus().Why does the patch change
_cpu_up()logic?The patch cares the race of hot-remove cpu and
_cpu_up(). If the patch does not change it, there is the following race.hot-remove cpu |
_cpu_up()
------------------------------------- ------------------------------------call acpi_processor_handle_eject() | call cpu_down() | call get_online_cpus() | | call cpu_hotplug_begin() and stop here call arch_unregister_cpu() | call acpi_unmap_lsapic() | call put_online_cpus() | | start and continue _cpu_up() return acpi_processor_remove() | continue hot-remove the cpu |So
_cpu_up()can continue to itself. And hot-remove cpu can also continue itself. If the patch changes_cpu_up()logic, the race disappears as below:hot-remove cpu |
_cpu_up()
-----------------------------------------------------------------------call acpi_processor_handle_eject() | call cpu_down() | call get_online_cpus() | | call cpu_hotplug_begin() and stop here call arch_unregister_cpu() | call acpi_unmap_lsapic() | cpu's cpu_present is set | to false by set_cpu_present()| call put_online_cpus() | | start _cpu_up() | check cpu_present() and return -EINVAL return acpi_processor_remove() | continue hot-remove the cpu |Signed-off-by Yasuaki Ishimatsu <[email protected]>--- drivers/acpi/processor_driver.c | 14 ++++++++++++++ kernel/cpu.c | 8 +++++--- 2 files changed, 19 insertions(+), 3 deletions(-)Index:
linux-3.5-rc6/drivers/acpi/processor_driver.c
===================================================================drivers/acpi/processor_driver.c +1
-0@@ -850,8 +850,22 @@ static int acpi_processor_handle_eject(sreturn ret; } +get_online_cpus ();
drivers/acpi/processor_driver.c static int acpi_processor_handle_eject(s · line 863
Quoted 10 lines
drivers/acpi/processor_driver.c +10
-0+/* +* The cpu might become online again at this point. So we check whether +* the cpu has been onlined or not. If the cpu became online, it means +* that someone wants to use the cpu. So acpi_processor_handle_eject() +* returns -EAGAIN. +*/ +if (unlikely (cpu_online (pr->id))) { +put_online_cpus (); +printk (KERN_WARNING "Failed to remove CPU %d, " +"since someone onlines the cpu\n" , pr->id);
pr_warn() should be used per the recent checkpatch change.
Thanks,
-Toshi
Quoted 30 lines
drivers/acpi/processor_driver.c +3
-0+ return -EAGAIN; + }arch_unregister_cpu (pr->id);acpi_unmap_lsapic (pr->id); +put_online_cpus ();return ret; }#else Index:
linux-3.5-rc6/kernel/cpu.c
===================================================================kernel/cpu.c +5
-3@@ -343,11 +343,13 @@ static int __cpuinit _cpu_up(unsigned inunsigned long mod = tasks_frozen ?CPU_TASKS_FROZEN :0 ;struct task_struct *idle; -if (cpu_online (cpu) || !cpu_present (cpu)) -return -EINVAL ; -cpu_hotplug_begin (); +if (cpu_online (cpu) || !cpu_present (cpu)) { + ret = -EINVAL ; + goto out; + } + idle =idle_thread_get (cpu);if (IS_ERR (idle)) { ret =PTR_ERR (idle);
Re: [PATCH v3 2/3 RESEND] acpi : prevent cpu from becoming online
Hi Toshi,
Quoted 57 lines · Toshi Kani
Quoted 56 lines · Yasuaki Ishimatsu
Even if
acpi_processor_handle_eject()offlines cpu, there is a chance to online the cpu after that. So the patch closes the window by using get/put_online_cpus().Why does the patch change
_cpu_up()logic?The patch cares the race of hot-remove cpu and
_cpu_up(). If the patch does not change it, there is the following race.hot-remove cpu |
_cpu_up()
------------------------------------- ------------------------------------
callacpi_processor_handle_eject()|call cpu_down() | call get_online_cpus() | | call cpu_hotplug_begin() and stop here call arch_unregister_cpu() | call acpi_unmap_lsapic() | call put_online_cpus() | | start and continue _cpu_up() return acpi_processor_remove() |continue hot-remove the cpu |
So
_cpu_up()can continue to itself. And hot-remove cpu can also continue itself. If the patch changes_cpu_up()logic, the race disappears as below:hot-remove cpu |
_cpu_up()
-----------------------------------------------------------------------
callacpi_processor_handle_eject()|call cpu_down() | call get_online_cpus() | | call cpu_hotplug_begin() and stop here call arch_unregister_cpu() | call acpi_unmap_lsapic() | cpu's cpu_present is set | to false by set_cpu_present()| call put_online_cpus() | | start _cpu_up() | check cpu_present() and return -EINVAL return acpi_processor_remove() |continue hot-remove the cpu |
Signed-off-by Yasuaki Ishimatsu <[email protected]>--- drivers/acpi/processor_driver.c | 14 ++++++++++++++ kernel/cpu.c | 8 +++++--- 2 files changed, 19 insertions(+), 3 deletions(-)Index:
linux-3.5-rc6/drivers/acpi/processor_driver.c
===================================================================drivers/acpi/processor_driver.c +0
-0@@ -850,8 +850,22 @@ static int acpi_processor_handle_eject(sreturn ret; }
Quoted 13 lines
drivers/acpi/processor_driver.c static int acpi_processor_handle_eject(s · line 863
Quoted 11 lines
drivers/acpi/processor_driver.c +11
-0+get_online_cpus (); +/* +* The cpu might become online again at this point. So we check whether +* the cpu has been onlined or not. If the cpu became online, it means +* that someone wants to use the cpu. So acpi_processor_handle_eject() +* returns -EAGAIN. +*/ +if (unlikely (cpu_online (pr->id))) { +put_online_cpus (); +printk (KERN_WARNING "Failed to remove CPU %d, " +"since someone onlines the cpu\n" , pr->id);
pr_warn()should be used per the recent checkpatch change.
O.K. I'll update it.
Thanks,
Yasuaki Ishimatsu
Quoted 40 lines
Thanks,
-ToshiQuoted 20 lines
drivers/acpi/processor_driver.c +3
-0+ return -EAGAIN; + }arch_unregister_cpu (pr->id);acpi_unmap_lsapic (pr->id); +put_online_cpus ();return ret; }#else Index:
linux-3.5-rc6/kernel/cpu.c
===================================================================kernel/cpu.c +0
-3@@ -343,11 +343,13 @@ static int __cpuinit _cpu_up(unsigned inunsigned long mod = tasks_frozen ?CPU_TASKS_FROZEN :0 ;struct task_struct *idle; -if (cpu_online (cpu) || !cpu_present (cpu)) -return -EINVAL ; -kernel/cpu.c static int __cpuinit _cpu_up(unsigned in · line 355
Quoted 10 lines
kernel/cpu.c +5
-0cpu_hotplug_begin (); +if (cpu_online (cpu) || !cpu_present (cpu)) { + ret = -EINVAL ; + goto out; + } + idle =idle_thread_get (cpu);if (IS_ERR (idle)) { ret =PTR_ERR (idle);--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH v3 3/3 acpi : acpi_bus_trim() stops removing devices when failing to remove the device
In reply to Yasuaki Ishimatsuacpi_bus_trim() stops removing devices, when acpi_bus_remove() return error number. But acpi_bus_remove() cannot return error number correctly. acpi_bus_remove() only return -EINVAL, when dev argument is NULL. Thus even if device cannot be removed correctly, acpi_bus_trim() ignores and continues to remove devices. acpi_bus_hot_remove_device() uses acpi_bus_trim() for removing devices. Therefore acpi_bus_hot_remove_device() can send "_EJ0" to firmware, even if the device is running on the system. In this case, the system cannot work well. So acpi_bus_trim() should check whether device was removed or not correctly. The patch adds error check into some functions to remove the device.
--- drivers/acpi/scan.c | 15 ++++++++++++--- drivers/base/dd.c | 22 +++++++++++++++++----- include/linux/device.h | 2 +- 3 files changed, 30 insertions(+), 9 deletions(-)
drivers/acpi/scan.c +12 -3
@@ -425,12 +425,17 @@ static int acpi_device_remove(struct dev {struct acpi_device *acpi_dev =to_acpi_device (dev);struct acpi_driver *acpi_drv = acpi_dev->driver; +int ret;if (acpi_drv) {if (acpi_drv->ops.notify)acpi_device_remove_notify_handler (acpi_dev); -if (acpi_drv->ops.remove) - acpi_drv->ops.remove (acpi_dev, acpi_dev->removal_type); +if (acpi_drv->ops.remove) { + ret = acpi_drv->ops.remove (acpi_dev, + acpi_dev->removal_type); +if (ret) +return ret; + } } acpi_dev->driver =NULL ; acpi_dev->driver_data =NULL ;
@@ -1208,11 +1213,15 @@ static int acpi_device_set_context(strucstatic int acpi_bus_remove (struct acpi_device *dev,int rmdevice) { +int ret; +if (!dev)return -EINVAL ; dev->removal_type =ACPI_BUS_REMOVAL_EJECT ; -device_release_driver (&dev->dev); + ret =device_release_driver (&dev->dev); +if (ret) +return ret;if (!rmdevice)return 0 ;
drivers/base/dd.c +17 -5
@@ -464,9 +464,10 @@ EXPORT_SYMBOL_GPL(driver_attach);* __device_release_driver() must be called with @dev lock held. * When called for a USB interface, @dev->parent lock must be held as well. */ -static void __device_release_driver (struct device *dev) +static int __device_release_driver (struct device *dev) {struct device_driver *drv; +int ret; drv = dev->driver;if (drv) {
@@ -482,9 +483,11 @@ static void __device_release_driver(strupm_runtime_put_sync (dev);if (dev->bus && dev->bus->remove) - dev->bus->remove (dev); + ret = dev->bus->remove (dev);else if (drv->remove) - drv->remove (dev); + ret = drv->remove (dev); +if (ret) + goto rollback;devres_release_all (dev); dev->driver =NULL ;klist_remove (&dev->p->knode_driver);
@@ -494,6 +497,12 @@ static void __device_release_driver(stru dev); } + +return ret; + +rollback: +driver_sysfs_add (dev); +return ret; }/**
@@ -503,16 +512,19 @@ static void __device_release_driver(stru* Manually detach device from driver. * When called for a USB interface, @dev->parent lock must be held. */ -void device_release_driver (struct device *dev) +int device_release_driver (struct device *dev) { +int ret;/* * If anyone calls device_release_driver() recursively from * within their ->remove callback for the same device, they * will deadlock right here. */ device_lock (dev); -__device_release_driver (dev); + ret =__device_release_driver (dev);device_unlock (dev); + +return ret; }EXPORT_SYMBOL_GPL (device_release_driver);
include/linux/device.h +1 -1
@@ -827,7 +827,7 @@ static inline void *dev_get_platdata(con* for information on use. */ extern int __must_check device_bind_driver (struct device *dev); -extern void device_release_driver (struct device *dev); +extern int device_release_driver (struct device *dev);extern int __must_check device_attach (struct device *dev);extern int __must_check driver_attach (struct device_driver *drv);extern int __must_check device_reprobe (struct device *dev);
Re: [PATCH v3 3/3] acpi : acpi_bus_trim() stops removing devices when failing to remove the device
Quoted 90 lines · Yasuaki Ishimatsu
acpi_bus_trim()stops removing devices, whenacpi_bus_remove()return error number. Butacpi_bus_remove()cannot return error number correctly.acpi_bus_remove()only return-EINVAL, when dev argument is NULL. Thus even if device cannot be removed correctly,acpi_bus_trim()ignores and continues to remove devices.acpi_bus_hot_remove_device()usesacpi_bus_trim()for removing devices. Thereforeacpi_bus_hot_remove_device()can send "_EJ0" to firmware, even if the device is running on the system. In this case, the system cannot work well. Soacpi_bus_trim()should check whether device was removed or not correctly. The patch adds error check into some functions to remove the device.Signed-off-by Yasuaki Ishimatsu <[email protected]>--- drivers/acpi/scan.c | 15 ++++++++++++--- drivers/base/dd.c | 22 +++++++++++++++++----- include/linux/device.h | 2 +- 3 files changed, 30 insertions(+), 9 deletions(-)Index:
linux-3.5-rc6/drivers/acpi/scan.c
===================================================================drivers/acpi/scan.c +12
-3@@ -425,12 +425,17 @@ static int acpi_device_remove(struct dev {struct acpi_device *acpi_dev =to_acpi_device (dev);struct acpi_driver *acpi_drv = acpi_dev->driver; +int ret;if (acpi_drv) {if (acpi_drv->ops.notify)acpi_device_remove_notify_handler (acpi_dev); -if (acpi_drv->ops.remove) - acpi_drv->ops.remove (acpi_dev, acpi_dev->removal_type); +if (acpi_drv->ops.remove) { + ret = acpi_drv->ops.remove (acpi_dev, + acpi_dev->removal_type); +if (ret) +return ret; + } } acpi_dev->driver =NULL ; acpi_dev->driver_data =NULL ;@@ -1208,11 +1213,15 @@ static int acpi_device_set_context(strucstatic int acpi_bus_remove (struct acpi_device *dev,int rmdevice) { +int ret; +if (!dev)return -EINVAL ; dev->removal_type =ACPI_BUS_REMOVAL_EJECT ; -device_release_driver (&dev->dev); + ret =device_release_driver (&dev->dev); +if (ret) +return ret;if (!rmdevice)return 0 ;Index:
linux-3.5-rc6/drivers/base/dd.c
===================================================================drivers/base/dd.c +6
-3@@ -464,9 +464,10 @@ EXPORT_SYMBOL_GPL(driver_attach);* __device_release_driver() must be called with @dev lock held. * When called for a USB interface, @dev->parent lock must be held as well. */ -static void __device_release_driver (struct device *dev) +static int __device_release_driver (struct device *dev) {struct device_driver *drv; +int ret; drv = dev->driver;if (drv) {@@ -482,9 +483,11 @@ static void __device_release_driver(strupm_runtime_put_sync (dev);if (dev->bus && dev->bus->remove) - dev->bus->remove (dev); + ret = dev->bus->remove (dev);else if (drv->remove) - drv->remove (dev); + ret = drv->remove (dev); +if (ret) + goto rollback;devres_release_all (dev); dev->driver =NULL ;klist_remove (&dev->p->knode_driver);
drivers/base/dd.c static void __device_release_driver(stru · line 501
Quoted 5 lines
drivers/base/dd.c +2
-0@@ -494,6 +497,12 @@ static void __device_release_driver(stru dev); } + +return ret;
ret is uninitialized when !drv.
drivers/base/dd.c static void __device_release_driver(stru · line 515
Quoted 13 lines
drivers/base/dd.c +5
-1+ +rollback: +driver_sysfs_add (dev); +return ret; }/** @@ -503,16 +512,19 @@ static void __device_release_driver(stru* Manually detach device from driver. * When called for a USB interface, @dev->parent lock must be held. */ -void device_release_driver (struct device *dev) +int device_release_driver (struct device *dev)
I agree with this change as driver's remove interface can fail. However, there are other callers to this function, which do not check the return value. I suppose there is no impact to the other paths since you only changed the CPU hotplug path to fail properly, but please confirm this is the case. I recommend documenting this change to the change log.
Thanks,
-Toshi
Quoted 30 lines
drivers/base/dd.c +4
-1{ +int ret;/* * If anyone calls device_release_driver() recursively from * within their ->remove callback for the same device, they * will deadlock right here. */ device_lock (dev); -__device_release_driver (dev); + ret =__device_release_driver (dev);device_unlock (dev); + +return ret; }EXPORT_SYMBOL_GPL (device_release_driver);Index:
linux-3.5-rc6/include/linux/device.h
===================================================================include/linux/device.h +1
-1@@ -827,7 +827,7 @@ static inline void *dev_get_platdata(con* for information on use. */ extern int __must_check device_bind_driver (struct device *dev); -extern void device_release_driver (struct device *dev); +extern int device_release_driver (struct device *dev);extern int __must_check device_attach (struct device *dev);extern int __must_check driver_attach (struct device_driver *drv);extern int __must_check device_reprobe (struct device *dev);
Re: [PATCH v3 3/3] acpi : acpi_bus_trim() stops removing devices when failing to remove the device
Quoted 93 lines · Toshi Kani
Quoted 92 lines · Yasuaki Ishimatsu
acpi_bus_trim()stops removing devices, whenacpi_bus_remove()return error number. Butacpi_bus_remove()cannot return error number correctly.acpi_bus_remove()only return-EINVAL, when dev argument is NULL. Thus even if device cannot be removed correctly,acpi_bus_trim()ignores and continues to remove devices.acpi_bus_hot_remove_device()usesacpi_bus_trim()for removing devices. Thereforeacpi_bus_hot_remove_device()can send "_EJ0" to firmware, even if the device is running on the system. In this case, the system cannot work well. Soacpi_bus_trim()should check whether device was removed or not correctly. The patch adds error check into some functions to remove the device.Signed-off-by Yasuaki Ishimatsu <[email protected]>--- drivers/acpi/scan.c | 15 ++++++++++++--- drivers/base/dd.c | 22 +++++++++++++++++----- include/linux/device.h | 2 +- 3 files changed, 30 insertions(+), 9 deletions(-)Index:
linux-3.5-rc6/drivers/acpi/scan.c
===================================================================drivers/acpi/scan.c +12
-3@@ -425,12 +425,17 @@ static int acpi_device_remove(struct dev {struct acpi_device *acpi_dev =to_acpi_device (dev);struct acpi_driver *acpi_drv = acpi_dev->driver; +int ret;if (acpi_drv) {if (acpi_drv->ops.notify)acpi_device_remove_notify_handler (acpi_dev); -if (acpi_drv->ops.remove) - acpi_drv->ops.remove (acpi_dev, acpi_dev->removal_type); +if (acpi_drv->ops.remove) { + ret = acpi_drv->ops.remove (acpi_dev, + acpi_dev->removal_type); +if (ret) +return ret; + } } acpi_dev->driver =NULL ; acpi_dev->driver_data =NULL ;@@ -1208,11 +1213,15 @@ static int acpi_device_set_context(strucstatic int acpi_bus_remove (struct acpi_device *dev,int rmdevice) { +int ret; +if (!dev)return -EINVAL ; dev->removal_type =ACPI_BUS_REMOVAL_EJECT ; -device_release_driver (&dev->dev); + ret =device_release_driver (&dev->dev); +if (ret) +return ret;if (!rmdevice)return 0 ;Index:
linux-3.5-rc6/drivers/base/dd.c
===================================================================drivers/base/dd.c +6
-3@@ -464,9 +464,10 @@ EXPORT_SYMBOL_GPL(driver_attach);* __device_release_driver() must be called with @dev lock held. * When called for a USB interface, @dev->parent lock must be held as well. */ -static void __device_release_driver (struct device *dev) +static int __device_release_driver (struct device *dev) {struct device_driver *drv; +int ret; drv = dev->driver;if (drv) {@@ -482,9 +483,11 @@ static void __device_release_driver(strupm_runtime_put_sync (dev);if (dev->bus && dev->bus->remove) - dev->bus->remove (dev); + ret = dev->bus->remove (dev);else if (drv->remove) - drv->remove (dev); + ret = drv->remove (dev); +if (ret) + goto rollback;devres_release_all (dev); dev->driver =NULL ;klist_remove (&dev->p->knode_driver);@@ -494,6 +497,12 @@ static void __device_release_driver(stru dev);
Quoted 5 lines
drivers/base/dd.c static void __device_release_driver(stru · line 501
Quoted 3 lines
drivers/base/dd.c +2
-0} + +return ret;ret is uninitialized when !drv.
Thanks! I'll update it.
Quoted 7 lines
Quoted 7 lines
drivers/base/dd.c +4
-0+ +rollback: +driver_sysfs_add (dev); +return ret; }
Quoted 14 lines
drivers/base/dd.c static void __device_release_driver(stru · line 515
Quoted 7 lines
drivers/base/dd.c +1
-1/** @@ -503,16 +512,19 @@ static void __device_release_driver(stru* Manually detach device from driver. * When called for a USB interface, @dev->parent lock must be held. */ -void device_release_driver (struct device *dev) +int device_release_driver (struct device *dev)I agree with this change as driver's remove interface can fail. However, there are other callers to this function, which do not check the return value. I suppose there is no impact to the other paths since you only changed the CPU hotplug path to fail properly, but please confirm this is the case. I recommend documenting this change to the change log.
Thank you for your agreement. As you know, there are other callers. I believe the patch does not impact to them, since all of them does not check return value of device_release_driver().
I will write it to the patch.
Thanks,
Yasuaki Ishimatsu
Quoted 41 lines
Thanks,
-ToshiQuoted 22 lines
drivers/base/dd.c +4
-1{ +int ret;/* * If anyone calls device_release_driver() recursively from * within their ->remove callback for the same device, they * will deadlock right here. */ device_lock (dev); -__device_release_driver (dev); + ret =__device_release_driver (dev);device_unlock (dev); + +return ret; }EXPORT_SYMBOL_GPL (device_release_driver);Index:
linux-3.5-rc6/include/linux/device.h
===================================================================include/linux/device.h static inline void *dev_get_platdata(con · line 833
Quoted 8 lines
include/linux/device.h +1
-1@@ -827,7 +827,7 @@ static inline void *dev_get_platdata(con* for information on use. */ extern int __must_check device_bind_driver (struct device *dev); -extern void device_release_driver (struct device *dev); +extern int device_release_driver (struct device *dev);extern int __must_check device_attach (struct device *dev);extern int __must_check driver_attach (struct device_driver *drv);extern int __must_check device_reprobe (struct device *dev);--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 3/3] acpi : acpi_bus_trim() stops removing devices when failing to remove the device
In reply to Yasuaki IshimatsuHi, ishimatsu:
At 07/12/2012 07:28 PM, Yasuaki Ishimatsu Wrote:
Quoted 9 lines
acpi_bus_trim()stops removing devices, whenacpi_bus_remove()return error number. Butacpi_bus_remove()cannot return error number correctly.acpi_bus_remove()only return-EINVAL, when dev argument is NULL. Thus even if device cannot be removed correctly,acpi_bus_trim()ignores and continues to remove devices.acpi_bus_hot_remove_device()usesacpi_bus_trim()for removing devices. Thereforeacpi_bus_hot_remove_device()can send "_EJ0" to firmware, even if the device is running on the system. In this case, the system cannot work well. Soacpi_bus_trim()should check whether device was removed or not correctly. The patch adds error check into some functions to remove the device.
What is the status about this patch?
Vasilis Liaskovitis found a similar bug about the memory hotplug, and this patch can fix this problem:
https://lkml.org/lkml/2012/9/26/318
Thanks
Wen Congyang
Quoted 135 lines
Signed-off-by Yasuaki Ishimatsu <[email protected]>--- drivers/acpi/scan.c | 15 ++++++++++++--- drivers/base/dd.c | 22 +++++++++++++++++----- include/linux/device.h | 2 +- 3 files changed, 30 insertions(+), 9 deletions(-)Index:
linux-3.5-rc6/drivers/acpi/scan.c
===================================================================drivers/acpi/scan.c +12
-3@@ -425,12 +425,17 @@ static int acpi_device_remove(struct dev {struct acpi_device *acpi_dev =to_acpi_device (dev);struct acpi_driver *acpi_drv = acpi_dev->driver; +int ret;if (acpi_drv) {if (acpi_drv->ops.notify)acpi_device_remove_notify_handler (acpi_dev); -if (acpi_drv->ops.remove) - acpi_drv->ops.remove (acpi_dev, acpi_dev->removal_type); +if (acpi_drv->ops.remove) { + ret = acpi_drv->ops.remove (acpi_dev, + acpi_dev->removal_type); +if (ret) +return ret; + } } acpi_dev->driver =NULL ; acpi_dev->driver_data =NULL ;@@ -1208,11 +1213,15 @@ static int acpi_device_set_context(strucstatic int acpi_bus_remove (struct acpi_device *dev,int rmdevice) { +int ret; +if (!dev)return -EINVAL ; dev->removal_type =ACPI_BUS_REMOVAL_EJECT ; -device_release_driver (&dev->dev); + ret =device_release_driver (&dev->dev); +if (ret) +return ret;if (!rmdevice)return 0 ;Index:
linux-3.5-rc6/drivers/base/dd.c
===================================================================drivers/base/dd.c +17
-5@@ -464,9 +464,10 @@ EXPORT_SYMBOL_GPL(driver_attach);* __device_release_driver() must be called with @dev lock held. * When called for a USB interface, @dev->parent lock must be held as well. */ -static void __device_release_driver (struct device *dev) +static int __device_release_driver (struct device *dev) {struct device_driver *drv; +int ret; drv = dev->driver;if (drv) {@@ -482,9 +483,11 @@ static void __device_release_driver(strupm_runtime_put_sync (dev);if (dev->bus && dev->bus->remove) - dev->bus->remove (dev); + ret = dev->bus->remove (dev);else if (drv->remove) - drv->remove (dev); + ret = drv->remove (dev); +if (ret) + goto rollback;devres_release_all (dev); dev->driver =NULL ;klist_remove (&dev->p->knode_driver);@@ -494,6 +497,12 @@ static void __device_release_driver(stru dev); } + +return ret; + +rollback: +driver_sysfs_add (dev); +return ret; }/** @@ -503,16 +512,19 @@ static void __device_release_driver(stru* Manually detach device from driver. * When called for a USB interface, @dev->parent lock must be held. */ -void device_release_driver (struct device *dev) +int device_release_driver (struct device *dev) { +int ret;/* * If anyone calls device_release_driver() recursively from * within their ->remove callback for the same device, they * will deadlock right here. */ device_lock (dev); -__device_release_driver (dev); + ret =__device_release_driver (dev);device_unlock (dev); + +return ret; }EXPORT_SYMBOL_GPL (device_release_driver);Index:
linux-3.5-rc6/include/linux/device.h
===================================================================include/linux/device.h +1
-2@@ -827,7 +827,7 @@ static inline void *dev_get_platdata(con* for information on use. */ extern int __must_check device_bind_driver (struct device *dev); -extern void device_release_driver (struct device *dev); +extern int device_release_driver (struct device *dev);extern int __must_check device_attach (struct device *dev);extern int __must_check driver_attach (struct device_driver *drv);extern int __must_check device_reprobe (struct device *dev); --To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v3 3/3] acpi : acpi_bus_trim() stops removing devices when failing to remove the device
Hi Wen,
Quoted 13 lines · Wen Congyang
Hi, ishimatsu:
At 07/12/2012 07:28 PM, Yasuaki Ishimatsu Wrote:
Quoted 9 lines
acpi_bus_trim()stops removing devices, whenacpi_bus_remove()return error number. Butacpi_bus_remove()cannot return error number correctly.acpi_bus_remove()only return-EINVAL, when dev argument is NULL. Thus even if device cannot be removed correctly,acpi_bus_trim()ignores and continues to remove devices.acpi_bus_hot_remove_device()usesacpi_bus_trim()for removing devices. Thereforeacpi_bus_hot_remove_device()can send "_EJ0" to firmware, even if the device is running on the system. In this case, the system cannot work well. Soacpi_bus_trim()should check whether device was removed or not correctly. The patch adds error check into some functions to remove the device.
Quoted 1 line
What is the status about this patch?
I need to update the description against Toshi's comment as follows:
"I agree with this change as driver's remove interface can fail. However, there are other callers to this function, which do not check the return value. I suppose there is no impact to the other paths since you only changed the CPU hotplug path to fail properly, but please confirm this is the case. I recommend documenting this change to the change log."
I have already checked that the patch does not impact the other path with the exception of CPU and Memory hotplug path. So I will adds the result of investigation and following Vasislis's problem into the patch and resend to lklml.
Quoted 3 lines
Vasilis Liaskovitis found a similar bug about the memory hotplug, and this patch can fix this problem:
https://lkml.org/lkml/2012/9/26/318
Thanks,
Yasuaki Ishimatsu
Quoted 139 lines
Thanks
Wen CongyangQuoted 135 lines
Signed-off-by Yasuaki Ishimatsu <[email protected]>--- drivers/acpi/scan.c | 15 ++++++++++++--- drivers/base/dd.c | 22 +++++++++++++++++----- include/linux/device.h | 2 +- 3 files changed, 30 insertions(+), 9 deletions(-)Index:
linux-3.5-rc6/drivers/acpi/scan.c
===================================================================drivers/acpi/scan.c +12
-3@@ -425,12 +425,17 @@ static int acpi_device_remove(struct dev {struct acpi_device *acpi_dev =to_acpi_device (dev);struct acpi_driver *acpi_drv = acpi_dev->driver; +int ret;if (acpi_drv) {if (acpi_drv->ops.notify)acpi_device_remove_notify_handler (acpi_dev); -if (acpi_drv->ops.remove) - acpi_drv->ops.remove (acpi_dev, acpi_dev->removal_type); +if (acpi_drv->ops.remove) { + ret = acpi_drv->ops.remove (acpi_dev, + acpi_dev->removal_type); +if (ret) +return ret; + } } acpi_dev->driver =NULL ; acpi_dev->driver_data =NULL ;@@ -1208,11 +1213,15 @@ static int acpi_device_set_context(strucstatic int acpi_bus_remove (struct acpi_device *dev,int rmdevice) { +int ret; +if (!dev)return -EINVAL ; dev->removal_type =ACPI_BUS_REMOVAL_EJECT ; -device_release_driver (&dev->dev); + ret =device_release_driver (&dev->dev); +if (ret) +return ret;if (!rmdevice)return 0 ;Index:
linux-3.5-rc6/drivers/base/dd.c
===================================================================drivers/base/dd.c +17
-5@@ -464,9 +464,10 @@ EXPORT_SYMBOL_GPL(driver_attach);* __device_release_driver() must be called with @dev lock held. * When called for a USB interface, @dev->parent lock must be held as well. */ -static void __device_release_driver (struct device *dev) +static int __device_release_driver (struct device *dev) {struct device_driver *drv; +int ret; drv = dev->driver;if (drv) {@@ -482,9 +483,11 @@ static void __device_release_driver(strupm_runtime_put_sync (dev);if (dev->bus && dev->bus->remove) - dev->bus->remove (dev); + ret = dev->bus->remove (dev);else if (drv->remove) - drv->remove (dev); + ret = drv->remove (dev); +if (ret) + goto rollback;devres_release_all (dev); dev->driver =NULL ;klist_remove (&dev->p->knode_driver);@@ -494,6 +497,12 @@ static void __device_release_driver(stru dev); } + +return ret; + +rollback: +driver_sysfs_add (dev); +return ret; }/** @@ -503,16 +512,19 @@ static void __device_release_driver(stru* Manually detach device from driver. * When called for a USB interface, @dev->parent lock must be held. */ -void device_release_driver (struct device *dev) +int device_release_driver (struct device *dev) { +int ret;/* * If anyone calls device_release_driver() recursively from * within their ->remove callback for the same device, they * will deadlock right here. */ device_lock (dev); -__device_release_driver (dev); + ret =__device_release_driver (dev);device_unlock (dev); + +return ret; }EXPORT_SYMBOL_GPL (device_release_driver);Index:
linux-3.5-rc6/include/linux/device.h
===================================================================include/linux/device.h +1
-2@@ -827,7 +827,7 @@ static inline void *dev_get_platdata(con* for information on use. */ extern int __must_check device_bind_driver (struct device *dev); -extern void device_release_driver (struct device *dev); +extern int device_release_driver (struct device *dev);extern int __must_check device_attach (struct device *dev);extern int __must_check driver_attach (struct device_driver *drv);extern int __must_check device_reprobe (struct device *dev); --To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Quoted 7 lines · Yasuaki Ishimatsu
Even if
cpu_down()fails,acpi_processor_remove()continues to remove the cpu. But in this case, it should return error number since some process may run on the cpu. If the cpu has a running process and the cpu is turned the power off, the system may not work well.Signed-off-by Yasuaki Ishimatsu <[email protected]>
Regards,
Srivatsa S. Bhat
Quoted 51 lines
--- drivers/acpi/processor_driver.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)Index:
linux-3.5-rc4/drivers/acpi/processor_driver.c
===================================================================drivers/acpi/processor_driver.c +12
-6@@ -610,7 +610,7 @@ err_free_pr:static int acpi_processor_remove (struct acpi_device *device,int type) {struct acpi_processor *pr =NULL ; - +int ret;if (!device || !acpi_driver_data (device))return -EINVAL ;@@ -621,8 +621,9 @@ static int acpi_processor_remove(struct goto free;if (type ==ACPI_BUS_REMOVAL_EJECT ) { -if (acpi_processor_handle_eject (pr)) -return -EINVAL ; + ret =acpi_processor_handle_eject (pr); +if (ret) +return ret; }acpi_processor_power_exit (pr, device);@@ -841,12 +842,17 @@ static acpi_status acpi_processor_hotaddstatic int acpi_processor_handle_eject (struct acpi_processor *pr) { -if (cpu_online (pr->id)) -cpu_down (pr->id); +int ret; + +if (cpu_online (pr->id)) { + ret =cpu_down (pr->id); +if (ret) +return ret; + }arch_unregister_cpu (pr->id);acpi_unmap_lsapic (pr->id); -return (0 ); +return ret; }#else static acpi_status acpi_processor_hotadd_init (struct acpi_processor *pr)
Hi Srivatsa,
Quoted 10 lines · Srivatsa S. Bhat
Quoted 7 lines · Yasuaki Ishimatsu
Even if
cpu_down()fails,acpi_processor_remove()continues to remove the cpu. But in this case, it should return error number since some process may run on the cpu. If the cpu has a running process and the cpu is turned the power off, the system may not work well.Signed-off-by Yasuaki Ishimatsu <[email protected]>Reviewed-by Srivatsa S. Bhat <[email protected]>
Thank you for reviewing.
Thanks,
Yasuaki Ishimatsu
Quoted 60 lines
Regards,
Srivatsa S. BhatQuoted 41 lines
--- drivers/acpi/processor_driver.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)Index:
linux-3.5-rc4/drivers/acpi/processor_driver.c
===================================================================drivers/acpi/processor_driver.c +9
-5@@ -610,7 +610,7 @@ err_free_pr:static int acpi_processor_remove (struct acpi_device *device,int type) {struct acpi_processor *pr =NULL ; - +int ret;if (!device || !acpi_driver_data (device))return -EINVAL ;@@ -621,8 +621,9 @@ static int acpi_processor_remove(struct goto free;if (type ==ACPI_BUS_REMOVAL_EJECT ) { -if (acpi_processor_handle_eject (pr)) -return -EINVAL ; + ret =acpi_processor_handle_eject (pr); +if (ret) +return ret; }acpi_processor_power_exit (pr, device);@@ -841,12 +842,17 @@ static acpi_status acpi_processor_hotaddstatic int acpi_processor_handle_eject (struct acpi_processor *pr) { -if (cpu_online (pr->id)) -cpu_down (pr->id); +int ret; + +if (cpu_online (pr->id)) { + ret =cpu_down (pr->id); +if (ret)drivers/acpi/processor_driver.c static acpi_status acpi_processor_hotadd · line 858
Quoted 10 lines
drivers/acpi/processor_driver.c +3
-1+ return ret; + }arch_unregister_cpu (pr->id);acpi_unmap_lsapic (pr->id); - return (0); +return ret; }#else static acpi_status acpi_processor_hotadd_init (struct acpi_processor *pr)--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 44 lines · Yasuaki Ishimatsu
Even if
cpu_down()fails,acpi_processor_remove()continues to remove the cpu. But in this case, it should return error number since some process may run on the cpu. If the cpu has a running process and the cpu is turned the power off, the system may not work well.Signed-off-by Yasuaki Ishimatsu <[email protected]>--- drivers/acpi/processor_driver.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)Index:
linux-3.5-rc4/drivers/acpi/processor_driver.c
===================================================================drivers/acpi/processor_driver.c +6
-5@@ -610,7 +610,7 @@ err_free_pr:static int acpi_processor_remove (struct acpi_device *device,int type) {struct acpi_processor *pr =NULL ; - +int ret;if (!device || !acpi_driver_data (device))return -EINVAL ;@@ -621,8 +621,9 @@ static int acpi_processor_remove(struct goto free;if (type ==ACPI_BUS_REMOVAL_EJECT ) { -if (acpi_processor_handle_eject (pr)) -return -EINVAL ; + ret =acpi_processor_handle_eject (pr); +if (ret) +return ret; }acpi_processor_power_exit (pr, device);@@ -841,12 +842,17 @@ static acpi_status acpi_processor_hotaddstatic int acpi_processor_handle_eject (struct acpi_processor *pr) { -if (cpu_online (pr->id)) -cpu_down (pr->id); +int ret; +
drivers/acpi/processor_driver.c static acpi_status acpi_processor_hotadd · line 855
Quoted 10 lines
drivers/acpi/processor_driver.c +6
-1+if (cpu_online (pr->id)) { + ret =cpu_down (pr->id); +if (ret) +return ret; + }arch_unregister_cpu (pr->id);acpi_unmap_lsapic (pr->id); -return (0 ); +return ret;
ret is uninitialized when !cpu_online().
Thanks,
-Toshi
Quoted 8 lines
drivers/acpi/processor_driver.c +0
-1}#else static acpi_status acpi_processor_hotadd_init (struct acpi_processor *pr) --To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi Toshi,
Quoted 51 lines · Toshi Kani
Quoted 50 lines · Yasuaki Ishimatsu
Even if
cpu_down()fails,acpi_processor_remove()continues to remove the cpu. But in this case, it should return error number since some process may run on the cpu. If the cpu has a running process and the cpu is turned the power off, the system may not work well.Signed-off-by Yasuaki Ishimatsu <[email protected]>--- drivers/acpi/processor_driver.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)Index:
linux-3.5-rc4/drivers/acpi/processor_driver.c
===================================================================drivers/acpi/processor_driver.c +11
-5@@ -610,7 +610,7 @@ err_free_pr:static int acpi_processor_remove (struct acpi_device *device,int type) {struct acpi_processor *pr =NULL ; - +int ret;if (!device || !acpi_driver_data (device))return -EINVAL ;@@ -621,8 +621,9 @@ static int acpi_processor_remove(struct goto free;if (type ==ACPI_BUS_REMOVAL_EJECT ) { -if (acpi_processor_handle_eject (pr)) -return -EINVAL ; + ret =acpi_processor_handle_eject (pr); +if (ret) +return ret; }acpi_processor_power_exit (pr, device);@@ -841,12 +842,17 @@ static acpi_status acpi_processor_hotaddstatic int acpi_processor_handle_eject (struct acpi_processor *pr) { -if (cpu_online (pr->id)) -cpu_down (pr->id); +int ret; + +if (cpu_online (pr->id)) { + ret =cpu_down (pr->id); +if (ret) +return ret; + }
Quoted 6 lines
drivers/acpi/processor_driver.c static acpi_status acpi_processor_hotadd · line 855
Quoted 4 lines
drivers/acpi/processor_driver.c +1
-1arch_unregister_cpu (pr->id);acpi_unmap_lsapic (pr->id); -return (0 ); +return ret;ret is uninitialized when !cpu_online().
Oops! I'll update it.
Thanks,
Yasuaki Ishimatsu
Quoted 18 lines
Thanks,
-ToshiQuoted 8 lines
drivers/acpi/processor_driver.c +0
-1}#else static acpi_status acpi_processor_hotadd_init (struct acpi_processor *pr) --To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html