본문 바로가기

[Debugging] Tips

[Kernel][Debug] 런큐에서 CFS 스케쥴러에 큐잉된 프로세스 찾기

런큐에 CFS 스케쥴러로 큐잉된 상태로 기다리는 프로세스 목록은 어디서 찾을 수 있을까요?
per-cpu 타입의 runqueues.cfs_tasks 멤버를 찾으면 됩니다.
 
다음은 CPU4 runqueue의 예시입니다.
  (struct rq *) [-] (struct rq*)(((void*)&runqueues)+__per_cpu_offset[4]) = 0xFFFFFFC73E0F2900 -> (
    (raw_spinlock_t) [D:0xFFFFFFC73E0F2900] lock = ((arch_spinlock_t) [D:0xFFFFFFC73E0F2900] raw_lock = ((u16) [D:0xFFFF
    (unsigned int) [D:0xFFFFFFC73E0F2918] nr_running = 0x3,
 //...
    (int) [D:0xFFFFFFC73E0F3298] cpu = 0x4,
    (int) [D:0xFFFFFFC73E0F329C] online = 0x1,
    (struct list_head) [D:0xFFFFFFC73E0F32A0] cfs_tasks = (
      (struct list_head *) [D:0xFFFFFFC73E0F32A0] next = 0xFFFFFFC67B0CE9A8 -> (
        (struct list_head *) [D:0xFFFFFFC67B0CE9A8] next = 0xFFFFFFC73E0F32A0,
        (struct list_head *) [D:0xFFFFFFC67B0CE9B0] prev = 0xFFFFFFC73E0F32A0),
      (struct list_head *) [D:0xFFFFFFC73E0F32A8] prev = 0xFFFFFFC67B0CE9A8),
 
runqueues.cfs_tasks.next는 해당 프로세스의 struct task_struct,se.group_node 멤버로 등록돼 있습니다.
따라서 다음 커맨드를 입력하면 프로세스 태스크 디스크립터 주소를 알아낼 수 있습니다.
  (struct task_struct *) container_of(0xFFFFFFC67B0CE9A8struct task_struct,se.group_node) = 0xFFFFFFC67B0CE900 -> (
    (struct thread_info) thread_info = ((long unsigned int) flags = 0x00400000, (mm_segment_t) addr_limit = 0x0000008000000000, (int) pre
    (long int) state = 0x0,
    (void *) stack = 0xFFFFFFC6A295C000,
//...
    (struct cred *) ptracer_cred = 0x0,
    (struct cred *) real_cred = 0xFFFFFFC72D06E180,
    (struct cred *) cred = 0xFFFFFFC72D06E180,
    (char [16]) comm = "visualizer capt",