2017-02-16 112 views
0

我有一个内核模块。它有一个IOCTL,它分配页面,然后使用kmap_atomic一次一页地映射到内核。在进程上下文中调用kmap_atomic()

当我运行通过一个测试应用程序行使这种IOCTL,我得到以下调度BUG:

[41216.007065] BUG: scheduling while atomic: app/1242/0x00000002 
    [41216.007403] Modules linked in: allocator(O) gpu(O) [last unloaded: gpu] 
    [41216.007910] CPU: 0 PID: 1242 Comm: app Tainted: G  W O 4.10.0-rc5-00111-g49e555a-dirty #22 
    [41216.008385] Hardware name: linux,dummy-virt (DT) 
    [41216.008667] Call trace: 
    [41216.008907] [<ffff000008088ba0>] dump_backtrace+0x0/0x23c 
    [41216.009242] [<ffff000008088df0>] show_stack+0x14/0x1c 
    [41216.009563] [<ffff000008375efc>] dump_stack+0x94/0xb4 
    [41216.010318] [<ffff00000816bcb0>] __schedule_bug+0x58/0x6c 
    [41216.010723] [<ffff0000088a9204>] __schedule+0x404/0x574 
    [41216.011099] [<ffff0000088a93ac>] schedule+0x38/0x9c 
    [41216.011454] [<ffff00000808873c>] do_notify_resume+0x90/0xa0 
    [41216.011844] [<ffff000008083618>] work_pending+0x8/0x10 

有谁知道是什么原因造成的? 在内核中,该消息被印刷在内核/排程/ core.c 因为下面的检查为真

if (unlikely(in_atomic_preempt_off())) { 
    __schedule_bug(prev); 
    preempt_count_set(PREEMPT_DISABLED); 
    } 

该检查在定义包括/ LINUX/preempt.h

/* 
    * Check whether we were atomic before we did preempt_disable(): 
    * (used by the scheduler) 
    */ 
    #define in_atomic_preempt_off() (preempt_count() != PREEMPT_DISABLE_OFFSET) 

如果这对任何人都有意义,请分享你的观点。

回答

1

之间kmap_atomic()kunmap_atomic它不允许睡觉

Documentation/vm/highmem.txt

kmap_atomic()。这允许一个非常短的时间映射一个单一的页面。由于映射仅限于发布它的CPU,因此它的性能良好,但发布任务因此需要保留在CPU上,直到完成为止,以免其他任务取代其映射。

相关问题