포스트

임베디드 스터디 - 커널 주요 자료구조

임베디드 스터디 - 커널 주요 자료구조

list_head

  • 커널 안에서 여러 항목을 연결해 관리할 때 사용하는 타입에 독립적인 연결 리스트
  • 일반적인 연결 리스트는 next 포인터가 특정 타입에 고정됨
    • 자료구조마다 리스트 코드를 따로 작성해야 하는 문제 발생
1
2
3
4
5
6
7
8
9
10
11
12
13
/* 일반적인 연결 리스트 */
struct device_node {
    int id;
    char name[32];
    struct device_node *next;   // device_node만 연결 가능
};

/* 커널 list_head 방식 */
struct device_node {
    int id;
    char name[32];
    struct list_head list;      // 리스트 연결 정보만 분리
};
  • list_head를 별도 멤버로 분리하면 리스트 순회·삽입·삭제 코드를 한 번만 작성하고 어떤 구조체에든 재사용 가능
    • C++의 템플릿, Java의 제네릭과 동일한 목적

wait_queue

  • 데이터가 준비되지 않았을 때 프로세스를 SLEEP 시키고, 데이터가 도착하면 WAKE UP 시키는 대기 큐
  • Busy wait(while(데이터없음) {}) 대신 사용하여 CPU를 다른 프로세스에 양보
1
2
3
4
5
6
7
8
9
10
11
read() 호출 → 데이터 없음
        ↓
프로세스를 wait_queue에 넣고 SLEEP 상태로 전환
        ↓
CPU는 다른 프로세스 실행 (스케줄러가 관리)
        ↓
인터럽트 발생 → 데이터 도착
        ↓
드라이버가 wait_queue의 프로세스를 WAKE UP
        ↓
프로세스가 read()에서 데이터를 받아 반환

인터럽트 상하반부 분리

  • 인터럽트 핸들러가 실행되는 동안 같은 CPU의 다른 인터럽트가 블로킹됨
    • 핸들러가 길어지면 다른 인터럽트를 놓칠 수 있음
  • 이를 해결하기 위해 인터럽트 처리를 두 단계로 분리
1
2
3
4
5
6
7
8
9
인터럽트 발생
        ↓
상반부 (Top Half) — 인터럽트 핸들러
: 최소한의 작업만 (데이터 레지스터 읽기, 플래그 저장)
: 빠르게 끝내야 함
        ↓
하반부 (Bottom Half) — 후처리
: 무거운 작업 (데이터 파싱, 버퍼 복사, 프로토콜 처리)
: 인터럽트 핸들러 밖에서 실행

tasklet

  • 인터럽트 핸들러 동작 후 무거운 작업을 처리하는 메커니즘
  • 인터럽트 컨텍스트에서 실행 → sleep 불가 (논블로킹 작업만 가능)
    • kmalloc(GFP_KERNEL) 등 sleep이 발생할 수 있는 함수 사용 불가

work_queue

  • 인터럽트 핸들러 동작 후 무거운 작업을 처리하는 메커니즘
  • 커널 스레드로 실행 → sleep 가능 (블로킹 작업 가능)
1
2
3
후처리 작업이 sleep/wait가 필요한가?
├── NO  → tasklet    (빠른 데이터 복사, 플래그 처리 등)
└── YES → work_queue (파일 I/O, 네트워크 전송, kmalloc 등)

kfifo

  • 커널이 제공하는 Thread-Safe 링 버퍼 구현
  • UART 드라이버에서 인터럽트가 발생할 때마다 수신 데이터를 쌓아두고, read() 시 꺼내주는 버퍼로 사용
  • FIFO 구조를 사용하는 이유 : 시간 순서대로 먼저 들어온 데이터부터 처리해야 하기 때문
    • 직렬 통신에서 바이트 순서가 바뀌면 데이터가 깨짐
  • 인터럽트 핸들러(쓰기)와 read()(읽기)가 동시에 접근할 때 발생하는 레이스 컨디션 문제를 내부적으로 처리

정리

자료구조역할특징
list_head범용 연결 리스트타입 독립적
wait_queue프로세스 대기 큐SLEEP / WAKE UP
tasklet인터럽트 하반부sleep 불가
work_queue인터럽트 하반부sleep 가능
kfifo링 버퍼thread-safe FIFO
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.