aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@novell.com>2010-09-13 06:11:05 -0400
committerGuenter Roeck <guenter.roeck@ericsson.com>2010-09-24 14:44:18 -0400
commitd9bca4358286584cc22f4261ee3a60cad01aa4d4 (patch)
treef18ecad6c5d1983d6c4b33544e405fb9680f000c
parent89a3fd35ba0318a7208e2c8d8ca6189f567d4a93 (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>
-rw-r--r--drivers/hwmon/pkgtemp.c7
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
340static void pkgtemp_device_remove(unsigned int cpu) 340static 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}