From 61d1f2eb9b1b2d3784f077bf77cfeb4944277ab0 Mon Sep 17 00:00:00 2001 From: Satya Durga Srinivasu Prabhala Date: Fri, 22 Feb 2019 21:32:35 -0800 Subject: [PATCH] hrtimer: fix issue during core isolation During core isolation, while migrating hrtimers to one of online CPUs, below issue is being observed due to commit 5da70160462e80b ("hrtimer: Implement support for softirq based hrtimers") which started to enable local irqs. Fix it by moving local_bh_disable/enable calls to hotplug path only. [ 73.488582] WARNING: CPU: 0 PID: 7 at kernel/softirq.c:106 \ __local_bh_disable_ip+0xc4/0xd0 [ 73.506182] WARNING: CPU: 0 PID: 7 at kernel/softirq.c:160 \ __local_bh_enable_ip+0xd0/0x140 [ 73.523834] kernel BUG at kernel/irq_work.c:138! [ 73.531979] Internal error: Oops - BUG: 0 [#1] PREEMPT SMP [ 73.567732] pstate: 60400005 (nZCv daif +PAN -UAO) [ 73.572663] pc : irq_work_run+0x160/0x170 [ 73.576795] lr : flush_smp_call_function_queue+0x178/0x1b0 [ 73.674966] Call trace: [ 73.677494] irq_work_run+0x160/0x170 [ 73.681271] flush_smp_call_function_queue+0x178/0x1b0 [ 73.686558] generic_smp_call_function_single_interrupt+0x14/0x20 [ 73.692832] handle_IPI+0x188/0x2f8 [ 73.696426] gic_handle_irq+0x110/0x1d8 [ 73.700374] el1_irq+0xb4/0x130 Change-Id: I969171022377dc793834c4c4343e5f839f224dbe Signed-off-by: Satya Durga Srinivasu Prabhala --- kernel/time/hrtimer.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c index f53495f36177..6c39b7f6bb1a 100644 --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c @@ -2073,12 +2073,6 @@ static void __migrate_hrtimers(unsigned int scpu, bool remove_pinned) unsigned long flags; int i; - /* - * this BH disable ensures that raise_softirq_irqoff() does - * not wakeup ksoftirqd (and acquire the pi-lock) while - * holding the cpu_base lock - */ - local_bh_disable(); local_irq_save(flags); old_base = &per_cpu(hrtimer_bases, scpu); new_base = this_cpu_ptr(&hrtimer_bases); @@ -2106,7 +2100,6 @@ static void __migrate_hrtimers(unsigned int scpu, bool remove_pinned) /* Check, if we got expired work to do */ __hrtimer_peek_ahead_timers(); local_irq_restore(flags); - local_bh_enable(); } int hrtimers_dead_cpu(unsigned int scpu) @@ -2114,7 +2107,14 @@ int hrtimers_dead_cpu(unsigned int scpu) BUG_ON(cpu_online(scpu)); tick_cancel_sched_timer(scpu); + /* + * this BH disable ensures that raise_softirq_irqoff() does + * not wakeup ksoftirqd (and acquire the pi-lock) while + * holding the cpu_base lock + */ + local_bh_disable(); __migrate_hrtimers(scpu, true); + local_bh_enable(); return 0; }