Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1624101 > unrolled thread

[patch 19/20] ACPI/processor: Use cpu_hotplug_disable() instead of get_online_cpus()

Started byThomas Gleixner <tglx@linutronix.de>
First post2017-04-15 19:40 +0200
Last post2017-04-17 01:00 +0200
Articles 2 — 2 participants

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  [patch 19/20] ACPI/processor: Use cpu_hotplug_disable() instead of  get_online_cpus() Thomas Gleixner <tglx@linutronix.de> - 2017-04-15 19:40 +0200
    Re: [patch 19/20] ACPI/processor: Use cpu_hotplug_disable() instead of get_online_cpus() "Rafael J. Wysocki" <rjw@rjwysocki.net> - 2017-04-17 01:00 +0200

#1624101 — [patch 19/20] ACPI/processor: Use cpu_hotplug_disable() instead of get_online_cpus()

FromThomas Gleixner <tglx@linutronix.de>
Date2017-04-15 19:40 +0200
Subject[patch 19/20] ACPI/processor: Use cpu_hotplug_disable() instead of get_online_cpus()
Message-ID<twzPX-123-5@gated-at.bofh.it>
Converting the hotplug locking, i.e. get_online_cpus(), to a percpu rwsem
unearthed a circular lock dependency which was hidden from lockdep due to
the lockdep annotation of get_online_cpus() which prevents lockdep from
creating full dependency chains.

CPU0                    CPU1
----                    ----
lock((&wfc.work));
                         lock(cpu_hotplug_lock.rw_sem);
                         lock((&wfc.work));
lock(cpu_hotplug_lock.rw_sem);

This dependency is established via acpi_processor_start() which calls into
the work queue code. And the work queue code establishes the reverse
dependency.

This is not a problem of get_online_cpus() recursion, it's a possible
deadlock undetected by lockdep so far.

The cure is to use cpu_hotplug_disable() instead of get_online_cpus() to
protect the probing from acpi_processor_start().

There is a side effect to this: cpu_hotplug_disable() makes a concurrent
cpu hotplug attempt via the sysfs interfaces fail with -EBUSY, but that
probing usually happens during the boot process where no interaction is
possible. Any later invocations are infrequent enough and concurrent
hotplug attempts are so unlikely that the danger of user space visible
regressions is very close to zero. Anyway, thats preferrable over a real
deadlock.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Len Brown <lenb@kernel.org>
Cc: linux-acpi@vger.kernel.org
---
 drivers/acpi/processor_driver.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/drivers/acpi/processor_driver.c
+++ b/drivers/acpi/processor_driver.c
@@ -268,9 +268,9 @@ static int acpi_processor_start(struct d
 		return -ENODEV;
 
 	/* Protect against concurrent CPU hotplug operations */
-	get_online_cpus();
+	cpu_hotplug_disable();
 	ret = __acpi_processor_start(device);
-	put_online_cpus();
+	cpu_hotplug_enable();
 	return ret;
 }
 

[toc] | [next] | [standalone]


#1624482 — Re: [patch 19/20] ACPI/processor: Use cpu_hotplug_disable() instead of get_online_cpus()

From"Rafael J. Wysocki" <rjw@rjwysocki.net>
Date2017-04-17 01:00 +0200
SubjectRe: [patch 19/20] ACPI/processor: Use cpu_hotplug_disable() instead of get_online_cpus()
Message-ID<tx1jb-12F-1@gated-at.bofh.it>
In reply to#1624101
On Saturday, April 15, 2017 07:01:26 PM Thomas Gleixner wrote:
> Converting the hotplug locking, i.e. get_online_cpus(), to a percpu rwsem
> unearthed a circular lock dependency which was hidden from lockdep due to
> the lockdep annotation of get_online_cpus() which prevents lockdep from
> creating full dependency chains.
> 
> CPU0                    CPU1
> ----                    ----
> lock((&wfc.work));
>                          lock(cpu_hotplug_lock.rw_sem);
>                          lock((&wfc.work));
> lock(cpu_hotplug_lock.rw_sem);
> 
> This dependency is established via acpi_processor_start() which calls into
> the work queue code. And the work queue code establishes the reverse
> dependency.
> 
> This is not a problem of get_online_cpus() recursion, it's a possible
> deadlock undetected by lockdep so far.
> 
> The cure is to use cpu_hotplug_disable() instead of get_online_cpus() to
> protect the probing from acpi_processor_start().
> 
> There is a side effect to this: cpu_hotplug_disable() makes a concurrent
> cpu hotplug attempt via the sysfs interfaces fail with -EBUSY, but that
> probing usually happens during the boot process where no interaction is
> possible. Any later invocations are infrequent enough and concurrent
> hotplug attempts are so unlikely that the danger of user space visible
> regressions is very close to zero. Anyway, thats preferrable over a real
> deadlock.
> 
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
> Cc: Len Brown <lenb@kernel.org>
> Cc: linux-acpi@vger.kernel.org

Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

> ---
>  drivers/acpi/processor_driver.c |    4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> --- a/drivers/acpi/processor_driver.c
> +++ b/drivers/acpi/processor_driver.c
> @@ -268,9 +268,9 @@ static int acpi_processor_start(struct d
>  		return -ENODEV;
>  
>  	/* Protect against concurrent CPU hotplug operations */
> -	get_online_cpus();
> +	cpu_hotplug_disable();
>  	ret = __acpi_processor_start(device);
> -	put_online_cpus();
> +	cpu_hotplug_enable();
>  	return ret;
>  }
>  
> 
> 

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web