* 44주차
10차 ARM 리눅스 커널 스터디 44주차(2014.03.01) 후기입니다.
# 일시 : 2014.03.01 (44주차)
# 장소 : 토즈 타워점
# 참여인원 : 4명
# 스터디 진도 : start_kernel()-> setup_per_cpu_areas() -> pcpu_embed_first_chunk();
# 스터디 주요 논의 내용
# if(max_distance > (VMALLOC_END - VMALLOC_START) * ¾) {
}
75%보다(크기를 계산해 보면 180MB) max_distance가 크면 안된다.
# pcpu_embed_first_chunk () -> pcpu_setup_first_chunk(ai, base)
dyn_size : 0x3000 (12kB)
size_sum : ai->static_size + ai->reserved_size + dyn_size
// ai->static_size + 0x5000 (20kB : 8kB + 12kB)
# PRINTF 에서 *는 무엇을 의미할까?
참조 링크 : http://www.soen.kr/
pintf에서 *는 폭지정을 인수로부터 전달받는다.
보통은 %5이런식으로 %다음에 숫자가 폭을 지정하나,
가변적으로 폭을 지정하고 싶을때는 인자를 2개 사용해서 *와 출력을 사용한다.
## 예시 1: 폭지정의 예이다. *으로 하면 폭이 3이되고 출력이 5가 출력된다.
printf(“wwww%*dwww”,3,5);
→ www__5www
## 예시 2 (길님):
35 fprintf( stderr, "%s%0*lx\n", "", 1, 0xf );
36 fprintf( stderr, "%s%0*lx\n", ",", 2, 0xf );
37 fprintf( stderr, "%s%0*lx\n", ",", 3, 0xf );
38 fprintf( stderr, "%s%0*lx\n", ",", 4, 0xf );
출력결과
f
,0f
,00f
,000f
# BUG_ON 에서 체크하는 것들
ai->nr_groups : 1
ai_static_size : 실제 할당된 size
~PAGE_MASK : 0x00000FFF
!base_addr : 128K만큼 물리주소 0x5FFFFFFF 근처에서 할당받는 주소
~PAGE_MASK : 0x00000FFF
ai->unit_size : 0x8000 (32kB로 가정)
ai->unit_size : 0x8000 & ~PAGE_MASK :
ai->unit_size < PCPU_MIN_UNIT_SIZE : 0x3000 (12kB)
ai->dyn_size < PERCPU_DYNAMIC_EARLY_SIZE
pcpu_verify_alloc_info(ai) <0;
# 4kB단위로 할당 받는 메모리들
group_offsets :
group_sizes:
unit_map :
unit_off :
# 각 cpu에 해당하는 unit_map[0~3] 와 할당 받은 unit_off를 설정하는 과정
1283 for (group = 0, unit = 0; group < ai->nr_groups; group++, unit += i) {
1284 const struct pcpu_group_info *gi = &ai->groups[group];
1285
1286 group_offsets[group] = gi->base_offset;
1287 group_sizes[group] = gi->nr_units * ai->unit_size;
1288
1289 for (i = 0; i < gi->nr_units; i++) {
1290 cpu = gi->cpu_map[i];
1291 if (cpu == NR_CPUS)
1292 continue;
1293
1294 PCPU_SETUP_BUG_ON(cpu > nr_cpu_ids);
1295 PCPU_SETUP_BUG_ON(!cpu_possible(cpu));
1296 PCPU_SETUP_BUG_ON(unit_map[cpu] != UINT_MAX);
1297
1298 unit_map[cpu] = unit + i;
1299 unit_off[cpu] = gi->base_offset + i * ai->unit_size;
1300
1301 /* determine low/high unit_cpu */
1302 if (pcpu_low_unit_cpu == NR_CPUS ||
1303 unit_off[cpu] < unit_off[pcpu_low_unit_cpu])
1304 pcpu_low_unit_cpu = cpu;
1305 if (pcpu_high_unit_cpu == NR_CPUS ||
1306 unit_off[cpu] > unit_off[pcpu_high_unit_cpu])
1307 pcpu_high_unit_cpu = cpu;
1308 }
1309 }
실행 후 :
// unit : 4
unit_off[0] 의 offset 0x0
unit_off[1] 의 offset 0x8000 * 1
unit_off[2] 의 offset 0x8000 * 2
unit_off[3] 의 offset 0x8000 * 3
# 부팅 중 percpu관련 메시지 예시 ( x86, 우분투 12.04)
[ 0.000000] setup_percpu: NR_CPUS:256 nr_cpumask_bits:256 nr_cpu_ids:1 nr_nod
e_ids:1
[ 0.000000] PERCPU: Embedded 29 pages/cpu @ffff88003fc00000 s86720 r8192 d238
72 u2097152
[ 0.000000] pcpu-alloc: s86720 r8192 d23872 u2097152 alloc=1*2097152
[ 0.000000] pcpu-alloc: [0] 0
[ 0.000000] Built 1 zonelists in Node order, mobility grouping on. Total pages: 257913
# pcpu_first_chunk 는 어떤 값이 될까?
1527 pcpu_first_chunk = dchunk ?: schunk;
컴파일로 실험해 보니
dchunk가 NULL이 아니라면 pcup_first_chunk = dchunk가 된다. (우리는 이것)
dchunk가 NULL이라면 pcpu_first_chunk = schunk가 된다.
# pcpu_chunk_relocate(pcpu_first_chunk, -1);
&pcpu_slot[11] (list)에 pcpu_first_chunk(&dchunk)가 할당됨
# 왜 11 slot에 할당될까?
dchunk->free_size 가 0x3000 (12kB)이기 때문이다.
정확히는 소스코드에서 계산되고
return max(highbit - PCPU_SLOT_BASE_SHIFT + 2, 1);
우리는 highbit가 14이기 때문에 return max(11,1 ) = 11 이된다.
slot number와 slot size를 정리하면 다음과 같다.
| slot number | slot size |
|-----------+-------------|
| 13 | 32kB |
| 12 | 16kB |
| 11 | 8kB |
| 10 | 4kB |
| 09 | 2kB |
| 08 | 1kB |
| 07 | 512B |
| 06 | 256B |
| 05 | 128B |
| 04 | 64B |
| 03 | 32B |
| 02 | 16B |
| 01 | 8B |
| 0 | 4B |
|-----------+-------------|
# chunk란 ?
청크는 사전적 의미는 덩어리라는 뜻이다. 정보 덩어리를 나누고 나누어진 덩어리에 대한 정보를 찾기 위한 색인을 정의하여 편리하게 찾기 위한 방법이다.
# 왜 perCPU메모리를 할당해서 사용할까?
1. 각 CPU가 사용하는 메모리 자원을 locking을 위해서 이다.
2. 캐쉬 invalid를 향상 시킨다.
# 스터디 log 1차
38f9803..e31c467 master -> origin/master
Updating 38f9803..e31c467
Fast-forward
arch/arm/include/asm/pgtable.h | 4 +-
include/asm-generic/sections.h | 1 +
include/linux/bitops.h | 7 +++
include/linux/cpumask.h | 4 ++
include/linux/kern_levels.h | 4 ++
include/linux/kernel.h | 3 +
include/linux/log2.h | 13 ++++-
include/linux/percpu.h | 1 +
include/uapi/linux/kernel.h | 2 +
kernel/cpu.c | 1 +
lib/bitmap.c | 29 ++++++++++
lib/vsprintf.c | 2 +
mm/percpu-km.c | 6 ++
mm/percpu.c | 164 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
14 files changed, 235 insertions(+), 6 deletions(-)
# 스터디 log 2차
e31c467..e768777 master -> origin/master
Updating e31c467..e768777
Fast-forward
drivers/gpu/drm/vmwgfx/svga3d_surfacedefs.h | 1 +
include/asm-generic/bitops/non-atomic.h | 4 +
include/linux/bitmap.h | 15 ++
include/linux/bitops.h | 1 +
include/linux/cpumask.h | 13 +-
include/linux/kernel.h | 1 +
include/linux/list.h | 17 ++
include/linux/poison.h | 1 +
include/linux/types.h | 1 +
mm/percpu.c | 258 ++++++++++++++++++++++++++-----
10 files changed, 273 insertions(+), 39 deletions(-)
# 44주차 스터디를 정리해서 그림을 그리면 다음이 된다.
댓글 없음:
댓글 쓰기