“BUG: sleeping function called from invalid context at ......”(might_sleep 함수 설명)
[ 88.055297] BUG: sleeping function called from invalid context at ......
이 오류는might_sleep 함수에 인쇄된 이 함수에 대한 설명은 다음과 같이 귀결되었다.
이 함수는 내가 코드를 볼 때 기본적으로 직접적으로 소홀히 하는 것이다. (왜냐하면 나는 그것이 실제로 무슨 일을 하지 않는다는 것을 알고 있기 때문이다.) 그러나 내부 핵 중의 많은 함수는 처음부터 그것을 사용하기 때문이다. 내부 핵 원본을 배우고 있는 네티즌들을 편리하게 하기 위해 본 글은 이 함수가 도대체 내부 핵에 의해 무엇을 하는지 전문적으로 토론하고자 한다.
간단하게 말하자면, 디버깅 수요가 없다면, 이 매크로(또는 함수, 칭호는 중요하지 않다)는 실질적인 일은 하지 않고, 커널은 단지 그것으로 한 가지 일을 할 뿐이다. 이 함수를 호출하는 함수는 sleep가 될 수 있다는 것을 일깨워 주는 것이다. 이것은 그 이름과 일치한다. The function calling might_sleep() might sleep.이 함수의 정의는 다음과 같습니다.
#ifdef CONFIG_PREEMPT_VOLUNTARY
extern int _cond_resched(void);
# define might_resched() _cond_resched()
#else
# define might_resched() do { } while (0)
#endif
#ifdef CONFIG_DEBUG_ATOMIC_SLEEP
void __might_sleep(const char *file, int line, int preempt_offset);
/**
* might_sleep - annotation for functions that can sleep
*
* this macro will print a stack trace if it is executed in an atomic
* context (spinlock, irq-handler, ...).
*
* This is a useful debugging help to be able to catch problems early and not
* be bitten later when the calling function happens to sleep when it is not
* supposed to.
*/
# define might_sleep() \
do { __might_sleep(__FILE__, __LINE__, 0); might_resched(); } while (0)
#else
static inline void __might_sleep(const char *file, int line,
int preempt_offset) { }
# define might_sleep() do { might_resched(); } while (0)
#endif
사실 내부 원본 코드에 대해서도 명확한 주석이 있다:might_sleep - annotation for functions that can sleep.그래서 릴리스 버전의kernel image에 대해might_sleep의 역할은 단지 annotation일 뿐, 사용자에게 일깨워주고,might_sleep의 함수는 그 후의 코드 실행에서 sleep가 될 수 있습니다.
그러나 디버깅 수요가 개입된다면 예를 들어 당신의 시스템이 영문도 모른 채 무작위로 충돌을 일으킬 수 있습니다. 어려운 사건 분석 조사를 거친 후에 마지막으로 코어를 열기로 결정한 CONFIG_DEBUG_ATOMIC_SLEEP 옵션, 이제 might_sleep는 사건의 진일보한 추진에 기여할 수 있다.CONFIG_DEBUG_ATOMIC_SLEEP 옵션은 주로 하나의 ATOMIC 조작의 상하문에서 함수가sleep 행위를 하는지 확인하는 데 사용되며, ATOMIC 조작이 무엇인지, 내부 원본 코드는might_sleep 함수 앞에도 다음 설명이 있습니다.
this macro will print a stack trace if it is executed in an atomic context (spinlock, irq-handler, ...)
그래서 하나의 프로세스가 spinlock을 얻은 후에 이른바 atomiccontext, 또는irq-handler, 즉 인터럽트 상하문에 들어간 것이 분명하다.이 두 가지 상하문에서 이론적으로 현재의 execution path를 sleep 상태에 들어가게 해서는 안 된다. (강제 규정은 아니지만, 다시 말하면spinlock을 가진 프로세스가 sleep에 들어가는 것은 시스템이 반드시 deadlock 등을 의미하는 것은 아니지만 내부 프로그래밍에 있어서는 이 지뢰밭을 최대한 피해야 한다.)CONFIG에서_DEBUG_ATOMIC_SLEEP 옵션이 켜진 경우 might_sleep에는 또 어떤 특수한 기능이 있습니까?코어의 소스 코드를 살펴보십시오.
void __might_sleep(const char *file, int line, int preempt_offset)
{
static unsigned long prev_jiffy; /* ratelimiting */
rcu_sleep_check(); /* WARN_ON_ONCE() by default, no rate limit reqd. */
if ((preempt_count_equals(preempt_offset) && !irqs_disabled()) ||
oops_in_progress)
return;
if (system_state != SYSTEM_RUNNING &&
(!__might_sleep_init_called || system_state != SYSTEM_BOOTING))
return;
if (time_before(jiffies, prev_jiffy + HZ) && prev_jiffy)
return;
prev_jiffy = jiffies;
printk(KERN_ERR
"BUG: sleeping function called from invalid context at %s:%d
",
file, line);
printk(KERN_ERR
"in_atomic(): %d, irqs_disabled(): %d, pid: %d, name: %s
",
in_atomic(), irqs_disabled(),
current->pid, current->comm);
debug_show_held_locks(current);
if (irqs_disabled())
print_irqtrace_events(current);
dump_stack();
}
EXPORT_SYMBOL(__might_sleep);
현재 CONFIG_DEBUG_ATOMIC_SLEEP 옵션을 사용하면 __might_sleep는 여전히 많은 일을 했습니다. 가장 중요한 일은 첫 번째if문장, 특히preempt_count_equals 및 irqs_disabled는 현재 상하문이 하나의atomiccontext인지 판단하는 데 사용됩니다. 프로세스가 spin_를 얻으면lock의 변종 형식의 lock은 단일 프로세서 시스템이든 다중 프로세서 시스템이든preempt_count 변경,irq_disabled는 현재 중단이 켜져 있는지 여부를 판단하는 데 사용됩니다. __might_sleep는 바로 이러한 정보에 근거하여 현재 실행 중인 코드 상하문이atomic인지 아닌지를 판단하는 것입니다. 그렇지 않으면 함수는 모든 것이 정상적이기 때문에 바로 되돌아옵니다.만약 그렇다면 코드는 아래로 내려간다.
그래서 CONFIG_DEBUG_ATOMIC_SLEEP 옵션을 열면 atomic context에서sleep가 발생했는지 확인할 수 있습니다. 만약 코드가 실수로 어딘가에 이런 상황이 발생했다면might_sleep는 다음 printk 및 dump_를 통해stack은 당신이 이런 상황을 발견하는 것을 협조합니다.
__might_sleep 함수의 system_state, 이것은 전역적인enum형 변수로 현재 시스템의 상태를 기록하는 데 주로 사용된다.주의 system_state는 export에 의해 나왔기 때문에 내부 모듈은 이 값을 직접 읽어서 현재 시스템의 운행 상태를 판단할 수 있습니다. 흔히 볼 수 있는 상태는 다음과 같습니다.
extern enum system_states {
SYSTEM_BOOTING,
SYSTEM_RUNNING,
SYSTEM_HALT,
SYSTEM_POWER_OFF,
SYSTEM_RESTART,
SYSTEM_SUSPEND_DISK,
} system_state;
가장 흔한 상태는 단연 SYSTEM입니다.RUNNING, 당신의 시스템이 정상이 된 후에 이 상태에 처해 있다.현재의 화제와 직접적인 연관이 없기 때문에, 여기에서 한 번만 언급하면 된다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.