[커널 17차] 83주차

2022.04.03 00:00

ㅇㅇㅇ 조회 수:92

kmem_cache_free_bulk()
- kmem_cache type의 slab cache object를 size 개수만큼 반환한다
- 인자로 들어온 p 배열에 object가 들어있다
- L3625 : 함수 memcg_slab_free_hook()로 memcg 관련 처리 및 stat 업데이트를 수행한다
- L3629 : 함수 build_detached_freelist()로 p 배열에서 같은 페이지에 속하는 오브젝트들을 모아서 df의 list에 달아준다. 반환되는 size는 남은 오브젝트의 개수이다.
- L3630 : df.page가 비어 있으면 continue로 루프 재개
- L3633 : 함수 slab_free()로 df의 list에 달린 object들을 해제한다
- L3634 : size가 0이 될 때까지 루프를 반복한다

 

build_detached_freelist()
- 길이 size인 배열 p에 존재하는 slab cache type s의 object들 중 같은 페이지에 속한 것들을 모아서 df의 list에 달아준다
- 이 때 p 배열의 뒤에 있는 object 부터 처리한다
- L3548 : 다른 페이지에 있는 object가 중간에 나오면 3번까지는 넘어가며, 그 이후엔 처리를 중단하고 리턴한다
- L3553 : df->page = NULL로 초기화한다
- L3556 : p 배열의 끝에 있는 object를 가져온다
- L3558 : p 배열이 남아있는데 object가 NULL이면 다음 object로 패스한다
- L3560 : p 배열이 모두 NULL이면 리턴한다
- L3563 : object의 page를 가져온다
- L3564 : slab cache type이 있는 경우 (kmalloc()으로 할당받은 경우가 아닌 경우) if 문으로 들어간다
- L3566 : kmalloc() 할당 받은 경우에는 함수 free_nonslab_page()로 버디로 메모리를 반환하고 p[size] = NULL로 만든 뒤 size를 리턴한다
- L3572 : kmem_cache로 할당 받은 경우에는 df->s = page->slab_cache를 달아준다
- L3574 : slab cache type이 없으면 함수 cache_from_obj()로 object로부터 slab cache type을 구해서 df->s에 달아준다
- L3577 : kfence 처리는 패스
- L3585 : df->page에 object 페이지를 달아준다
- L3586 : 현 object를 df->freelist에 달아준다
- L3589 : p[size] = NULL로 현 object를 p 배열에서 제거
- L3590 : df->cnt = 1로 초기화
- L3592 : size가 0이 될 때까지 while 문 수행
- L3593 : p 배열의 뒤에서 object를 가져온다
- L3594 : object가 NULL이면 다음 object로 넘어간다
- L3598 : df->page가 현 object page와 동일하면 if 문 수행
- L3600 : 현 object를 df->freelist 첫 번째로 추가하고, df->cnt를 증가시킨다. 그리고 p 배열에서 현 object를 제거한 뒤 continue
- L3609 : 현 object page가 df->page와 다르면 p 배열에서 현재 위치를 first_skipped_index에 기록한다. 만약 이렇게 page가 다른 object가 3번째 나온 경우에는 break하여 loop를 나와서 first_skipped_index를 리턴한다

 

kmem_cache_release()
- kobject로부터 소속 slab을 구해서 해당 slab cache를 제거한다
- 함수 slab_kmem_cache_release()를 호출

 

slab_kmem_cache_release()
- 함수 __kmem_cache_release()로 node와 percpu, random sequence 메모리를 제거한다
- 함수 kfree_const()로 slab cache의 이름 메모리를 제거한다
- 함수 kmem_cache_free()로 slab cache 메모리를 제거한다

 

__kmem_cache_release()
- 함수 cache_random_seq_destroy()로 slab cache의 random seq 메모리 제거
- 함수 free_percpu()로 slab cache의 cpu slab 제거
- 함수 free_kmem_cache_nodes()로 slab cache의 node partial list 메모리 제거

 

cache_random_seq_destroy()
- kfree()로 cachep->randomseq 메모리를 해제한다
- cachep->randomseq = NULL로 만든다

 

