티스토리 뷰
4-101, 102
kswapd 는 페이지를 회수하는데, watermark_high 보다 올라가면 잠들고, low 보다 낮아지면 깨어나서 회수를 시작한다.
min_free_kbytes 보다 높아질때까지 kswapd 는 메모리를 확보하고, min 보다 낮아지는 경우는 kswapd 에 의존하기만 하지 않고, 직접 페이지 수행을 시도해본다
page_alloc.c __zone_watermark_ok
alloc_harder = highautomic 용도로 사용되는 reserve 페이지 블록에서도 할당
free_pages 로 들어온 인자는 밖에서 zone_page_stage(z_ NR_FREE_PAGES)) 로 넘어온 값
min = ? 여기에서 min 의 의미가 뭘까? -> 할당 성공률을 높인다고는 하는데,,
min = mark 로 사용했는데, alloc 시 WATER_MARK FLAG 에 따라서 워터마크에 설정된 값이 들어옴. (min,low,high, or none 에 따라?)
그러므로 min 같은걸 설정했으면 더 작은수가 들어왔을 것.
if (free_pages <= min + z->lowmem_reserve[classzone_idx])
return false;
그러니까 이것의 의미는, 내가 할당을 수행하고 나면 남는 페이지 수가 워터마크 이하로 떨어지는 경우 워터마크에서 허락하지 않겠다.
오더가 큰 경우는 버디에 해당 오더의 페이지가 있는지 확인해야 한다. -> 회수를 진행하지 않았을때 머지가 안된 상태이고. 더 높은 오더의 페이지가 있다면 쪼개서 사용할 수 있으니
근데 high atomic 은 왜 검사 안해주냐?
-->
if (likely(!alloc_harder))
free_pages -= z->nr_reserved_highatomic;
alloc harder 가 아닐때는 여기서 이미 뺐기땜문!@!!@!@ / alloc harder 일때는 min 을 줄였음
if (alloc_harder)
return true;
--> migrate 타입 검사 안하고 트루 해버림
4-103
init_per_zone_wmark_min
nr_free_buffer_pages -> water mark high 이상의 페이지 수를 줌.
--> ZONE_HIGHMEM, ZONE_NORMAL, ZONE_DMA 모두 각자 HIGH 워터마크가 있는거였는데, HIGHMEM 이랑 헷갈렸었따.
--> ZONE_NORMAL 이하에서 water mark high 이상을 뺀 페이지 수를 구했던 것
gpt: nr_free_buffer_pages 함수는 특정 워터마크 기준(WMARK_HIGH)보다 여유가 있는 페이지 수를 반환합니다. 이 값은 현재 사용 가능한 메모리 양이 워터마크에 대해 얼마나 안정적인지를 나타내는 지표로 볼 수 있습니다.
lowmem_kbytes -> node 에서 계산되고, 이걸 가지고 각 zone 에서 처리 되는걸로 보임
여기서 10 씩 >> 땡긴게 kbytes 라 그렇구나
4-104
__setup_per_zone_wmarks
zone 은 아래 페이지 타입을 갖고 있었음
unsigned long managed_pages;
unsigned long spanned_pages;
unsigned long present_pages;
이중에 lowmem_pages 는 managed_pages 를 합산해서 사용함. 근데 저 페이지들이 뭔지 까먹었음.
spanned_pages = zone_end_pfn - zone_start_pfn; -> 전체
present_pages = spanned_pages - absent_pages(pages in holes); -> hole 제거
managed_pages = present_pages - reserved_pages; -> reserved pages 제거인데 reserved 가 뭐더라
tmp = (u64)pages_min * zone->managed_pages;
do_div(tmp, lowmem_pages);
-> zone 의 managed_pages 비율만큼 중에서 pages_min 곱한만큼 가져감
highmem 인 경우는 아주 작게 설정하는 걸로 보임
tmp 가 MIN 까지는 비율로 바로 처리했었음. 여기서 scale_factor 를 적용하는 값으로 LOW, HIGH 를 구함
tmp >> 2 로 4로 나눴으니 25% 로 줄인 값과 watermark_scale_factor 에 따라 결정된 값을 max
4-105
calculate_totalreserve_pages
모든 node 의 모든 zone 을 순회 한다.
watermark 의 비율은 ZONE_HIGHMEM 를 제외하고는 비율에 따라 된거고
lowmem_reserve -> 다른 zone 꺼의 lowmem 을 미리 예약해둔건가? 이중에 max 를 찾아서 reserve 로 처리하고있음
근데 아직 잘모르겠다.
gpt: memblock의 lowmem은 시스템 부팅 시 사용 가능한 저메모리 영역을 관리하는 반면, zone의 lowmem_reserve는 이미 예약된 페이지 수를 관리하여 시스템 메모리의 안정성을 높이는 데 초점을 맞추고 있습니다.
4-106, 4-107
refresh_zone_stat_thresholds
원래는 존과 각 cpu 의 카운터를 다 더해야 하는데, 성능상 아까우니까 thresholds 보다 크면 대충 계산하겠다.
모든 zone 을 순회해서, 해당 zone 의 threshold 를 계산한다.
tolerate = 참을 수 있는 수준
max = 최대치
fls -> find last set bit
이게 맞아?
Gpt: 이 조건문은 max_drift가 tolerate_drift보다 클 경우, 즉 모든 CPU가 동시에 요구할 수 있는 최대 메모리량이 현재 존에서 수용할 수 있는 여유 공간보다 클 때를 체크합니다.
4-108
setup_per_zone_lowmem_reserve
일단 자기 zone 이 자기를 가리키는 lowmem_reserve 를 0으로 초기화
그리고 자기 아래 zone 들에 대해 (normal 이었다면 dma 에 대해, high 였다면 normal dma 에 대해)
해당 zone 의 lowmem_reserve_ratio 만큼을 내 managed_pages 에 적는다. 아 그러니까 normal 이었다면 dma 영역도 쓸 수 있다는 뜻인듯. 그래서 managed_pages 에 lower_zone 의 managed_pages 를 점점 추가함
409 page
setup_per_zone_inactive_ration
mangaed_pages 에 따라 inactive anon 페이지 비율을 정하는데, 이게 뭐 실제 비율도아니고 그냥 페이지 수에따라 비율이 정해지는데 이게 왜필요한거지?
gpt: 메모리 압박 감지: 시스템에서 메모리 사용량이 증가하고, 비활성 익명 페이지가 부족할 때 이 함수가 호출됩니다
일정 비율보다 떨어지면 필요한 페이지를 가져와야 하나보다
inactive_anon_is_low_global
inactive_anon_is_low
check if anonymous pages need to be deactivated
4.7 슬랩 할당자
- 슬랩, 슬럽, 슬롭 중 하나를 선택
- 여기서는 슬럽을 기준으로 알아보자
사용중인 객체 / 빈 객체 (free)
빈 객체는 서로 FreePointer (FP) 를 통해 연결
kmem_cache 는 커널 메모리 슬랩 캐시의 약자.
4-109
kmem_cache_init
boot_kmem_cache -> kmem_cache 라는 구조체를 슬랩 객체로 할당해주기 위한 슬랩 캐시
boot_kmem_cache_node -> kmem_cache_node 라는 구조체를 슬랩 객체로 할당하기 위한 슬랩 캐시
근데 둘다 kmem_cache 구조체로 만들어졌음!!!!
static __initdata struct kmem_cache boot_kmem_cache, boot_kmem_cache_node;
void __init create_boot_cache(struct kmem_cache *s, const char *name, size_t size,
unsigned long flags)
4-110, 4-111
create_boot_cache
kmem_cache 에 값을 설정. 그러나 kmem_cache 의 정확한 용도는 파악이 되지 않은 상태
object 의 사이즈와 align 을 설정 (hardware align 의 경우 default 는 L1 cache bytes (8k~64k)
gpt: 캐시 바이트 사이즈와 데이터 캐시라인 크기는 다른 정의
- 정의: 캐시 바이트 사이즈는 전체 캐시 메모리 용량을 의미하며, 캐시에 저장할 수 있는 데이터의 총 양입니다.
- 일반적으로 L1 데이터 캐시의 캐시 라인 크기는 64바이트입니다.
mcg: Memory Resource Controller. 메모리 접근 가능에 대한 설정인듯?
memcg_params 을 설정
RCU_INIT_POINTER -> Read Copy Update 포인터??
__kmem_cache_create(s, flags); // flags = SLAB_HWCACHE_ALIGN
4-112
bootstrap
kmem_cache (전역) = &boot_kem_cache
bootmem 으로 만들었던 kmem_cache 를 memcpy 로 복사함. object size 만큼 복사하는걸 보니 딱 하나만 있던 상태
IPI(Inter-Processor Interrupt)는 Inter-Processor Interrupt의 약자로, 다중 프로세서 시스템에서 하나의 CPU가 다른 CPU에게 특정 작업을 수행하라고 요청하는 인터럽트
gpt: smp_processor_id는 Linux 커널에서 현재 실행 중인 CPU의 ID를 반환하는 함수입니다. SMP(대칭 멀티 프로세싱) 시스템에서 각 CPU는 고유한 ID를 가지며, smp_processor_id 함수를 통해 현재 코드를 실행 중인 CPU의 ID를 확인할 수 있습니다.
그러니까 내 로컬 cpu 에서 slab 캐스를 플러시한다는 뜻인가?
4-113
setup_kmalloc_cache_index_table
- 사이즈에 따라 배열에 값을 지정하는데, 그림 4-80 은 초기 배열의 상태이고, 4-81 은 setup_kmalloc_cache_index_table 을 실행하면 저렇게 바뀜
min 사이즈가 작을때 넣어놨던 최적화 코드가 사이즈가 크다면 쓸 필요 없으니 없앰
'개발 > 코드로 알아보는 ARM 리눅스 커널 TIL' 카테고리의 다른 글
20241116 4.7.5슬랩 페이지와 슬랩 객체 할당 (p442) (1) | 2024.11.21 |
---|---|
20241109 4.7.4 kmem 캐시 생성 (p426) (0) | 2024.11.21 |
20241026 4.6.9 slowpath 페이지 할당 (p388) (0) | 2024.11.20 |
20241019 4.6 페이지 할당자 (p356) (0) | 2024.11.20 |
20241012 4.4.4 버디 시스템의 페이지 해제 (p336) ~ 4.5 pcp (355) (0) | 2024.11.20 |
- Total
- Today
- Yesterday
- 클래스 맴버 변수 출력하기
- hole-punching
- 잘못된 빨간줄
- Visual Studio
- Quest2
- 카카오
- 봄날에 스케치
- it's called a vrpit
- vr핏
- 코어 남기기
- red underline
- 우리는 vr핏이라고 부릅니다
- print shared_ptr class member variable
- C++
- 에러 위치 찾기
- 면접
- cockroach db
- set value
- RVO
- vrpit
- mysql
- boost
- Golang
- 영상 픽셀화 하기
- Reciprocal n-body Collision Avoidance
- chrome-extension
- shared_from_this
- ad skip
- SuffixArray
- Obstacle Avoidance
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |