Linux Kernel(4.19) Hacks

rousalome.egloos.com

포토로그 Kernel Crash


통계 위젯 (화이트)

178162
807
85246


[라즈베리파이] 시스템 콜 - 시스템 콜 핸들러 실행을 마무리하면 어떤 동작을 할까? 11장. 시스템 콜

시스템 콜을 수행하면 시스템 콜 핸들러를 통해 가상 파일시스템이나 커널 프로세스 함수를 실행합니다. 이후 시스템 콜 종류에 따라 시스템 콜 핸들러 하부 루틴을 수행하고 유저 공간 복귀합니다.

시스템 콜 실행 후 복귀할 때 ret_fast_syscall 레이블에서 리눅스 커널 시그널 및 스케줄링 관점에서 중요한 동작을 실행합니다.

시스템 콜 테이블을 통해 시스템 콜 핸들러를 분기하기 직전 다음 1번째 줄 코드와 같이 복귀 레지스터(r14, lr)에 ret_fast_syscall 레이블을 지정했습니다. 
[https://elixir.bootlin.com/linux/v4.14.70/source/arch/arm/kernel/entry-common.S]
1 badr lr, ret_fast_syscall @ return address
2 ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine

시스템 콜 핸들러에서 시스템 콜 종류에 따라 시스템 콜 핸들러에서 실행을 마친 후 ret_fast_syscall 레이블을 실행합니다.

다음 ftrace 로그를 예로 들어 보겠습니다.
1 chromium-browse-1200 [001] 952.125229: _raw_spin_lock+0x10/0x54 <-__schedule+0xc0/0xa50
2 chromium-browse-1200 [001] 952.125238: <stack trace>
3 => futex_wait_queue_me+0x10c/0x1a8
4 => futex_wait+0xf8/0x234
5 => do_futex+0x10c/0xc58
6 => SyS_futex+0xec/0x194
7 => ret_fast_syscall+0x0/0x28

이 프로세스는 __schedule() 함수 호출로 준비 상태로 대기하고 있다가 스케줄러에 의해 다시 실행할 수 있습니다. 이 때 futex_wait_queue_me() 함수 혹은 서브 루틴 실행 후 1번에서 7번 ret_fast_syscall 레이블 방향으로 다시 복귀합니다.

시스템 콜을 ftrace 로 분석하면 대부분 시스템 콜은 아주 짧은 시간 내(0.005ms) 실행을 마무리합니다. 
Xorg-485 [001] 2720.496312: sys_enter: NR 297 (20, 7ee069dc, 0, 0, 0, 7ee069dc)
Xorg-485 [001] 2720.496317: sys_exit: NR 297 = 4 // __NR_recvmsg
Xorg-485 [001] 2720.496321: sys_enter: NR 146 (20, 7ee06b7c, 1, 8e500700, 0, 270d7b0)
Xorg-485 [001] 2720.496327: sys_exit: NR 146 = 32  // __NR_writev
Xorg-485 [001] 2720.496329: sys_enter: NR 297 (20, 7ee069dc, 0, 0, 0, 7ee069dc)
Xorg-485 [001] 2720.496331: sys_exit: NR 297 = -11  // __NR_recvmsg
Xorg-485 [001] 2720.496332: sys_enter: NR 104 (0, 7ee06c0c, 0, 0, 76fc6ce8, 1fb000)
Xorg-485 [001] 2720.496335: sys_exit: NR 104 = 0  // __NR_setitimer
Xorg-485 [001] 2720.496337: sys_enter: NR 252 (3, 7ee05c00, 100, e434, 0, 1fb000)
Xorg-485 [001] 2720.496375: sys_exit: NR 252 = 1 // __NR_recvmsg
주석문으로 표시한 부분은 시스템 콜 번호에 대응하는 시스템 콜 핸들러를 의미합니다.


다음 그림은 ret_fast_syscall 레이블에서 시작해서 no_work_pending 레이블까지 동작 흐름도입니다. 시스템 콜 실행을 종료하고 유저 공간으로 복귀하는 과정입니다.

각 레이블 별로 어떤 동작을 하는지 살펴봅시다.

ret_fast_syscall
프로세스 최상단 주소에 있는 struct thread_info flag 멤버가 _TIF_WORK_MASK 인지 점검합니다.

struct thread_info flag 멤버가 _TIF_WORK_MASK가 아닐 경우 다음 조건으로 처리합니다.
1> TIF_SYSCALL_WORK 이면 ?
   __sys_trace_return_nosave 레이블 실행으로 ftrace sys_exit 이벤트 로그 실행 후 유저 공간 복귀

2> TIF_SYSCALL_WORK 아니면 ?
 no_work_pending 레이블을 실행해서 유저 공간으로 복귀

slow_work_pending
 do_work_pending() 함수 실행해서 시그널 및 스케줄링 처리를 한 후  no_work_pending 레이블을 호출합니다. 리눅스 커널 관점에서 눈여겨봐야 할 레이블 코드입니다.
  
no_work_pending
 restore_user_regs 매크로 실행으로 유저 공간 복귀하는 레이블입니다.

다음 시간에는 각 레이블이 어떤 동작을 하는지 어셈블리 코드 분석으로 알아보겠습니다.

#Reference 시스템 콜


Reference(워크큐)
워크큐(Workqueue) Overview





핑백

덧글

댓글 입력 영역