diff options
author | Jan Beulich <jbeulich@novell.com> | 2010-09-13 06:11:05 -0400 |
---|---|---|
committer | Guenter Roeck <guenter.roeck@ericsson.com> | 2010-09-24 14:44:18 -0400 |
commit | d9bca4358286584cc22f4261ee3a60cad01aa4d4 (patch) | |
tree | f18ecad6c5d1983d6c4b33544e405fb9680f000c /drivers/hwmon | |
parent | 89a3fd35ba0318a7208e2c8d8ca6189f567d4a93 (diff) |
x86/hwmon: avoid deadlock on CPU removal in pkgtemp
pkgtemp_device_remove(), holding the list protecting mutex, calls
pkgtemp_device_add(), which itself wants to acquire the same mutex.
Holding the mutex over the entire loop body in pkgtemp_device_remove()
isn't really necessary, as long as the loop gets exited after
processing the matched CPU.
Once exiting the loop after removing an eventual match, there's no
need for using the "safe" list iterator anymore.
Signed-off-by: Jan Beulich <jbeulich@novell.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Signed-off-by: Guenter Roeck <guenter.roeck@ericsson.com>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r-- | drivers/hwmon/pkgtemp.c | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/drivers/hwmon/pkgtemp.c b/drivers/hwmon/pkgtemp.c index 74157fcda6ed..844957333fe5 100644 --- a/drivers/hwmon/pkgtemp.c +++ b/drivers/hwmon/pkgtemp.c | |||
@@ -339,17 +339,18 @@ exit: | |||
339 | #ifdef CONFIG_HOTPLUG_CPU | 339 | #ifdef CONFIG_HOTPLUG_CPU |
340 | static void pkgtemp_device_remove(unsigned int cpu) | 340 | static void pkgtemp_device_remove(unsigned int cpu) |
341 | { | 341 | { |
342 | struct pdev_entry *p, *n; | 342 | struct pdev_entry *p; |
343 | unsigned int i; | 343 | unsigned int i; |
344 | int err; | 344 | int err; |
345 | 345 | ||
346 | mutex_lock(&pdev_list_mutex); | 346 | mutex_lock(&pdev_list_mutex); |
347 | list_for_each_entry_safe(p, n, &pdev_list, list) { | 347 | list_for_each_entry(p, &pdev_list, list) { |
348 | if (p->cpu != cpu) | 348 | if (p->cpu != cpu) |
349 | continue; | 349 | continue; |
350 | 350 | ||
351 | platform_device_unregister(p->pdev); | 351 | platform_device_unregister(p->pdev); |
352 | list_del(&p->list); | 352 | list_del(&p->list); |
353 | mutex_unlock(&pdev_list_mutex); | ||
353 | kfree(p); | 354 | kfree(p); |
354 | for_each_cpu(i, cpu_core_mask(cpu)) { | 355 | for_each_cpu(i, cpu_core_mask(cpu)) { |
355 | if (i != cpu) { | 356 | if (i != cpu) { |
@@ -358,7 +359,7 @@ static void pkgtemp_device_remove(unsigned int cpu) | |||
358 | break; | 359 | break; |
359 | } | 360 | } |
360 | } | 361 | } |
361 | break; | 362 | return; |
362 | } | 363 | } |
363 | mutex_unlock(&pdev_list_mutex); | 364 | mutex_unlock(&pdev_list_mutex); |
364 | } | 365 | } |