Linux Kernel(4.19) Hacks

rousalome.egloos.com

포토로그 Kernel Crash


통계 위젯 (화이트)

5112
737
82115


[프로세스] 실행 중인 cpu 정보 업데이트(커널 4.9.65 ) 4장. 프로세스 관리

ARM64 비트 리눅스 커널 4.9.65 버전에서 아래 구조체가 변경됐습니다.
특히 해당 프로세스가 돌고 있던 CPU 정보를 담고 있는 int cpu 멤버가 사라졌는데요.
crash64> struct thread_info
struct thread_info {
    unsigned long flags;
    mm_segment_t addr_limit;
    int preempt_count;
}

기존 Linux version 4.6.0 버전
crash64> p linux_banner
linux_banner = $1 = "Linux version 4.6.0 (sudhakar.koppiset@ubuntu) (gcc version 5.2.1 20151005 (Linaro GCC 5.2-2015.11-2) ) #1 SMP Tue Apr 4 17:38:35 KST 2017\n"
crash64> struct thread_info
struct thread_info {
    unsigned long flags;
    mm_segment_t addr_limit;
    struct task_struct *task;
    int preempt_count;
    int cpu;
}

기존 리눅스 커널 코드를 잠깐 살펴봐도 알 수 있습니다.
현재 프로세스가 돌고 있는 CPU는 smp_processor_id 함수로 얻어오는데 다음 코드 흐름을 보면 current_thread_info()->cpu로 얻어옵니다. 
void smp_call_function_many(const struct cpumask *mask,
    smp_call_func_t func, void *info, bool wait)
{
struct call_function_data *cfd;
int cpu, next_cpu, this_cpu = smp_processor_id();

# define smp_processor_id() raw_smp_processor_id()
#define raw_smp_processor_id() (current_thread_info()->cpu)

그런데 커널 4.9 버젼은 cpu_number 변수로 cpu 번호를 읽어옵니다.
# define smp_processor_id() raw_smp_processor_id()
#define raw_smp_processor_id() (*raw_cpu_ptr(&cpu_number))

코드와 함께 크래시 유틸리티 프로그램으로 확인하니 역시 per-cpu 타입 변수이네요.
DECLARE_PER_CPU_READ_MOSTLY(int, cpu_number);

crash64> p cpu_number
PER-CPU DATA TYPE:
  int cpu_number;
PER-CPU ADDRESSES:
  [0]: ffffffd27b2ce000
  [1]: ffffffd27b2e5000
  [2]: ffffffd27b2fc000
  [3]: ffffffd27b313000
  [4]: ffffffd27b32a000
  [5]: ffffffd27b341000
  [6]: ffffffd27b358000
  [7]: ffffffd27b36f000

태스크 디스크립터에 cpu란 멤버 변수가 있네요.
crash64> struct task_struct.cpu
struct task_struct {
    [68] unsigned int cpu;
}

크래시 유틸리티로 검증해도 같은 결과값를 확인할 수 있군요.
crash64> runq -m
 CPU 0: [0 00:00:03.122]  PID: 442    TASK: ffffffd267a26680  COMMAND: "mmcqd/0"
 CPU 1: [6 04:54:56.161]  PID: 0      TASK: ffffffd2741a6680  COMMAND: "swapper/1"
 CPU 2: [0 00:00:12.009]  PID: 83     TASK: ffffffd27358c480  COMMAND: "msm_watchdog"
 CPU 3: [0 00:00:00.050]  PID: 435    TASK: ffffffd267cce680  COMMAND: "irq/85-8804000."
 CPU 4: [6 04:54:46.752]  PID: 0      TASK: ffffffd2741a2280  COMMAND: "swapper/4"
 CPU 5: [6 04:54:46.752]  PID: 0      TASK: ffffffd2741a4480  COMMAND: "swapper/5"
 CPU 6: [0 00:00:13.364]  PID: 5359   TASK: ffffffd2685e0080  COMMAND: "kworker/u16:7"
 CPU 7: [6 04:54:56.161]  PID: 0      TASK: ffffffd2741d0080  COMMAND: "swapper/7"

crash64> struct task_struct.cpu ffffffd27358c480
  cpu = 2
crash64> struct task_struct.cpu ffffffd2685e0080
  cpu = 6

이렇게 리눅스 커널 4.9 버젼부터 ARM64 비트 아키텍처에서 CPU번호를 per-cpu 타입으로 관리하는데, 
왜 코드를 바꿨을까요? 여러 의견이 있는데 Security 때문이라는 주장에 저는 점수를 주고 싶습니다.


덧글

댓글 입력 영역