2012년 5월 13일 일요일

spin lock

  1. spin lock 의 정의 보면 SMP 에서만 사용함을 알 수 있다.
    • 구현에 있어 memory 관련 내용은 memory-barriers.txt 참조.
  2. 결국 이것은 SMP 에서 새로이 나타난 동기화를 해결 하기 위한 solution 이라는 관점으로 접근 하는것이 이해하기 좋다. 간단히 mutex 를 생각해 보면...

  • mutex
  1. semaphore 의 특수한 경우이지만 따로 보통 분리해서 다룬다.
    • 효율성 때문 mutex-design.txt 참조
  2. Rule
    • only one task can hold the mutex at a time
    • only the owner can unlock the mutex
    • multiple unlocks are not permitted
    • recursive locking is not permitted
    • a mutex object must be initialized via the API
    • a mutex object must not be initialized via memset or copying
    • task may not exit with mutex held
    • memory areas where held locks reside must not be freed
    • held mutexes must not be reinitialized
    • mutexes may not be used in hardware or software interrupt contexts such as tasklets and timers
  3. APIs
    •  DEFINE_MUTEX(name);
    •  mutex_init(mutex);
    •  void mutex_lock(struct mutex *lock);
    •  int  mutex_lock_interruptible(struct mutex *lock);
    •  int  mutex_trylock(struct mutex *lock);
    •  void mutex_unlock(struct mutex *lock);
    •  int  mutex_is_locked(struct mutex *lock);
    •  void mutex_lock_nested(struct mutex *lock, unsigned int subclass);
    •  int  mutex_lock_interruptible_nested(struct mutex *lock, unsigned int subclass);
    •  int atomic_dec_and_mutex_lock(atomic_t *cnt, struct mutex *lock);

UP 에서 mutex 를 구현 한다는 것은 결국 atomic 하게 exchange 를 할 수 있으면 되는 거다.
보통 관련한 instruction 이 있지.
SMP 환경이라면, 아무리 atomic exchange instruction 이 있어도 다른 코어 가 동시에 접근 하는 것을 막을 수는 없지.
즉, mutex 의 구현안에 spin lock 을 이용한 SMP 보호 구역이 있어야 겠지.
물론 실제로도 그러하다.

spinlock 사용 되는 경우 보면...

code sample 1>

static DEFINE_SPINLOCK(xxx_lock);

unsigned long flags;

spin_lock_irqsave(&xxx_lock, flags);
... critical section here ..
spin_unlock_irqrestore(&xxx_lock, flags);

언제나 안전하다. irq 를 막기 때문에 아무도 침범 불가.

code sample 2>


   rwlock_t xxx_lock = __RW_LOCK_UNLOCKED(xxx_lock);


unsigned long flags;

read_lock_irqsave(&xxx_lock, flags);
.. critical section that only reads the info ...
read_unlock_irqrestore(&xxx_lock, flags);

write_lock_irqsave(&xxx_lock, flags);
.. read and write exclusive access to the info ...
write_unlock_irqrestore(&xxx_lock, flags);
이것은 RCU 로 대체 되었고, 제거 중이다.
- 참조 rcu.txt, listRCU.txt

code sample 3>

spin_lock(&lock);
...
spin_unlock(&lock)

irq 안막았기 때문에 아래와 같은 deadlock 가능.
spin_lock(&lock);
...
<- interrupt comes in:
spin_lock(&lock);

같은 걸 동일 cpu 에서 lock 해 버리면 deadlock 이 된다.



spinlock 의 사용시 irq 도 막을지 말지는 보호하려는 critical section 이 ISR 에서 참조 하는지 유무에 따라 결정 하면 된다.



댓글 없음:

댓글 쓰기