From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
stable@vger.kernel.org, Michael Bohan <mbohan@codeaurora.org>,
Thomas Gleixner <tglx@linutronix.de>
Subject: [ 01/23] hrtimer: Dont reinitialize a cpu_base lock on CPU_UP
Date: Tue, 23 Apr 2013 14:56:08 -0700 [thread overview]
Message-ID: <20130423215456.456015128@linuxfoundation.org> (raw)
In-Reply-To: <20130423215456.307216898@linuxfoundation.org>
3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Bohan <mbohan@codeaurora.org>
commit 84cc8fd2fe65866e49d70b38b3fdf7219dd92fe0 upstream.
The current code makes the assumption that a cpu_base lock won't be
held if the CPU corresponding to that cpu_base is offline, which isn't
always true.
If a hrtimer is not queued, then it will not be migrated by
migrate_hrtimers() when a CPU is offlined. Therefore, the hrtimer's
cpu_base may still point to a CPU which has subsequently gone offline
if the timer wasn't enqueued at the time the CPU went down.
Normally this wouldn't be a problem, but a cpu_base's lock is blindly
reinitialized each time a CPU is brought up. If a CPU is brought
online during the period that another thread is performing a hrtimer
operation on a stale hrtimer, then the lock will be reinitialized
under its feet, and a SPIN_BUG() like the following will be observed:
<0>[ 28.082085] BUG: spinlock already unlocked on CPU#0, swapper/0/0
<0>[ 28.087078] lock: 0xc4780b40, value 0x0 .magic: dead4ead, .owner: <none>/-1, .owner_cpu: -1
<4>[ 42.451150] [<c0014398>] (unwind_backtrace+0x0/0x120) from [<c0269220>] (do_raw_spin_unlock+0x44/0xdc)
<4>[ 42.460430] [<c0269220>] (do_raw_spin_unlock+0x44/0xdc) from [<c071b5bc>] (_raw_spin_unlock+0x8/0x30)
<4>[ 42.469632] [<c071b5bc>] (_raw_spin_unlock+0x8/0x30) from [<c00a9ce0>] (__hrtimer_start_range_ns+0x1e4/0x4f8)
<4>[ 42.479521] [<c00a9ce0>] (__hrtimer_start_range_ns+0x1e4/0x4f8) from [<c00aa014>] (hrtimer_start+0x20/0x28)
<4>[ 42.489247] [<c00aa014>] (hrtimer_start+0x20/0x28) from [<c00e6190>] (rcu_idle_enter_common+0x1ac/0x320)
<4>[ 42.498709] [<c00e6190>] (rcu_idle_enter_common+0x1ac/0x320) from [<c00e6440>] (rcu_idle_enter+0xa0/0xb8)
<4>[ 42.508259] [<c00e6440>] (rcu_idle_enter+0xa0/0xb8) from [<c000f268>] (cpu_idle+0x24/0xf0)
<4>[ 42.516503] [<c000f268>] (cpu_idle+0x24/0xf0) from [<c06ed3c0>] (rest_init+0x88/0xa0)
<4>[ 42.524319] [<c06ed3c0>] (rest_init+0x88/0xa0) from [<c0c00978>] (start_kernel+0x3d0/0x434)
As an example, this particular crash occurred when hrtimer_start() was
executed on CPU #0. The code locked the hrtimer's current cpu_base
corresponding to CPU #1. CPU #0 then tried to switch the hrtimer's
cpu_base to an optimal CPU which was online. In this case, it selected
the cpu_base corresponding to CPU #3.
Before it could proceed, CPU #1 came online and reinitialized the
spinlock corresponding to its cpu_base. Thus now CPU #0 held a lock
which was reinitialized. When CPU #0 finally ended up unlocking the
old cpu_base corresponding to CPU #1 so that it could switch to CPU
#3, we hit this SPIN_BUG() above while in switch_hrtimer_base().
CPU #0 CPU #1
---- ----
... <offline>
hrtimer_start()
lock_hrtimer_base(base #1)
... init_hrtimers_cpu()
switch_hrtimer_base() ...
... raw_spin_lock_init(&cpu_base->lock)
raw_spin_unlock(&cpu_base->lock) ...
<spin_bug>
Solve this by statically initializing the lock.
Signed-off-by: Michael Bohan <mbohan@codeaurora.org>
Link: http://lkml.kernel.org/r/1363745965-23475-1-git-send-email-mbohan@codeaurora.org
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/hrtimer.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -61,6 +61,7 @@
DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) =
{
+ .lock = __RAW_SPIN_LOCK_UNLOCKED(hrtimer_bases.lock),
.clock_base =
{
{
@@ -1640,8 +1641,6 @@ static void __cpuinit init_hrtimers_cpu(
struct hrtimer_cpu_base *cpu_base = &per_cpu(hrtimer_bases, cpu);
int i;
- raw_spin_lock_init(&cpu_base->lock);
-
for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) {
cpu_base->clock_base[i].cpu_base = cpu_base;
timerqueue_init_head(&cpu_base->clock_base[i].active);
next prev parent reply other threads:[~2013-04-23 21:56 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-04-23 21:56 [ 00/23] 3.0.75-stable review Greg Kroah-Hartman
2013-04-23 21:56 ` Greg Kroah-Hartman [this message]
2013-04-23 21:56 ` [ 02/23] Revert "8021q: fix a potential use-after-free" Greg Kroah-Hartman
2013-04-23 21:56 ` [ 03/23] can: sja1000: fix handling on dt properties on little endian systems Greg Kroah-Hartman
2013-04-24 22:55 ` Ben Hutchings
2013-04-23 21:56 ` [ 04/23] hugetlbfs: add swap entry check in follow_hugetlb_page() Greg Kroah-Hartman
2013-04-23 21:56 ` [ 05/23] kernel/signal.c: stop info leak via the tkill and the tgkill syscalls Greg Kroah-Hartman
2013-04-23 21:56 ` [ 06/23] hfsplus: fix potential overflow in hfsplus_file_truncate() Greg Kroah-Hartman
2013-04-23 21:56 ` [ 07/23] KVM: x86: fix for buffer overflow in handling of MSR_KVM_SYSTEM_TIME (CVE-2013-1796) Greg Kroah-Hartman
2013-04-23 21:56 ` [ 08/23] KVM: x86: Convert MSR_KVM_SYSTEM_TIME to use gfn_to_hva_cache functions (CVE-2013-1797) Greg Kroah-Hartman
2013-04-23 21:56 ` [ 09/23] KVM: Fix bounds checking in ioapic indirect register reads (CVE-2013-1798) Greg Kroah-Hartman
2013-04-23 21:56 ` [ 10/23] KVM: Allow cross page reads and writes from cached translations Greg Kroah-Hartman
2013-04-23 21:56 ` [ 11/23] ARM: 7696/1: Fix kexec by setting outer_cache.inv_all for Feroceon Greg Kroah-Hartman
2013-04-23 21:56 ` [ 12/23] ath9k_htc: accept 1.x firmware newer than 1.3 Greg Kroah-Hartman
2013-04-23 21:56 ` [ 13/23] sched: Convert BUG_ON()s in try_to_wake_up_local() to WARN_ON_ONCE()s Greg Kroah-Hartman
2013-04-23 21:56 ` [ 14/23] crypto: algif - suppress sending source address information in recvmsg Greg Kroah-Hartman
2013-04-23 21:56 ` Greg Kroah-Hartman
2013-04-23 21:56 ` [ 15/23] Revert "sysfs: fix race between readdir and lseek" Greg Kroah-Hartman
2013-04-23 21:56 ` [ 16/23] perf: Treat attr.config as u64 in perf_swevent_init() Greg Kroah-Hartman
2013-04-23 21:56 ` [ 17/23] fbcon: fix locking harder Greg Kroah-Hartman
2013-04-23 21:56 ` [ 18/23] vm: add vm_iomap_memory() helper function Greg Kroah-Hartman
2013-04-23 21:56 ` [ 19/23] vm: convert snd_pcm_lib_mmap_iomem() to vm_iomap_memory() helper Greg Kroah-Hartman
2013-04-23 21:56 ` [ 20/23] vm: convert fb_mmap " Greg Kroah-Hartman
2013-04-23 21:56 ` [ 21/23] vm: convert HPET mmap " Greg Kroah-Hartman
2013-04-23 21:56 ` [ 22/23] vm: convert mtdchar " Greg Kroah-Hartman
2013-04-23 21:56 ` [ 23/23] Btrfs: make sure nbytes are right after log replay Greg Kroah-Hartman
2013-04-24 16:21 ` [ 00/23] 3.0.75-stable review Shuah Khan
2013-04-24 16:21 ` Shuah Khan
2013-04-25 10:40 ` Satoru Takeuchi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20130423215456.456015128@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mbohan@codeaurora.org \
--cc=stable@vger.kernel.org \
--cc=tglx@linutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.