Skip to content

Commit 6d913c3

Browse files
Damian Eppelmoonlinux
authored andcommitted
clocksource: exynos_mct: Avoid blocking calls in the cpu hotplug notifier
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). [ 0.091617] [c0] CPU0: thread -1, cpu 0, socket 1, mpidr 80000100 [ 0.091828] [c0] Running under secure firmware. [ 0.091901] [c0] Setting up static identity map for 0xc0618b98 - 0xc0618bf0 [ 0.091962] [c0] Exynos-SnapShot: exynos_ss_init failed [ 0.112330] [c0] ftrace: Allocated trace_printk buffers [ 0.134323] [c1] CPU1: Booted secondary processor [ 0.134354] [c1] CPU1: thread -1, cpu 1, socket 1, mpidr 80000101 [ 0.134402] [c1] BUG: sleeping function called from invalid context at mm/page_alloc.c:2638 [ 0.134518] [c1] in_atomic(): 1, irqs_disabled(): 0, pid: 0, name: swapper/1 [ 0.134560] [c1] no locks held by swapper/1/0. [ 0.134598] [c1] CPU: 1 PID: 0 Comm: swapper/1 Not tainted 3.10.82-xu43hk #11 [ 0.134640] [c1] Backtrace: [ 0.134694] [c1] [<c00132e4>] (dump_backtrace+0x0/0x114) from [<c0013554>] (show_stack+0x20/0x24) [ 0.134744] [c1] r7:00000000 r6:00000000 r5:df2da000 r4:c098c9c0 [ 0.134826] [c1] [<c0013534>] (show_stack+0x0/0x24) from [<c06124d8>] (dump_stack+0x24/0x28) [ 0.134887] [c1] [<c06124b4>] (dump_stack+0x0/0x28) from [<c00617f8>] (__might_sleep+0x144/0x148) [ 0.134952] [c1] [<c00616b4>] (__might_sleep+0x0/0x148) from [<c00f5590>] (__alloc_pages_nodemask+0x2a0/0xaac) [ 0.135006] [c1] r5:00080008 r4:002012d0 [ 0.135065] [c1] [<c00f52f0>] (__alloc_pages_nodemask+0x0/0xaac) from [<c012875c>] (new_slab+0x7c/0x22c) [ 0.135132] [c1] [<c01286e0>] (new_slab+0x0/0x22c) from [<c012a92c>] (__slab_alloc.isra.14.constprop.18+0x558/0x61c) [ 0.135187] [c1] r9:00000000 r8:df001f00 r7:014f7000 r6:00000000 r5:c1dee9e0 [ 0.135187] r4:c08f79e0 [ 0.135295] [c1] [<c012a3d4>] (__slab_alloc.isra.14.constprop.18+0x0/0x61c) from [<c012af3c>] (kmem_cache_alloc_trace+0x194/0x1c8) [ 0.135367] [c1] [<c012ada8>] (kmem_cache_alloc_trace+0x0/0x1c8) from [<c00b04e0>] (request_threaded_irq+0x78/0x138) [ 0.135433] [c1] [<c00b0468>] (request_threaded_irq+0x0/0x138) from [<c0610f7c>] (exynos4_local_timer_setup+0x100/0x160) [ 0.135507] [c1] [<c0610e7c>] (exynos4_local_timer_setup+0x0/0x160) from [<c060de3c>] (percpu_timer_setup+0xa4/0xb0) [ 0.135562] [c1] r8:4000406a r7:c0968c84 r6:10c0387d r5:c09148c0 r4:c1de9280 [ 0.135655] [c1] [<c060dd98>] (percpu_timer_setup+0x0/0xb0) from [<c060e1e4>] (secondary_start_kernel+0x118/0x134) [ 0.135710] [c1] r5:c09148c0 r4:00000001 [ 0.135765] [c1] [<c060e0cc>] (secondary_start_kernel+0x0/0x134) from [<4060d784>] (0x4060d784) [ 0.135815] [c1] r5:00000015 r4:5f13006a [ 0.144239] [c2] CPU2: Booted secondary processor [ 0.144267] [c2] CPU2: thread -1, cpu 2, socket 1, mpidr 80000102 [ 0.154295] [c3] CPU3: Booted secondary processor Change-Id: I78ee2d3997b2137e3c19432e17b3e3672523cf43
1 parent 2366f77 commit 6d913c3

