Guillermo Austin Kim

Sources

Posts

998 posts

[Linux][Kernel] 슬랩 Slab Memory 디버깅(Debugging) - 1

Guillermo Austin Kim|2017년 12월 12일

슬랩 디버그 컨피그를 키면 어떤 일을 더 할까요? 정리해볼께요 콜트래이스 저장슬랩 메모리를 할당 및 해제할 때 콜트래이스를 저장해요. 이 콜트래이스는 struct track 변수에서 쓰이거든요. 우리가 알고 있는 슬랩의 종류는 30여 가지나 되죠. 이런 슬랩 메모리를 할당하고 해제할 때 콜스택을 모두 저장한다는 것은 시스템에 과부하를 주게 되요. 성능이 좋지 않은 CPU가 탑재된 타겟 디바이스에서 심하면 부팅도 제대로 못할 수도 있어요. 아래 Slab corruption으로 커널 패닉이 발생한 로그를 잠깐 봅시다. 아래 커널 로그는 lkdtm feature를 써서 WRITE_AFTER_FREE 버그를 강제로 유발시킨 건데요. 문제 발생 코드는 아래와 같아요.(CONFIG_LKDTM을 키고 커널 이미지를

[Linux][Kernel] 슬랩 Slab Memory 소개

Guillermo Austin Kim|2017년 12월 11일

리눅스 커널 Memory Management의 꽃 슬랩(Slab)을 소개할께요. 슬랩이 소개 되기 전 리눅스 커널 메모리는 모두 동적 할당을 했어요. 한참 그렇게 메모리를 썼었죠. 그러다가 메모리 성능을 높이기 위한 과제를 리눅스 커널 전문가들이 진행했어요. 여러가지 메모리 성능을 키우는 코드 작업을 진행하다가, 한 가지 조사를 했어요. 뭐나면, 어떤 타입의 메모리를 커널 코드에서 할당하는지에 대해서였어요. 그런데 재미있게도 메모리를 할당하는 패턴이 정해져 있다는 걸 확인했어요. 평범한 서민들이 먹는 식단을 몇 가지가 될까요? 아마 전 먹는 메뉴가 20여 가지로 정해져 있거든요. 비빔밥, 짜장면, 고구마(저녁으로 먹죠), 스타벅스, 삽겹살, 순대… 저 같은 경우는 20가지도 안되는 것 같네요. 그래서

[Linux][Kernel] signal - signal handler 설정 및 처리

Guillermo Austin Kim|2017년 12월 11일

리눅스 커널 코드 리뷰를 많이 했는데요.리눅스 시스템 프로그램이 커널과 어떻게 연동되는지 한 가지 점검해볼께요. 유저 공간에서 signal을 설정하는 코드를 많이 볼 수 있습니다. 아래는 SIGINT란 시그널이 전달되었을 때 linux_sig()란 함수가 호출되는 간단한 코드입니다.그럼 아래 시그널 콜백 함수가 어떻게 실행이 될까요?#include #define SIGINT (2) typedef void (*handler_t)(int); handler_t signal( int, handler_t ); handler_t old;void linux_sig( int signo ){ printf("linux_sig(%d)\n", signo ); signal( SIGINT, ol

[Linux][Kernel] preempt_disable(), preemption 상세 분석

Guillermo Austin Kim|2017년 12월 10일

저번 시간에 preempt_disable() 함수 호출로 커널 패닉이 일어나는 문제가 있었는데요.이 매크로 함수와 preemption의 관계에 대해서 좀 더 알아보고자 해요. preemption은 리눅스 커널 핵심 개념 중의 핵심이죠. preempt_disable() 함수를 호출하면 스택 주소를 꺼내와서, current_thread_info에 있는 preempt_count에 1을 더하는 짓만 하거든요. 그럼 current_thread_info의 preempt_count를 어떻게 접근하냐구요?어떤 프로그램이 돌던 스택 주소를 접근하면 해당 current_thread_info를 가져올 수 있어요.static inline struct thread_info *current_thread_info(void){ r

[Linux][Kernel] 타이머(Timer) Overview

Guillermo Austin Kim|2017년 12월 9일

리눅스 커널에서 아주 중요한 Subsystem 중 하나인 타이머에 대해서 간단히 짚어 볼께요. init_timer아래 함수 콜로 do_init_timer() 함수에서 struct timer_list *timer 초기화를 수행해요.__init_timer((timer), 0)init_timer_key((_timer), (_flags), #_timer, &__key);do_init_timer(timer, flags, name, key); MIPS 아키텍쳐에서 아래와 같이 타이머를 세팅하는 코드가 있네요.static inline void ip32_power_button(void){// .. 생략.. blink_timer.data = POWERDOWN_FREQ; blink_timeout(POWERDOWN_