리눅스 커널 모듈 안에서 cpu 와 코어의 수를 얻어와야 할 일이 생겼다. 그리고 코어별로 클럭을 조절해서 테스트 해야 할 일이 생겨 찾아본 것을 정리해 보았다.

확인해 본 커널 버전은 2.6.30 , 2.6.34 였다. (2010년 8월 8일 현재 최신 커널버전은 2.6.35)


CPU info

http://www.hanb.co.kr/network/view.html?bi_id=1446

위 의 링크에서 친절히 잘 설명된 정보를 얻을 수 있었다.

리눅스 커널에서는 cpu 의 정보를 담은 구조체가 전역변수로 선언되어 있고 그것을 통해 cpu 정보를 가져올 수 있는 것이다.

다만 커널 버전이 올라가면서 전에는 cpu_data[] 배열에서 직접 데이터를 얻을 수 있던 것이 이제는 안된다. (정확히 언제 바뀌었는지 모르겠는데 2.6.30 이후 부터는 안됨.)

현재 실행중인 cpu 정보를 얻기위한 current_cpu_data 매크로는 여전히 존재하며 cpu_data() 매크로를 통해 특정 cpu 의 정보를 얻어올 수 있으니 이를 이용해보자.

두 매크로는 <asm/processor.h> 에 선언되어 있다.



pc 에서 아까의 매크로로 얻어온 데이터는 struct cpuinfo_x86 구조체로 되어있는데 여기서 내가 관심있는 물리적 코어수 관련 정보는 x86_max_cores 로 보인다.

arch/x86/kernel/cpu/intel.c 파일을 보면 아래와 같은 코드가 있고

c->x86_max_cores = intel_num_cpu_cores(c);

arch/x86/kernel/cpu/amd.c 파일에는 다음과 같은 코드가 있었는데 이를 보면 x86_max_cores는 cpu 의 코어수가 맞는 것 같다.

c->x86_max_cores = (ecx & 0xff) + 1;

booted_cores 도 같은 값을 가지고 있는데.. OS에서 보는 코어의 수라고 하니 하이퍼쓰레딩 같은 것에 따라 달라질 수 있는 것 같다. 이것은 테스트를 한번 해 볼 필요가 있다. 아래와 같은 코드로 값을 확인해 볼 수 있다.

printk("current_cpu_data.x86_max_cores : %hu\n",
                  current_cpu_data.x86_max_cores);
printk("current_cpu_data.booted_cores : %hu\n",
                  current_cpu_data.booted_cores); 


각 cpu의 core id 와 physical processor id 를 확인해 보기 위해 아래와 같은 코드로 테스트 해 보았다.

   for_each_possible_cpu( cpu ) {
       printk("cpu_data(%d).phys_proc_id : %hu\n",
               cpu, cpu_data(cpu).phys_proc_id);
       printk("cpu_data(%d).cpu_core_id : %hu\n",
               cpu, cpu_data(cpu).cpu_core_id);
   }

내 pc 는 1cpu 2 core 이기 때문에 결과는 다음과 같다.

cpu_data(0).phys_proc_id : 0
cpu_data(0).cpu_core_id : 0
cpu_data(1).phys_proc_id : 0
cpu_data(1).cpu_core_id : 1

CPU Frequency scaling

참조 : http://www.thinkwiki.org/wiki/How_to_make_use_of_Dynamic_Frequency_Scaling

리눅스에서 cpu 클럭을 동적으로 바꾸기 위해서는 먼저 cpu 에서 이를 지원해 주어야 하고( intel speed step, amd power now 등) 커널에서

CPU Frequency scaling
이 설정되어 있어야 한다. 자세한 설정은 위의 링크에 잘 나와있다.

그 다음. cpu frequency driver 를 로드해야 한다. 사용 가능한 드라이버는

/lib/modules/*/kernel/arch/*/kernel/cpu/cpufreq

에 있다. cpu 에 맞는 드라이버가 올라갔다면

/sys/devices/system/cpu/cpuN 밑에 cpufreq 디렉토리가 생성되고 아래와 같은 파일들이 생성된다.

affected_cpus     cpuinfo_transition_latency     scaling_driver
bios_limit        related_cpus                   scaling_governor
cpuinfo_cur_freq  scaling_available_frequencies  scaling_max_freq
cpuinfo_max_freq  scaling_available_governors    scaling_min_freq
cpuinfo_min_freq  scaling_cur_freq               scaling_setspeed


유저가 클럭을 변경하려면 scaling_setspeed 파일에 값을 설정하면 된다. 그런데 이때 governor 가 userspace 로 되어있지 않으면 값을 변경할 수 없다.

scaling_available_governors에서 사용 가능한 governor 를 확인할 수 있고 scaling_governor 에서 현재 설정된 governor 를 볼 수 있다.

echo userspace > scaling_governor

로 governor 를 설정하고 scaling_available_frequencies 에서 확인한 주파수로 클럭을 설정하면 된다.

echo 1000000 > scaling_setspeed

affected_cpus 파일에는 클럭 변경으로 영향을 받는 cpu들의 정보가 있다. 여기에 현재 cpu 만 있고 다른 cpu(core) 의 번호가 없다면 cpu(core)별로 클럭을 따로 설정할 수 있는 것이다.


이 글은 스프링노트에서 작성되었습니다.

by 패스파인더 2010. 8. 8. 22:23
| 1 |