Linux Kernel(4.19) Hacks

rousalome.egloos.com

포토로그 Kernel Crash


통계 위젯 (화이트)

183162
807
85251


[라즈베리파이] 동기화 - 스핀락(spinlock): spin_unlock() 함수 분석 9장. 커널 동기화 소개

이번에는 스핀락을 해제하는 spin_unlock() 함수 코드를 살펴보겠습니다.

spin_unlock() 함수도 spin_lock() 함수와 마찬가지로 여러 함수로 치환돼 do_raw_spin_unlock() 함수를 호출합니다.
[https://elixir.bootlin.com/linux/v4.14.43/source/include/linux/spinlock.h]
static __always_inline void spin_unlock(spinlock_t *lock)
{
raw_spin_unlock(&lock->rlock);
}

void __lockfunc _raw_spin_unlock(raw_spinlock_t *lock)
{
__raw_spin_unlock(lock);
}

static inline void __raw_spin_unlock(raw_spinlock_t *lock)
{
spin_release(&lock->dep_map, 1, _RET_IP_);
do_raw_spin_unlock(lock);
do { preempt_count_sub(1); __asm__ __volatile__("": : :"memory"); } while (0);
}

static inline void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock)
{
arch_spin_unlock(&lock->raw_lock);
__release(lock);
}

static inline void arch_spin_unlock(arch_spinlock_t *lock)
{
smp_mb();
lock->tickets.owner++;
dsb_sev();
}

스핀락을 해제하는 핵심 코드는 arch_spin_unlock인데 구현부는 간단합니다. lock->tickets.owner를 +1만큼 증가시킵니다.
static inline void arch_spin_unlock(arch_spinlock_t *lock)
{
smp_mb();
lock->tickets.owner++;
dsb_sev();
}

위 함수에서 lock이란 포인터형 인자는 스핀락 인스턴스를 의미합니다. 스핀락을 획득할 때 스핀락 인스턴스의 next를 +1만큼 증감했습니다. 스핀락을 해제할 때는 스핀란 인스턴스의 owner를 +1만큼 증감하는 겁니다.

이 함수를 실행하면 전체 스핀락 동작 흐름에서 다음 그림 검은색 부분 코드가 실행하는 겁니다.
 

스핀락 획득과 릴리즈 과정을 정리하면 아래와 같습니다.
1. &lock->tickets.next 1만큼 증가시키고 arch_spin_lock() 함수 빠져나옴
2. arch_spin_unlock() 호출로 &lock->tickets.owner 1만큼 증가

시간에 스핀락을 획득하고 해제하는 인라인 어셈블리 코드를 살펴봤습니다. 처음 보는 인라인 어셈블리 코드라 낯설게 느낄 수도 있는데 코드 의미를 차근차근 알아가면 그리 어렵지 않습니다.

다음 시간에는 스핀락 구현부를 어셈블리 코드로 알아봅니다. 인라인 어셈블리 코드 분석으로 기본 동작을 파악했으니 어셈블리 코드 분석으로 넘어가는 겁니다.



#Reference 시스템 콜


Reference(워크큐)
워크큐(Workqueue) Overview



덧글

댓글 입력 영역