在进程上下文中调用kmap_atomic()

时间:2017-02-16 06:37:40

标签: c linux-kernel scheduling preemption

我有一个内核模块。它有一个IOCTL,它分配页面,然后一次使用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

有谁知道造成这种情况的原因是什么? 在内核中,此消息打印在kernel / sched / core.c中 因为以下检查是真的

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

此检查在include / 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 个答案:

答案 0 :(得分:1)

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

来自Documentation/vm/highmem.txt

  

kmap_atomic()。这允许单个的非常短的持续时间映射        页。由于映射仅限于发布它的CPU,因此        表现良好,但因此要求发行任务保持不变        CPU直到完成,以免其他任务取代其映射。