디버깅 컨피그

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

0개의 댓글