]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.11-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 14 Nov 2013 08:40:48 +0000 (17:40 +0900)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 14 Nov 2013 08:40:48 +0000 (17:40 +0900)
added patches:
thermal-x86_pkg_temp-change-spin-lock.patch

queue-3.11/series
queue-3.11/thermal-x86_pkg_temp-change-spin-lock.patch [new file with mode: 0644]

index 3753d5abd1137702f9eb92c90154885aaba58961..22eedc7ed199846fc2f0afd140fb0b039a094985 100644 (file)
@@ -9,3 +9,4 @@ ipv6-ip6_dst_check-needs-to-check-for-expired-dst_entries.patch
 ipv6-reset-dst.expires-value-when-clearing-expire-flag.patch
 xen-netback-handle-backend-state-transitions-in-a-more-robust-way.patch
 xen-netback-transition-to-closed-when-removing-a-vif.patch
+thermal-x86_pkg_temp-change-spin-lock.patch
diff --git a/queue-3.11/thermal-x86_pkg_temp-change-spin-lock.patch b/queue-3.11/thermal-x86_pkg_temp-change-spin-lock.patch
new file mode 100644 (file)
index 0000000..ad93885
--- /dev/null
@@ -0,0 +1,87 @@
+From 7bed1b3caaedd5918f0820b29f3b7a2ddc812922 Mon Sep 17 00:00:00 2001
+From: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+Date: Tue, 24 Sep 2013 11:05:16 -0700
+Subject: Thermal: x86_pkg_temp: change spin lock
+
+From: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+
+commit 7bed1b3caaedd5918f0820b29f3b7a2ddc812922 upstream.
+
+x86_pkg_temp receives thermal notifications via a callback from a
+therm_throt driver, where thermal interrupts are processed.
+This callback is pkg_temp_thermal_platform_thermal_notify. Here to
+avoid multiple interrupts from cores in a package, we disable the
+source and also set a variable to avoid scheduling delayed work function.
+This variable is protected via spin_lock_irqsave. On one buggy platform,
+we still receiving interrupts even if the source is disabled. This
+can cause deadlock/lockdep warning, when interrupt is generated while under
+spinlock in work function.
+Change spin_lock to spin_lock_irqsave and spin_unlock to
+spin_unlock_irqrestore as the data it is trying to protect can also
+be modified in a notification call called from interrupt handler.
+
+Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Cc: Jonghwan Choi <jhbird.choi@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/thermal/x86_pkg_temp_thermal.c |   14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+--- a/drivers/thermal/x86_pkg_temp_thermal.c
++++ b/drivers/thermal/x86_pkg_temp_thermal.c
+@@ -316,18 +316,19 @@ static void pkg_temp_thermal_threshold_w
+       int phy_id = topology_physical_package_id(cpu);
+       struct phy_dev_entry *phdev = pkg_temp_thermal_get_phy_entry(cpu);
+       bool notify = false;
++      unsigned long flags;
+       if (!phdev)
+               return;
+-      spin_lock(&pkg_work_lock);
++      spin_lock_irqsave(&pkg_work_lock, flags);
+       ++pkg_work_cnt;
+       if (unlikely(phy_id > max_phy_id)) {
+-              spin_unlock(&pkg_work_lock);
++              spin_unlock_irqrestore(&pkg_work_lock, flags);
+               return;
+       }
+       pkg_work_scheduled[phy_id] = 0;
+-      spin_unlock(&pkg_work_lock);
++      spin_unlock_irqrestore(&pkg_work_lock, flags);
+       enable_pkg_thres_interrupt();
+       rdmsrl(MSR_IA32_PACKAGE_THERM_STATUS, msr_val);
+@@ -397,6 +398,7 @@ static int pkg_temp_thermal_device_add(u
+       int thres_count;
+       u32 eax, ebx, ecx, edx;
+       u8 *temp;
++      unsigned long flags;
+       cpuid(6, &eax, &ebx, &ecx, &edx);
+       thres_count = ebx & 0x07;
+@@ -420,19 +422,19 @@ static int pkg_temp_thermal_device_add(u
+               goto err_ret_unlock;
+       }
+-      spin_lock(&pkg_work_lock);
++      spin_lock_irqsave(&pkg_work_lock, flags);
+       if (topology_physical_package_id(cpu) > max_phy_id)
+               max_phy_id = topology_physical_package_id(cpu);
+       temp = krealloc(pkg_work_scheduled,
+                       (max_phy_id+1) * sizeof(u8), GFP_ATOMIC);
+       if (!temp) {
+-              spin_unlock(&pkg_work_lock);
++              spin_unlock_irqrestore(&pkg_work_lock, flags);
+               err = -ENOMEM;
+               goto err_ret_free;
+       }
+       pkg_work_scheduled = temp;
+       pkg_work_scheduled[topology_physical_package_id(cpu)] = 0;
+-      spin_unlock(&pkg_work_lock);
++      spin_unlock_irqrestore(&pkg_work_lock, flags);
+       phy_dev_entry->phys_proc_id = topology_physical_package_id(cpu);
+       phy_dev_entry->first_cpu = cpu;