代码之家  ›  专栏  ›  技术社区  ›  md.jamal

如果我们在SMP上的中断处理程序中睡眠会发生什么

  •  2
  • md.jamal  · 技术社区  · 5 年前

    如果我们睡在SMP机器上的中断处理器中会发生什么,

    keyboard driver 并在中断处理程序上添加了睡眠

    #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);
    

    系统运行了几分钟,然后出现了死机。为什么系统不能在禁用一个处理器的情况下工作,因为计时器中断将在另一个CPU上触发,并且可以调度进程。

    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
    
    1 回复  |  直到 5 年前
        1
  •  0
  •   John Burger    5 年前

    键盘中断可以在任何时候发生,包括在内核调用期间。正常情况下,这没关系:中断发生,驱动程序执行它的操作,中断处理程序返回,内核继续。

    但是如果你 sleep() 在中断处理程序中,内核处于中间状态。其他处理器无法执行内核调用,因为它已经很忙了。每个人都将被迫暂停等待内核,而内核不会返回。难怪会恐慌!