free_kmem_cache_nodes()
- 매크로 for_each_kmem_cache_node()로 모든 node를 루프를 돌면서 아래를 수행한다
-  s->node[node] = NULL로 만들고 함수 kmem_cache_free()로 각 노드의 kmem_cache_node 메모리를 해제한다

 

kfree_const()
- 함수 is_kernel_rodata()로 인자로 들어온 주소가 rodata 영역이 아니면 kfree()로 주소의 메모리를 해제한다

 

kmem_cache_create()
- kmem_cache_create_usercopy()를 호출한다

 

kmem_cache_create_usercopy()
- L326 : 플래그에 디버그 옵션이 있는 경우 static key slub_debug_enabled를 on 시킨다
- L330 : slab_mutex를 잡는다
- L332 : Sanity check를 수행한다. 이름이 NULL이거나, 인터럽트 내부이거나, 크키가 4MB보다 크면 에러를 리턴한다
- L338 : 플래그에 허용되지 않는 옵션이 있어도 에러 리턴
- L349 : 플래그를 캐시 생성에 유효한 옵션으로 마스킹한다
- L352 : user size/user offset 에러 체크를 수행하고 이상하면 둘 다 0으로 조정한다
- L356 : usersize = 0이면 함수 __kmem_cache_alias()로 이미 생성된 slab cache 중 alias로 사용될 수 있는 것을 찾는다
- L358 : 찾았으면 slab_mutex를 풀고 slab cache를 리턴한다
- L361 : 못 찾은 경우 함수 kstrdup_const()로 이름을 복사한다
- L367 : 함수 create_cache()로 slab cache를 새로 생성하여 반환한다
- L376 : slab_mutex를 풀고 slab cache를 리턴한다

 

__kmem_cache_alias()
- L4859 : 함수 find_mergeable()로 merge 가능한 slab cache를 찾는다
- L4860 : 찾았으면 s->refcount를 1 증가시킨다
- L4867 : s->object_size를 새 object size 만큼 증가시킨다. s->inuse도 같이 증가시킨다. merge의 경우 debug option 즉, redzone, poison, RCU, user track 등은 모두 없는 경우이므로 문제없다. 또한 free pointer offset은 건드리지 않으므로 freelist 동작에도 영향이 없다
- L4870 : 함수 sysfs_slab_alias()로 slab alias list에 새로 들어온 slab cache 이름을 추가한다
- L4876 : 찾은 slab cache를 반환한다

 

find_mergeable()
- L199 : 전역 변수 slab_nomerge = true로 설정되어 있으면 그냥 리턴
- L202 : contructor가 있어도 그냥 리턴
- L205 : size를 8B align + 함수 calculate_alignment()으로 align 시킨다. 또한 함수 kmem_cache_flags()로 플래그를 조정한다
- L210 : Merge될 수 없는 플래그인 경우 그냥 NULL 리턴한다
- L213 : 전역 변수 list slab_caches에 대해서 루프를 돌면서 아래를 수행한다
- L214 : 함수 slab_unmergeable()로 현재 slab cache가 merge 될 수 없으면 continue
- L217 : 새로 요청된 size가 s->size보다 크면 continue
- L220 : Merge 되기 위해 일치해야 하는 플래그가 일치하는지 체크한다
- L226 : s->size와 align이 호환되는지 확인한다
- L229 : s->size와 size가 일치하는지 확인한다
- L236 : 찾은 slab cache를 반환한다
- L238 : 못 찾은 경우 NULL 리턴

 

sysfs_slab_alias()
- L5975 : slub_state == FULL인 경우 sysfs를 이용하여 symbolic link 작업을 수행한다. 현재는 FULL이 아니므로 패스한다
- L5983 : 새로운 alias를 위한 메모리를 할당받는다
- L5987 : 새 alias에 이름, 사용할 slab cache를 달고 alias_list에 달아 준다
- L5991 : 0을 리턴한다

 

