2017-02-16 18 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); 
    } 

포함/리눅스/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를 유지해야하므로 다른 작업이 매핑을 옮겨 놓지 않도록해야합니다.