나는 커널 모듈을 가지고있다. 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)
이것이 어떤 사람 에게든 이해가된다면, 당신의 관점을 공유하십시오.