Lockdep ( locking validator ) 은 Community 에서(안드로이 혹은 기타 커널 어플리케이션듵) proactive debbeging tools 들중 가장 유용한 도구(실은 커널 라이브러리) 중 하나이다, 2006년 이후 이 기능이 소개된 이후로 가장 많은 커널의 데드락 버그를 잡는데 도움을 주었다고 한다.
데드락 이슈는 유저스페이스에서도 일어날 수 있다는 사실에도 불구하고, user-space 프로그래밍을 위한 고급 도구들은 부족했는데, 마침 다행히도 lockdep 이 user-space 에서도 가능하게 만들어지고있다는것.. 이건 누가 만들어줄때까지 기다리는 것 보다, 훨씬 간단한 일이였다...
Lockdep 은 커널에서 locking 을 호출한 부분에 추가되어 작동된다. 매번 특정한 타잎의 lock - 마치 프로세스가 지금 인터럽트를 서비스하고 있는지 등의 부수적 정보를 가록해 놓은 정보등 - 을 가져오거나 리릴리즈한다. Lockdep 은 또한 새로운 락을 가져올때, 다른 lock 이 이미 잠긴상태인지 등의 정보도 기록한다. - 이것은 lockdep 이 수행될때 접근 및 사용 가능한 키들이 어떤 것들인지 역시 확인한다.
아래 그림은 일반적인 AB-BA deadlock 이라고 불리우는 상황을 나타낸 그림으로, A 와 B 그리고 쓰레드 1과 2 가 있을때,
만약 한 쓰레드가 B를 잡고있는 상태에서 A를 요구한다면, 다음과같이 그려질고,
이제 아래와 같은 서로 lock이 풀리기만 기다리는 교착상태가 발생 할 수 있게된다.
이런 상황은 아주 기본적인 데드락 상황으로, context switching 이 많이 발생되는 고급시스템(요즘엔 다 그렇지만 ㅋ) 에서는 더욱 자주 발생될 수 있으며, 시스템들이 비록 완벽하게 서비스를 멈추진 않더라도, 시스템엔지니어라면 누구나 다 짜증날 만한 상황인 졸라, 부하가 천퍼센뜨(?) 이상 올라가고 엔지니어 머리속엔 그냥 지중해 어느 바닷가에서 비키니 북극곰들과 나뒹구는 - 물론 먹이로 - 상상외엔 아무것도 못할거같은 상황이 발생가능 하다는 것!
사실 A와 B 가 자원할당등을 요구할때 순서를 제대로 지킬 수 있게 즉, 특정한 룰에 의해 동작할 수 있도록, 정리만 잘하면 되는 부분이지만, 요즘같은 대량 리퀘스틀의 파도 - 절대 리퀘스트만 - 에선, 커널뿐만아닌, 각종 라이브러리와 3rd-party, 자바(우리꺼라 언급하기머시기하긴한데) 등 user-space 에서 동작하는 녀석들과 사소한 코드적 실수로도 쉽게 발생 될 수도 있다는 점!
(기초중으 기초이므로 넘어간다 넘 길었어 이미,,,이런걸 SR 로 물어보는 니네가 더 이상해!)
뭐 lockdep 의 실질적인 동작원리는 다른 아티클 링크(2006년도 기사) 에서도, 요즘엔 임베딩이나 안드로이드덕에 한글사이트들도 많은 편이라 찾아보면 되실거고, 일단 이 deadlock 해결을 위해 각 프로세스카운터를 효과적으로 추적하고, 일종의 경고나 해당 내용에 대한 레포팅을 발생시켜 줄 수 있다면 원인을 해결하는데 매우 큰 도움이 될 것이며, 이것이 lockdep 이 해결해 줄 수 있다는것에 주목하도록 하자...
하지만 이 글에의 요지는, 이 lockdep 이 어차피 다른놈들처럼 커널기반으로만 동작한다면, 뭐 다를바 있냐는 점이겠지.. 대부분의 커널관련 도구들은, 일반 유저스페이스에서 커널스페이스로의 접근이나 수정을 전혀 허용하지 않는 경우가 많으니까.. 벗뜨...샤샤(Shasa-오라클의 커널개발자이다!!!) 라는 커널개발자가 요녀석을 슬슬 보더니, 요놈은 실제로 커널에 대한 의존도 높은 코드는 거의 없이, 대부분 단순히 성능에 대한 카운터, 트레이싱그래프 등이 대다수를 차지함을 깨닳았다!!!! 그래서 샤샤는 커널의 컨텍스트 영역이 아닌 곳에서도 수행이 가능한 라이브러리에 대한 패치셋을 발표하였다! (역시 고금최강고수들의 수준인게지.털썩.....)
이 방망이라도 깍는듯한 노인이 설명하길, 실은, Local_irq_enable() 과 같은 함수를 호출하는것은 사실 user space 에서 아무런 의미가 없으며, Task_struck 같은 구조체의 경우 사용자공간에서 추적이 제공되고있는 데다가, print_stack_trace 의 경우 backtrace_symbols_fd 로 대체될 수 있으므로, 내부 커널 API 를 사용하는 것을 우회하였고, lockdep 에서 사용되는 커널 internal lock(mutex,shemaphore,spinlock 등등) 들약시 pthread mutex 로 재구현되어 플래그를 통한 트레이싱이 일반 유저스페이스에서도 충분히 제공될 수 있다는것이다! (이 무슨 부첫님염불소리이냔 말이다!!!) 무튼, 작업은 현재 완료되어, stub version 에서 따로 제공되던 부분이 곧 커널 메인 트리로 머지될 예정이다.
User-space 에서 lockdep 의 이점을 사용하기위한 방법도 간단한데, <lockdep/mutex.h> 헤더를 포함하고, Pthread_mutex_t 와 rwlock_t 주변에 liblockdep_init 을 호출해서 시작을 알리고, liblockdep_set_thread 함수로 POSIX thread 방식으로 생성된 task 들에 대한 mutex,rwlock 상태들을 lockdep 의 레포팅도구들에의해 확인하면 디버깅이나 추적이 가능하다.. 머 사실 시스템엔지니어위주로 작성하는 본인이니 대충알아두고..
현재 POC(proof of concept) 를 위해 강력한 커널 프로파일링툴인 perf 에 테스팅중이다. ( lockdep perf sched record 식으로 사용가능하며 추후 이것에 대한 테크노트 포스팅 예정이다. 나에겐 젤 중요해 이게.. 나중에 성능튜닝엔지녀도 해볼려면 )
사실, 이 모든 것들은, user-space 에서도 사용가능 하도록 많은 커널개발자들의 부단한 관심과 노력이 필요한 일이였으며, 특별한 부딪힘조차 없이 대동단결하여 훅훅 메인에 머지되고있다고 한다..쌈꾼들도 뭉칠만큼이란게 뽀인뜨 다른 커널 디버깅툴또한 사용자공간에서의 가능 하도록 되었으면 좋겠다...는 (나와 Jonathan 의 사족이..)
결론적으로, user-space 에서 런타임라이브러리 잠금을 추적 할 수 있도록 lockdep 의 유저영역 라이브러리가 GPL license 아래에서 많은 사람들의 노력으로 (특히 오라클의 샤샤 ㅋㅋ) 어렵지 않게 가능해 졌으며, system process 간의 높은 신뢰성을 제공하는 lock 시스템의 기반을 마련했기에, 다가올 미래가 밝다는 훈훈한 마무리....
Ps1 : 이 글은 실제 아티클을 번역하는 과정에서 나름대로의 쉬운(?) 풀이로 각색한 글이다. 게다가 아직 모르는사람이 설마 있겠냐만, 난 모든 작업에 맥주는 기본이므로, 가끔 길어지면 취해서 글이 그냥 폭발만하고 정리가 안된다는점... Ps2 : 올하클이는 회사지만 구성원은 사람이고, 뼛속에 펭귄이 살아 숨쉬는 리눅서들이라면, 회사가 아범이든, 하클이든, 삼성이든 문제되는것 따윈 없어!