[리눅스 커널 구조 원리] #6. 스레드 정보

문연수·2025년 3월 18일
0

0. thread_info 구조체란?

 커널에서는 프로세스의 세부 실행 정보를 저장하거나 로딩하는 자료구조가 필요한데 이를 thread_info 구조체에서 관리한다:

  • 선점 스케줄링 실행 여부
  • 시그널 전달 여부
  • 인터럽트 컨텍스트와 Soft IRQ 컨텍스트 상태
  • 휴면 상태로 진입하기 직전 레지스터 세트를 로딩 및 백업

이 구조체는 프로세스 스택의 최상단 주소에 있고, 프로세스마다 자신만의 스택이 있으므로 프로세스마다 1개의 thread_info 구조체가 있다. 이런 구조체를 따로 마련해서 관리하는 이유는 프로세스의 세부 실행 정보 관리 방식이 아키텍처마다 다르기 때문이다.

그래서 CPU 아키텍처 별로 프로세스의 세부 정보를 저장하는 자료구조인 thread_info 가 필요한 것이다.

1. thread_info 구조체 정의

arch/arm64/include/asm/thread_info.hstruct thread_info

unsigned long flags 는 프로세스의 동작을 관리하는 필드 멤버이다. _TIF_XXX 라는 이름으로 등록된 플래그를 사용한다. 대표적으로 다음의 플래그가 있다:

  • _TIF_SIGPENDING: 프로세스에 시그널이 전달된 경우
  • _TIF_NEED_RESCHED: 프로세스가 선점될 경우
  • _TIF_SYSCALL_TRACE: 시스템 콜 트레이스 선정

int preempt_count 는 프로세스의 컨텍스트 정보를 저장하는 필드이다. 프로세스의 컨텍스트(인터럽트 컨텍스트, Soft IRQ 컨텍스트, etc.) 실행 정보와 프로세스가 선점 스케줄링될 조건을 저장한다. thread_info 구조체에서 가장 중요한 필드이다.

u32 cpu 는 프로세스가 실행 중인 CPU 번호를 저장하는 필드이다. 보통 raw_smp_process_id() 함수를 호출하면 CPU 번호를 알 수 있다.

 책에서는 *task 필드와 cpu_context 필드를 소개하는데 우선 task 필드는 사라졌다. 왜냐하면 thread_info 구조체가 task_struct 의 첫 번째 멤버이기 때문이다. C 표준 상 첫번째 멤버의 주소는 해당 구조체의 주소와 동일하므로 thread_info 구조체에서 task 필드를 가지고 있을 필요가 없다.

 또한 cpu_context 필드도 사라졌는데 이는 struct task_struct 내의 struct thread_struct thread 라고 하는 새로운 멤버에 의해 관리된다. 또한 명칭도 sturct cpu_context_save 가 아닌 struct cpu_context 로 바뀌었다.

cpu_context 필드는 프로세스가 컨텍스트 스위칭을 수행할 때 접근하게 되는데 이는 switch_to() (kernel/sched/core.c) 함수에서 수행된다. 더 정확하게는 switch_to() -> __switch_to() -> cpu_switch_to() 순서로 실행되며 cpu_switch_to() 에서 사용하게 되는데 이는 entry.S 에 Assembly 언어로 구현되어 있다.

2. thread_info 구조체의 주소 위치

 앞서 말했듯이 책에서는 32-bit ARM, 필자는 64-bit ARM 을 기준으로 보고 있기 때문에 설명이 여기서부터는 완전히 다르다. 우선 전술했듯이 thread_info 구조체는 task_struct 구조체와 주소가 같기 때문에, 다른 말로 하자면 task_struct 구조체만 찾으면 된다는 뜻이다.

task_structget_current() 라는 함수로 찾아오고 이 함수는 다음과 같이 구현되어 있다:

mrs 명령은 move from system register 라는 뜻으로 sp_el0 라는 시스템 레지스터의 값을 읽어들인 것이다. 여기에서 spstack pointer 이고 el0 는 익셉션 레벨 0 을 뜻한다. 아무튼 stack pointer 최상단 주소를 읽는 명령어이다. 그럼 sp_el0 는 언제 어떻게 초기화가 될까? 이는 copy_thread() 함수에서 이뤄지는 것으로 추정이 되고 이 함수는 copy_process() 에서 호출한다.

3. 프로세스가 스택을 쓰는 방법

출처: https://wenboshen.org/posts/2015-12-18-kernel-stack
출처: https://wenboshen.org/posts/2015-12-18-kernel-stack

Wenbo Shen 이라고 하는 중국의 어느 유저가 쓴 글인데 진짜 레전드 정리 자료인 것 같다. 코드 구현도 딱 저런 식으로 되어 있다.

출처

[사이트] https://duetorun.com/blog/20230601/a64-regs/#general-purpose_registers
[사이트] https://wenboshen.org/posts/2015-12-18-kernel-stack

profile
2000.11.30

0개의 댓글

관련 채용 정보