[커널 17차] 56주차

2021.10.03 02:19

ㅇㅇㅇ 조회 수:27524

percpu 이론
- http://jake.dothome.co.kr/per-cpu/
- http://jake.dothome.co.kr/setup_per_cpu_areas/

 

setup_per_cpu_areas()
- pcpu_embed_first_chunk() 함수로 percpu 1st chunk를 embedded 방식으로 생성한다
 

pcpu_embed_first_chunk()
- reserved size, dynamic size, atomic size, cpu distance 계산 함수, 메모리 allocation 함수, 메모리 dealloc 함수를 받아서 embedded 방식으로 1st chunk를 생성한다

 

- 함수 pcpu_build_alloc_info()로 percpu data를 allocation하기 위한 자료 구조인 alloc info 구조체를 생성한다
- alloc info의 static size, reserved size, dynamic size를 모두 더해 size_sum을 계산
- nr_groups 만큼의 포인터를 저장할 수 있는 메모리를 memblock으로 할당받고 areas에 assign한다
- 각 group에 대해 총 unit size만큼의 메모리를 memblock으로 할당받고 이를 areas[group]가 가리키도록 한다
- 이 때 group의 첫 번째 cpu의 nid로 nid를 지정하여 메모리를 할당 받는다
- 각 group의 메모리 중 가장 높은 시작 주소와 가장 낮은 시작 주소(base)의 차를 구하고 가장 높은 시작 주소의 unit size 총 크기를 더해서 max_distance를 계산한다
- max_distance가 VMALLOC_TOTAL의 75% 이상이 되면 할당한 메모리를 모두 해제하고 리턴한다 (리턴 후 커널 패닉)
- 각 group의 각 unit에 대해 __per_cpu_load(__per_cpu_start와 동일 지점)로부터 static size 만큼 복사하여 percpu 데이터를 복사한다. 그리고 unit size에서 size sum 이상의 영역은 메모리 해제한다. 또한 possible cpu가 아닌 unit은 통째로 메모리 해제한다
- 각 group에 대해서 base_offset을 각 group의 메모리 영역과 base의 차이로 업데이트한다.
- 할당한 pcpu 메모리 영역에 대한 정보를 커널로그로 출력한다
- pcpu_setup_first_chunk()로 할당한 메모리에 1st chunk를 setup한다
- 필요없어진 areas, alloc info 메모리를 모두 해제하고 리턴한다.

 

 

pcpu_build_alloc_info()
- percpu data를 allocation하기 위한 자료 구조인 alloc info 구조체를 생성한다

- dynamic size가 12KB보다 작으면 12KB으로 조정한다
- static, reserved, dynamic size를 더해서 min_unit_size을 계산하고 이 값이 32KB보다 작으면 32KB로 조정한다
- min_unit_size를 atom_size 단위로 round up하여 alloc_size를 계산한다
- 따라서 unit size가 atom_size보다 비슷하거나 크면 upa (unit per allocation)은 항상 1이고 allocation 1개에 unit 1개만 들어간다
- 그러나 unit size가 atom_size보다 훨씬 작으면 alloc_size는 atom_size가 되고 upa는 1보다 커진다. 그리고 한 개 allocation에 여러 개의 unit이 들어간다.
- unit size가 page align되고 alloc size가 unit size의 배수가 될 때까지 upa를 감소 (unit size 증가) 시킨다.
- 모든 possible cpu들에 대해서 cpu distance를 계산하여 group으로 분류한다. cpu간 거리가 LOCAL_DISTANCE보다 크면 새로운 group을 만들고 cpu들을 할당한다
- 각 group에 대해 memory size를 allocation한다. 이 때 각 group은 최소 단위로 allocation size만큼씩 할당을 받는다. 따라서 group에 cpu (=unit)이 13개가 있고 upa=5일 경우 해당 group은 3개의 allocation을 할당받는다. 그리고 나머지 2개 만큼의 unit은 wasted size가 된다. 만약 wasted unit 개수가 전체 possible cpu 개수의 1/3을 넘으면 upa을 감소시키고 다시 allocation을 수행한다. 새로운 upa가 unit size가 page align되고 alloc size가 unit size의 배수의 조건을 만족시키지 못하면 다시 upa를 감소시키고 다시 allocation을 수행한다
- 각 group의 unit 수를 upa로 round up하여 모두 더해 nr_units를 계산한다
- 함수 pcpu_alloc_alloc_info()로 alloc info 구조체를 위한 메모리를 할당받는다 (포인터 ai)
- 각 group의 cpu_map이 각 group의 cpu_map 시작 지점을 가리키도록 한다 (각 group의 unit 개수를 upa로 round up하여 더한 값을 누적하여 시작 지점 계산)
- alloc info 구조체에 static size, reserved size, dynamic size, unit size, atom size, alloc size를 업데이트한다
- alloc info의 group info의 base_offset을 임시 초기화한다
- 각 group에 속하는 cpu를 group info의 cpu_map에 매핑하고 group info의 nr_unit도 업데이트한다 (nr_unit은 upa에 맞게 roundup)
- 만들어진 alloc info를 리턴한다

 


pcpu_alloc_alloc_info()
- nr_groups, nr_units를 인수로 받아 percpu 자료구조의 메모리 할당을 위한 alloc info 구조체를 위한 메모리를 할당한다

- pcpu_alloc_info 구조체 ai를 위한 메모리 사이즈를 계산하고 memblock으로 할당한다
- 첫 번째 group의 cpu_map을 전체 cpu_map 데이터의 첫 시작점을 가리키도록 한다
- cpu_map을 모두 NR_CPUS로 초기화한다
- ai의 nr_groups와 ai_size를 업데이트하고 ai 포인터를 리턴한다

XE Login