Patch "clocksource: exynos_mct: Avoid blocking calls in the cpu hotplug notifier" has been added to the 3.14-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
clocksource: exynos_mct: Avoid blocking calls in the cpu hotplug notifier
to the 3.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
clocksource-exynos_mct-avoid-blocking-calls-in-the-cpu-hotplug-notifier.patch
and it can be found in the queue-3.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
56a94f13919c0db5958611b388e1581b4852f3c9Mon Sep 17 00:00:00 2001
From: Damian Eppel <[email protected]>
Date: Fri, 26 Jun 2015 15:23:04 +0200
Subject: clocksource: exynos_mct: Avoid blocking calls in the cpu hotplug notifier
From: Damian Eppel <[email protected]>
commit 56a94f13919c0db5958611b388e1581b4852f3c9 upstream.
Whilst testing cpu hotplug events on kernel configured with DEBUG_PREEMPT and DEBUG_ATOMIC_SLEEP we get following BUG message, caused by calling request_irq() and free_irq() in the context of hotplug notification (which is in this case atomic context).
[ 40.785859] CPU1: Software reset [ 40.786660] BUG: sleeping function called from invalid context at mm/slub.c:1241 [ 40.786668] in_atomic(): 1, irqs_disabled(): 128, pid: 0, name: swapper/1 [ 40.786678] Preemption disabled at:[< (null)>] (null) [ 40.786681] [ 40.786692] CPU: 1 PID: 0 Comm: swapper/1 Not tainted 3.19.0-rc4-00024-g7dca860 #36 [ 40.786698] Hardware name: SAMSUNG EXYNOS (Flattened Device Tree) [ 40.786728] [<c0014a00>] (unwind_backtrace) from [<c0011980>] (show_stack+0x10/0x14) [ 40.786747] [<c0011980>] (show_stack) from [<c0449ba0>] (dump_stack+0x70/0xbc) [ 40.786767] [<c0449ba0>] (dump_stack) from [<c00c6124>] (kmem_cache_alloc+0xd8/0x170) [ 40.786785] [<c00c6124>] (kmem_cache_alloc) from [<c005d6f8>] (request_threaded_irq+0x64/0x128) [ 40.786804] [<c005d6f8>] (request_threaded_irq) from [<c0350b8c>] (exynos4_local_timer_setup+0xc0/0x13c) [ 40.786820] [<c0350b8c>] (exynos4_local_timer_setup) from [<c0350ca8>] (exynos4_mct_cpu_notify+0x30/0xa8) [ 40.786838] [<c0350ca8>] (exynos4_mct_cpu_notify) from [<c003b330>] (notifier_call_chain+0x44/0x84) [ 40.786857] [<c003b330>] (notifier_call_chain) from [<c0022fd4>] (__cpu_notify+0x28/0x44) [ 40.786873] [<c0022fd4>] (__cpu_notify) from [<c0013714>] (secondary_start_kernel+0xec/0x150) [ 40.786886] [<c0013714>] (secondary_start_kernel) from [<40008764>] (0x40008764)
Interrupts cannot be requested/freed in the CPU_STARTING/CPU_DYING notifications which run on the hotplugged cpu with interrupts and preemption disabled.
To avoid the issue, request the interrupts for all possible cpus in the boot code. The interrupts are marked NO_AUTOENABLE to avoid a racy request_irq/disable_irq() sequence. The flag prevents the request_irq() code from enabling the interrupt immediately.
The interrupt is then enabled in the CPU_STARTING notifier of the hotplugged cpu and again disabled with disable_irq_nosync() in the CPU_DYING notifier.
[ tglx: Massaged changelog to match the patch ]
--- drivers/clocksource/exynos_mct.c | 43 +++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 13 deletions(-)
drivers/clocksource/exynos_mct.c +30 -13
@@ -422,15 +422,12 @@ static int exynos4_local_timer_setup(strexynos4_mct_write (TICK_BASE_CNT , mevt->base +MCT_L_TCNTB_OFFSET );if (mct_int_type ==MCT_INT_SPI ) { - evt->irq = mct_irqs[MCT_L0_IRQ + cpu]; -if (request_irq (evt->irq, exynos4_mct_tick_isr, -IRQF_TIMER |IRQF_NOBALANCING , - evt->name, mevt)) { -pr_err ("exynos-mct: cannot register IRQ %d\n" , - evt->irq); + +if (evt->irq ==-1 )return -EIO ; - } -irq_force_affinity (mct_irqs[MCT_L0_IRQ + cpu],cpumask_of (cpu)); + +irq_force_affinity (evt->irq,cpumask_of (cpu)); +enable_irq (evt->irq); }else {enable_percpu_irq (mct_irqs[MCT_L0_IRQ ],0 ); }
@@ -443,10 +440,12 @@ static int exynos4_local_timer_setup(strstatic void exynos4_local_timer_stop (struct clock_event_device *evt) { evt->set_mode (CLOCK_EVT_MODE_UNUSED , evt); -if (mct_int_type ==MCT_INT_SPI ) -free_irq (evt->irq,this_cpu_ptr (&percpu_mct_tick)); -else +if (mct_int_type ==MCT_INT_SPI ) { +if (evt->irq !=-1 ) +disable_irq_nosync (evt->irq); + }else {disable_percpu_irq (mct_irqs[MCT_L0_IRQ ]); + } } static int exynos4_mct_cpu_notify(struct notifier_block *self,
@@ -478,7 +477,7 @@ static struct notifier_block exynos4_mctstatic void __init exynos4_timer_resources (struct device_node *np,void __iomem *base) { -int err; +int err, cpu;struct mct_clock_event_device *mevt =this_cpu_ptr (&percpu_mct_tick);struct clk *mct_clk, *tick_clk;
@@ -505,7 +504,25 @@ static void __init exynos4_timer_resourcWARN (err,"MCT: can't request IRQ %d (%d)\n" , mct_irqs[MCT_L0_IRQ ], err); }else { -irq_set_affinity (mct_irqs[MCT_L0_IRQ ],cpumask_of (0 )); +for_each_possible_cpu (cpu) { +int mct_irq = mct_irqs[MCT_L0_IRQ + cpu]; +struct mct_clock_event_device *pcpu_mevt = +per_cpu_ptr (&percpu_mct_tick, cpu); + + pcpu_mevt->evt.irq =-1 ; + +irq_set_status_flags (mct_irq,IRQ_NOAUTOEN ); +if (request_irq (mct_irq, + exynos4_mct_tick_isr, +IRQF_TIMER |IRQF_NOBALANCING , + pcpu_mevt->name, pcpu_mevt)) { +pr_err ("exynos-mct: cannot register IRQ (cpu%d)\n" , + cpu); + +continue ; + } + pcpu_mevt->evt.irq = mct_irq; + } } err =register_cpu_notifier (&exynos4_mct_cpu_nb);
Patches currently in stable-queue which might be from [email protected] are
queue-3.14/clocksource-exynos_mct-avoid-blocking-calls-in-the-cpu-hotplug-notifier.patch