디버깅 컨피그
CONFIG_DEBUG_SPINLOCK
- 스핀락을 잡기 전에 Sematic 체크
디버깅 컨피그
https://elixir.bootlin.com/linux/v5.15.30/source/kernel/locking/Makefile
...
obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock.o
obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock_debug.o
https://elixir.bootlin.com/linux/v5.15.30/source/kernel/locking/spinlock_debug.c
#define SPIN_BUG_ON(cond, lock, msg) if (unlikely(cond)) spin_bug(lock, msg)
static inline void
debug_spin_lock_before(raw_spinlock_t *lock)
{
SPIN_BUG_ON(READ_ONCE(lock->magic) != SPINLOCK_MAGIC, lock, "bad magic"); // 버그와 관련된 에러메시지와
SPIN_BUG_ON(READ_ONCE(lock->owner) == current, lock, "recursion");
SPIN_BUG_ON(READ_ONCE(lock->owner_cpu) == raw_smp_processor_id(),
lock, "cpu recursion");
}
DEBUG_SPINLOCK_SLEEP
- 스핀락을 획득한 상태에서 슬립 진입을 시도하면 다양한 디버깅 메시지 출
력
CONFIG_DEBUG_ATOMIC_SLEEP
- Atomic 코드 구간에서 슬립 진입을 시도하면 다양한 디버깅 메시지 출력
CONFIG_DEBUG_MUTEXES
- 뮤텍스 semantics 오류 검출
- fastpath 루틴은 사용할 수 없으며 항상 slowpath(midpath) 루틴만을 호
출
세마포어
Semaphores 소개
- Semaphores는 휴면 가능한 락
- 태스크가 사용 중인 세마포어를 얻으려 할 때, 대기큐에 넣고 슬립에 진입
- 무의미한 루프(Spin)돌면서 낭비하는 시간이 없어지므로 프로세서 활용도
가 높아짐
특징
- Critical Section의 실행 시간이 긴 경우 적합
- 세마포어를 사용하는 대부분의 경우는 다른 락(ex: 스핀락)을 사용할 수 없
는 상황
- 슬립이 필요하다면 세마포어만 사용 가능(세마포어는 process context에
서만 사용 가능)
Preemption Disable
- 다른 프로세스가, 선점된 프로세스에서 실행된, 동일한 Critical Section에
진입 가능
- preempt_disable()/preempt_enable() 함수를 사용해 Critical Section
https://elixir.bootlin.com/linux/v5.10.50/source/net/packet/af_packet.c
static int packet_release(struct socket *sock)
{
...
preempt_disable();
sock_prot_inuse_add(net, sk->sk_prot, -1);
preempt_enable();
...
}
Local Interrupt Disable
- Critical Section 구간에서 인터럽트 발생 비활성화
- local_irq_disable()/local_irq_enable() 함수를 사용해 로컬 인터럽트 비
활성화
https://elixir.bootlin.com/linux/v5.4.130/source/drivers/gpu/drm/i2c/tda998x_drv.c
static void tda998x_cec_calibration(struct tda998x_priv *priv)
{
...
local_irq_disable(); // 특정 코드구간 비활성화
gpiod_set_value(calib, 0);
mdelay(10);
gpiod_set_value(calib, 1);
local_irq_enable();
...
}
순차성 배리어
- 메모리 읽기 작업과 메모리 쓰기 작업이 프로그램 코드에서 지정
한 순서대로 진행하는 루틴
- 컴파일러와 프로세서가 성능을 이유로 읽기 작업과 쓰기 작업의
순서를 바꿀 수 있음
- 코드에서 지정한 순서대로 명령을 실행해야 하는 경우 배리어
(barrier)를 사용
배리어 인터페이스
https://elixir.bootlin.com/linux/v5.15.30/source/include/asm-generic/barrier.h
#ifdef CONFIG_SMP
#ifndef smp_mb
#define smp_mb() __smp_mb()
#endif
#ifndef smp_rmb
#define smp_rmb() __smp_rmb()
#endif
#ifndef smp_wmb
#define smp_wmb() __smp_wmb()
#endif