summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBharat Nihalani <bnihalani@nvidia.com>2010-07-28 19:32:21 +0530
committerGary King <gking@nvidia.com>2010-07-28 10:02:56 -0700
commitfdc51b5f2f7952f3ee1674bc4e29a7712c88f068 (patch)
tree95b9e5c88a6d323d67225c950e9e7a048c9469b7
parentd484b7d51e9fd73edd63c8b9cc80343d687d40fa (diff)
mutex: Don't spin when the owner CPU is offline or other weird cases
Due to recent load-balancer changes that delay the task migration to the next wakeup, the adaptive mutex spinning ends up in a live lock when the owner's CPU gets offlined because the cpu_online() check lives before the owner running check. This patch changes mutex_spin_on_owner() to return 0 (don't spin) in any case where we aren't sure about the owner struct validity or CPU number, and if the said CPU is offline. There is no point going back & re-evaluate spinning in corner cases like that, let's just go to sleep. Cherry-picked commit: 4b402210486c6414fe5fbfd85934a0a22da56b04 URL: http://android.git.kernel.org/?p=kernel/linux-2.6.git;a=summary Kernel version picked from: v2.6.34 Re-enable HAVE_DEFAULT_NO_SPIN_MUTEXES as root-cause of spin-lock is now fixed in sched.c For bug 713808 Change-Id: I06a7c85aa46be3cdd27da0a4e62ffa442a9805b4 Reviewed-on: http://git-master/r/4500 Tested-by: Bharat Nihalani <bnihalani@nvidia.com> Reviewed-by: Gary King <gking@nvidia.com>
-rw-r--r--arch/arm/Kconfig1
-rw-r--r--kernel/sched.c8
2 files changed, 4 insertions, 5 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 3625af25ca56..3ffb8571140f 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -12,7 +12,6 @@ config ARM
select HAVE_IDE
select RTC_LIB
select SYS_SUPPORTS_APM_EMULATION
- select HAVE_DEFAULT_NO_SPIN_MUTEXES
select HAVE_OPROFILE
select HAVE_ARCH_KGDB
select HAVE_KPROBES if (!XIP_KERNEL)
diff --git a/kernel/sched.c b/kernel/sched.c
index f297f4c2be50..8bd6bf6d4f2c 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -5519,7 +5519,7 @@ int mutex_spin_on_owner(struct mutex *lock, struct thread_info *owner)
* the mutex owner just released it and exited.
*/
if (probe_kernel_address(&owner->cpu, cpu))
- goto out;
+ return 0;
#else
cpu = owner->cpu;
#endif
@@ -5529,14 +5529,14 @@ int mutex_spin_on_owner(struct mutex *lock, struct thread_info *owner)
* the cpu field may no longer be valid.
*/
if (cpu >= nr_cpumask_bits)
- goto out;
+ return 0;
/*
* We need to validate that we can do a
* get_cpu() and that we have the percpu area.
*/
if (!cpu_online(cpu))
- goto out;
+ return 0;
rq = cpu_rq(cpu);
@@ -5555,7 +5555,7 @@ int mutex_spin_on_owner(struct mutex *lock, struct thread_info *owner)
cpu_relax();
}
-out:
+
return 1;
}
#endif