Что произойдет, если мы спим в обработчике прерываний по SMP - PullRequest
0 голосов
/ 06 января 2019

Что произойдет, если мы спим в обработчике прерываний на SMP-машине,

Я написал образец драйвера клавиатуры и добавил сон на обработчик прерываний

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

Система работала несколько минут, а затем паниковала. Почему система не может работать с одним отключенным процессором, поскольку прерывания по таймеру сработают на другом процессоре и могут планировать процессы.

Обратная трассировка, полученная с помощью настройки kgdb:

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 Ответ

0 голосов
/ 06 января 2019

Прерывание клавиатуры может произойти в любое время, в том числе во время вызова ядра. Обычно это нормально: прерывание происходит, драйвер делает свое дело, обработчик прерываний возвращается, а ядро ​​продолжается.

Но если вы sleep() в обработчике прерываний, ядро ​​находится в промежуточном состоянии. Другие процессоры не могут выполнять вызовы ядра, потому что он уже занят. Каждый будет вынужден сделать паузу в ожидании ядра - которое не возвращается. Неудивительно, что это паника!

...