kmem_cache_destroy
- L502 : slab cache == NULL이면 그냥 리턴
- L505 : 함수 cpus_read_lock()으로 cpu read lock을 잡는다
- L506 : slab_mutex를 잡는다
- L508 : s->recount를 감소시킨다 (alias 감소)
- L509 : 여전히 alias 남아있으면 mutex unlock하고 cpu read unlock하고 리턴
- L512 : 함수 shutdown_cache()로 slab cache를 삭제한다
- L519 : mutex unlock하고 cpu read unlock하고 리턴

 

shutdown_cache()
- L464 : kasan 관련 처리 수행
- L466 : 함수 __kmem_cache_shutdown()로 각 node의 slab page들을 삭제한다
- L469 : 전역 변수 slab_caches에서 현 slab cache를 제거한다
- L471 : RCU를 사용하는 경우 처리
- L478 : RCU를 사용하지 않는 경우 처리. kfence/debugfs/sysfs 등을 처리한 뒤 함수 slab_kmem_cache_release()로 slab cache 메모리를 제거한다
- 두 경우 모두 sysfs 및 scheduler를 본 뒤에 봐야 할 듯
- L488 : 0을 리턴한다

__kmem_cache_shutdown()
- L4291 : 함수 flush_all_cpus_locked() —> ??
- L4293 : 함수 free_partial()로 각 노드 별 해당 slab cache의 node partial list를 제거한다
- L4298 : 0을 리턴한다

 

free_partial()
- L4252 : discard list를 만든다
- L4256 : node list lock을 잡는다
- L4257 : node partial list에 있는 slab page를 하나씩 가져온다
- L4258 : page->inuse = 0이면 해당 페이지를 노드 리스트에서 제거하고 대신 discard list에 추가한다
- L4262 : page->inuse != 0이면 사용 중이므로 함수 list_slab_objects()로 에러 처리를 수행한다
- L4266 : node list lock을 푼다
- L4268 : discard list를 순회하면서 함수 discard_slab()로 page를 메모리 해제한다

 

list_slab_objects()
- L4229 : 함수 slab_err()로 페이지와 슬랩에 대한 에러 메시지를 출력한다
- L4230 : page lock을 잡는다
- L4232 : 함수 get_map()로 object map lock을 잡고 freelist object가 1로 set되어 있는 bitmap을 만든다
- L4233 : page의 object에 대해서 루프를 돌면서 bitmap이 0인 object가 나타나면 오브젝트와 주소, offset에 대한 정보를 출력한다
- L4240 : 함수 put_map()으로 object map lock을 푼다
- L4241 : page lock을 풀고 리턴한다

번호 제목 글쓴이 날짜 조회 수
공지 [공지] 스터디 정리 노트 공간입니다. woos 2016.05.14 627
128 [커널 17차] 94주차 ㅇㅇㅇ 2022.06.19 80
127 [커널 18차] 56주차 kkr 2022.06.18 71
126 [커널 17차] 92~93주차 ㅇㅇㅇ 2022.06.11 93
125 [커널 18차] 54주차 kkr 2022.06.04 82
124 [커널 19차] 3주차 리턴 2022.06.04 217
123 [커널 18차] 53주차 kkr 2022.05.29 93
122 [커널 17차] 91주차 ㅇㅇㅇ 2022.05.28 64
121 [커널 19차] 2주차 리턴 2022.05.28 169
120 [커널 17차] 90주차 ㅇㅇㅇ 2022.05.22 149
119 [커널 18차] 52주차 kkr 2022.05.21 124
118 [커널 19차] 1주차 리턴 2022.05.16 456
117 [커널 17차] 89주차 ㅇㅇㅇ 2022.05.15 65
116 [커널 18차] 51주차 kkr 2022.05.14 159
115 [커널 18차] 50주차 kkr 2022.05.10 207
114 [커널 17차] 88주차 ㅇㅇㅇ 2022.05.08 101
113 [커널 19차] 0주차 - 오리엔테이션 리턴 2022.05.07 600
112 [커널 17차] 86~87주차 ㅇㅇㅇ 2022.04.30 101
111 [커널 17차] 84~85주차 JSYoo5B 2022.04.16 86
» [커널 17차] 83주차 ㅇㅇㅇ 2022.04.03 92
109 [커널 17차] 82주차 ㅇㅇㅇ 2022.03.27 65
XE Login