1 file changed

Lines changed: 39 additions & 8 deletions

File tree

drivers/clocksource/exynos_mct.c

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,22 @@ static irqreturn_t exynos4_mct_tick_isr(int irq, void *dev_id)
413413
return IRQ_HANDLED;
414414
}
415415

416+
static const char *irq_names[] = {
417+
"mct_tick0",
418+
"mct_tick1",
419+
"mct_tick2",
420+
"mct_tick3",
421+
"mct_tick4",
422+
"mct_tick5",
423+
"mct_tick6",
424+
"mct_tick7",
425+
};
426+
427+
static DEFINE_PER_CPU(struct irqaction, percpu_mct_irq) = {
428+
.flags = IRQF_TIMER | IRQF_NOBALANCING,
429+
.handler = exynos4_mct_tick_isr,
430+
};
431+
416432
static int __cpuinit exynos4_local_timer_setup(struct clock_event_device *evt)
417433
{
418434
struct mct_clock_event_device *mevt;
@@ -433,15 +449,12 @@ static int __cpuinit exynos4_local_timer_setup(struct clock_event_device *evt)
433449
exynos4_mct_write(TICK_BASE_CNT, mevt->base + MCT_L_TCNTB_OFFSET);
434450

435451
if (mct_int_type == MCT_INT_SPI) {
452+
struct irqaction *mct_irq = this_cpu_ptr(&percpu_mct_irq);
453+
454+
mct_irq->dev_id = mevt;
436455
evt->irq = mct_irqs[MCT_L0_IRQ + cpu];
437-
if (request_irq(evt->irq, exynos4_mct_tick_isr,
438-
IRQF_TIMER | IRQF_NOBALANCING,
439-
evt->name, mevt)) {
440-
pr_err("exynos-mct: cannot register IRQ %d\n",
441-
evt->irq);
442-
return -EIO;
443-
}
444456
irq_set_affinity(evt->irq, cpumask_of(cpu));
457+
enable_irq(evt->irq);
445458
} else {
446459
enable_percpu_irq(mct_irqs[MCT_L0_IRQ], 0);
447460
}
@@ -456,7 +469,7 @@ static void exynos4_local_timer_stop(struct clock_event_device *evt)
456469
{
457470
evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
458471
if (mct_int_type == MCT_INT_SPI)
459-
free_irq(evt->irq, this_cpu_ptr(&percpu_mct_tick));
472+
disable_irq(evt->irq);
460473
else
461474
disable_percpu_irq(mct_irqs[MCT_L0_IRQ]);
462475
}
@@ -465,6 +478,21 @@ static struct local_timer_ops exynos4_mct_tick_ops __cpuinitdata = {
465478
.setup = exynos4_local_timer_setup,
466479
.stop = exynos4_local_timer_stop,
467480
};
481+
482+
static void __init exynos4_local_timer_init(void)
483+
{
484+
int cpu;
485+
486+
if (mct_int_type == MCT_INT_SPI) {
487+
for (cpu = 0; cpu < num_possible_cpus(); cpu++) {
488+
struct irqaction *mct_irq
489+
= per_cpu_ptr(&percpu_mct_irq, cpu);
490+
mct_irq->name = irq_names[cpu];
491+
setup_irq(mct_irqs[MCT_L0_IRQ + cpu], mct_irq);
492+
disable_irq(mct_irqs[MCT_L0_IRQ + cpu]);
493+
}
494+
}
495+
}
468496
#endif /* CONFIG_LOCAL_TIMERS */
469497

470498
static void __init exynos4_timer_resources(struct device_node *np, void __iomem *base)
@@ -551,6 +579,9 @@ static void __init mct_init_dt(struct device_node *np, unsigned int int_type)
551579
mct_irqs[i] = irq_of_parse_and_map(np, i);
552580

553581
exynos4_timer_resources(np, of_iomap(np, 0));
582+
#ifdef CONFIG_LOCAL_TIMERS
583+
exynos4_local_timer_init();
584+
#endif
554585
exynos4_clocksource_init();
555586
exynos4_clockevent_init();
556587
exynos4_timer_delay_init();

0 commit comments

Comments
 (0)