diff options
author | Bharat Nihalani <bnihalani@nvidia.com> | 2010-07-28 19:32:21 +0530 |
---|---|---|
committer | Gary King <gking@nvidia.com> | 2010-07-28 10:02:56 -0700 |
commit | fdc51b5f2f7952f3ee1674bc4e29a7712c88f068 (patch) | |
tree | 95b9e5c88a6d323d67225c950e9e7a048c9469b7 /kernel | |
parent | d484b7d51e9fd73edd63c8b9cc80343d687d40fa (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>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/sched.c | 8 |
1 files changed, 4 insertions, 4 deletions
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 |