From: Greg Kroah-Hartman Date: Thu, 14 Nov 2013 08:40:48 +0000 (+0900) Subject: 3.11-stable patches X-Git-Tag: v3.4.70~24 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6d667e955522fe4bda9465dd61868c6cbb438fb2;p=thirdparty%2Fkernel%2Fstable-queue.git 3.11-stable patches added patches: thermal-x86_pkg_temp-change-spin-lock.patch --- diff --git a/queue-3.11/series b/queue-3.11/series index 3753d5abd11..22eedc7ed19 100644 --- a/queue-3.11/series +++ b/queue-3.11/series @@ -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 index 00000000000..ad93885b3fd --- /dev/null +++ b/queue-3.11/thermal-x86_pkg_temp-change-spin-lock.patch @@ -0,0 +1,87 @@ +From 7bed1b3caaedd5918f0820b29f3b7a2ddc812922 Mon Sep 17 00:00:00 2001 +From: Srinivas Pandruvada +Date: Tue, 24 Sep 2013 11:05:16 -0700 +Subject: Thermal: x86_pkg_temp: change spin lock + +From: Srinivas Pandruvada + +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 +Signed-off-by: Zhang Rui +Cc: Jonghwan Choi +Signed-off-by: Greg Kroah-Hartman + +--- + 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;