В чем причина BUG_ON в __get_vm_area_node?

#c #memory-management #linux-kernel #vmalloc

#c #управление памятью #linux-ядро #vmalloc

Вопрос:

Почему это утверждение __get_vm_area_node включено?

 static struct vm_struct *__get_vm_area_node(...)
{
    // ...
    BUG_ON(in_interrupt())
    // ...
} 
  

Комментарии:

1. Потому что кто-то поместил это туда: P Вы вообще смотрели? Что in_interrupt() делать? Какой код __get_vm_area_node() не работает из-за прерываний?

Ответ №1:

Я думаю, что коммит, который ввел эту строку, объясняет это довольно хорошо:

Если __vmalloc вызывается для выделения памяти с GFP_ATOMIC помощью в атомарном контексте, цепочка вызовов приводит к __get_vm_area_node выделению памяти для vm_struct with GFP_KERNEL , вызывая предупреждение «переход в спящий режим из недопустимого контекста». Этот патч исправляет это, передавая флаги gfp, поэтому __get_vm_area_node выделяет память для vm_struct с теми же флагами.

 @@ -160,13  160,15 @@ int map_vm_area(struct vm_struct *area, pgprot_t prot, struct page ***pages)
    return err;
 }
 
-struct vm_struct *__get_vm_area_node(unsigned long size, unsigned long flags,
-               unsigned long start, unsigned long end, int node)
 static struct vm_struct *__get_vm_area_node(unsigned long size, unsigned long flags,
                        unsigned long start, unsigned long end,
                        int node, gfp_t gfp_mask)
 {
    struct vm_struct **p, *tmp, *area;
    unsigned long align = 1;
    unsigned long addr;
 
    BUG_ON(in_interrupt());
    if (flags amp; VM_IOREMAP) {
        int bit = fls(size);
  

Короче говоря, следующий код в этой функции может находиться в режиме ожидания, а режим ожидания не разрешен в контексте прерывания. Добавлен BUG_ON для предотвращения подобных проблем.