What will happen if we sleep in an interrupt handler on a SMP Machine,
I wrote a sample keyboard driver and added sleep on the interrupt handler
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/sched/signal.h>
MODULE_LICENSE("GPL");
static int irq = 1, dev = 0xaa, counter = 0;
static irqreturn_t keyboard_handler(int irq, void *dev)
{
pr_info("Keyboard Counter:%d\n", counter++);
msleep(1000);
return IRQ_NONE;
}
/* registering irq */
static int test_interrupt_init(void)
{
pr_info("%s: In init\n", __func__);
return request_irq(irq, keyboard_handler, IRQF_SHARED,"my_keyboard_handler", &dev);
}
static void test_interrupt_exit(void)
{
pr_info("%s: In exit\n", __func__);
synchronize_irq(irq); /* synchronize interrupt */
free_irq(irq, &dev);
}
module_init(test_interrupt_init);
module_exit(test_interrupt_exit);
The system ran for few minutes and then panic. Why can't the system work with one processor disabled, as the timer interrupts will be fired on the other CPU and can schedule processes.
Back Trace captured using kgdb setup:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 1254]
0x0000000000000000 in irq_stack_union ()
(gdb) bt
#0 0x0000000000000000 in irq_stack_union ()
#1 0xffffffff810ad8e4 in ttwu_activate (en_flags=<optimized out>, p=<optimized out>, rq=<optimized out>)
at kernel/sched/core.c:1638
#2 ttwu_do_activate (rq=0xffff888237422c40, p=0xffffffff82213780 <init_task>, wake_flags=9,
rf=0xffffc900022b3f10) at kernel/sched/core.c:1697
#3 0xffffffff810aec00 in sched_ttwu_pending () at kernel/sched/core.c:1740
#4 0xffffffff810aedcd in scheduler_ipi () at kernel/sched/core.c:1771
#5 0xffffffff81a01aef in reschedule_interrupt () at arch/x86/entry/entry_64.S:888
#6 0xffffc900022b3f58 in ?? ()
#7 0xffffffff81a01aea in reschedule_interrupt () at arch/x86/entry/entry_64.S:888
#8 0x0000000000000002 in irq_stack_union ()
#9 0x00007fcec3421b40 in ?? ()
#10 0x0000000000000006 in irq_stack_union ()
#11 0x00007fceb00008c0 in ?? ()
#12 0x0000000000000002 in irq_stack_union ()
#13 0x00000000020bd380 in ?? ()
#14 0x0012c8d2cc413914 in ?? ()
Cannot access memory at address 0x5000