[커널 19차] 98 주차
2024.03.23 21:48
static int init_kmem_cache_nodes(struct kmem_cache *s)
{
int node;
for_each_node_mask(node, slab_nodes) {
struct kmem_cache_node *n;
- 이 함수는 각 노드를 순회하면서 kmem_cache_node 구조체를 생성하고 초기화한다.
if (slab_state == DOWN) {
early_kmem_cache_node_alloc(node);
continue;
}
- slab의 state가 DOWN 상태일 때는, kmem_cache_node를 위한 슬랩 캐시가 생성되기 전이므로 수동으로 kmem_cache_node 구조체를 위한 슬랩을 만들고 해당 노드에 필요한 kmem_cache_node 구조체를 생성한 슬랩한 슬랩해서 가져와 초기화해준다.
n = kmem_cache_alloc_node(kmem_cache_node,
GFP_KERNEL, node);
if (!n) {
free_kmem_cache_nodes(s);
return 0;
}
init_kmem_cache_node(n);
s->node[node] = n;
}
return 1;
}
- kmem_cache_node 구조체를 슬랩 캐시에서 가져 올 수 있는 경우, 하나를 가지고 와서 init_kmem_cache_node() 함수를 통해 구조체를 초기화한다. 초기화 완료된 구조체를 kmem_cache의 node 배열에 넣는다.
early_kmem_cache_node_alloc()
/*
* No kmalloc_node yet so do it by hand. We know that this is the first
* slab on the node for this slabcache. There are no concurrent accesses
* possible.
*
* Note that this function only works on the kmem_cache_node
* when allocating for the kmem_cache_node. This is used for bootstrapping
* memory on a fresh node that has no slab structures yet.
*/
static void early_kmem_cache_node_alloc(int node)
{
struct slab *slab;
struct kmem_cache_node *n;
BUG_ON(kmem_cache_node->size < sizeof(struct kmem_cache_node));
slab = new_slab(kmem_cache_node, GFP_NOWAIT, node);
BUG_ON(!slab);
- new_slab()을 통해 해당하는 노드에서 새로운 슬랩 페이지를 생성해서 가지고 온다.
inc_slabs_node(kmem_cache_node, slab_nid(slab), slab->objects);
if (slab_nid(slab) != node) {
pr_err("SLUB: Unable to allocate memory from node %d\\n", node);
pr_err("SLUB: Allocating a useless per node structure in order to be able to continue\\n");
}
- inc_slabs_node()는 현재 kmem_cache의 node 배열에 아무 노드도 세팅되지 않은 상태여서 아무 동작하지 않는다. 이 부분이 왜 필요할까?
- 현재 노드에 메모리가 없는 경우 다른 노드에서 페이지를 할당해 올 수 있는데, 이런 경우 에러 메세지를 띄어준다.
n = slab->freelist;
BUG_ON(!n);
#ifdef CONFIG_SLUB_DEBUG
init_object(kmem_cache_node, n, SLUB_RED_ACTIVE);
init_tracking(kmem_cache_node, n);
#endif
n = kasan_slab_alloc(kmem_cache_node, n, GFP_KERNEL, false);
slab->freelist = get_freepointer(kmem_cache_node, n);
slab->inuse = 1;
kmem_cache_node->node[node] = n;
init_kmem_cache_node(n);
inc_slabs_node(kmem_cache_node, node, slab->objects);
- 새로 생성한 kmem_cache_node 슬랩 페이지에서 객체를 하나 가지고와서 초기화를 해주고 kmem_cache의 node 배열에 넣는다.
- slab의 freelist는 다음 객체를 가르키게 하고 inuse를 1로 변경한다.
- 새로 슬랩 페이지가 생성되었으므로 inc_slabs_node를 통해 관리되고 있는 슬랩 페이지 개수와 객체 개수를 증가시킨다.
- SLUB_DEBUG 설정이 켜져 있는 경우, 레드존과 track 관련된 초기화를 해준다.
/*
* No locks need to be taken here as it has just been
* initialized and there is no concurrent access.
*/
__add_partial(n, slab, DEACTIVATE_TO_HEAD);
}
- 새로 생성된 슬랩페이지도 어디선가 관리를 해줘야 하는데, 방금 생성한 kmem_cache_node의 partial에 넣어 관리한다.
alloc_kmem_cache_cpus()
static inline int alloc_kmem_cache_cpus(struct kmem_cache *s)
{
BUILD_BUG_ON(PERCPU_DYNAMIC_EARLY_SIZE <
NR_KMALLOC_TYPES * KMALLOC_SHIFT_HIGH *
sizeof(struct kmem_cache_cpu));
/*
* Must align to double word boundary for the double cmpxchg
* instructions to work; see __pcpu_double_call_return_bool().
*/
s->cpu_slab = __alloc_percpu(sizeof(struct kmem_cache_cpu),
2 * sizeof(void *));
if (!s->cpu_slab)
return 0;
init_kmem_cache_cpus(s);
return 1;
}
- CPU 별로 kmem_cache_cpu 구조체를 만들고 초기화해주는 함수이다.
- __alloc_percpu()함수를 통해 kmem_cache_cup 구조체를 담을 공간을 CPU마다 할당한다. 이때 cmpxchng를 사용하려면 double word로 정렬되어 있어야 해서 align을 맞춰 할당한다.
- init_kmem_cache_cpus() 함수를 통해 할당한 구조체를 초기화한다.
static void init_kmem_cache_cpus(struct kmem_cache *s)
{
int cpu;
struct kmem_cache_cpu *c;
for_each_possible_cpu(cpu) {
c = per_cpu_ptr(s->cpu_slab, cpu);
local_lock_init(&c->lock);
c->tid = init_tid(cpu);
}
}
- CPU를 순회하며 각 CPU의 kmem_cache_cup 구조체를 초기화한다. 초기 tid는 cpu id이다.
댓글 0
번호 | 제목 | 글쓴이 | 날짜 | 조회 수 |
---|---|---|---|---|
공지 | [공지] 스터디 정리 노트 공간입니다. | woos | 2016.05.14 | 631 |
248 | [커널 19차] 103 주차 | Min | 2024.04.28 | 48 |
247 | [커널 20차] 48주차 | 무한질주 | 2024.04.25 | 51 |
246 | [커널 19차] 102 주차 | Min | 2024.04.20 | 45 |
245 | [커널 19차] 101 주차 | Min | 2024.04.13 | 65 |
244 | [커널 19차] 100 주차 | Min | 2024.04.13 | 19 |
243 | [커널 19차] 99 주차 | Min | 2024.03.30 | 83 |
» | [커널 19차] 98 주차 | Min | 2024.03.23 | 57 |
241 | [커널 19차] 97 주차 | Min | 2024.03.16 | 50 |
240 | [커널 19차] 96 주차 | Min | 2024.03.14 | 32 |
239 | [커널 19차] 95 주차 [2] | Min | 2024.03.03 | 115 |
238 | [커널 20차] 32주차 | brw | 2023.12.16 | 389 |
237 | [커널 20차] 29주차 | brw | 2023.11.27 | 163 |
236 | [커널 20차] 27주차 | brw | 2023.11.21 | 87 |
235 | [커널 20차] 26주차 | brw | 2023.11.21 | 50 |
234 | [커널 20차] 28주차 | 이민찬 | 2023.11.19 | 65 |
233 | [커널 20차] 25주차 | 이민찬 | 2023.10.30 | 120 |
232 | [커널 20차] 24주차 | 이민찬 | 2023.10.22 | 838 |
231 | [커널 20차] 23주차 | 이민찬 | 2023.10.14 | 81 |
230 | [커널 20차] 22주차 | 이민찬 | 2023.10.08 | 77 |
229 | [커널 20차] 21주차 | 이민찬 | 2023.09.23 | 118 |
.