[커널 19차] 98 주차

2024.03.23 21:48

Min 조회 수:55

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이다.

 

번호 제목 글쓴이 날짜 조회 수
공지 [공지] 스터디 정리 노트 공간입니다. woos 2016.05.14 626
248 [커널 19차] 103 주차 Min 2024.04.28 4
247 [커널 20차] 48주차 무한질주 2024.04.25 22
246 [커널 19차] 102 주차 Min 2024.04.20 37
245 [커널 19차] 101 주차 Min 2024.04.13 63
244 [커널 19차] 100 주차 Min 2024.04.13 16
243 [커널 19차] 99 주차 Min 2024.03.30 82
» [커널 19차] 98 주차 Min 2024.03.23 55
241 [커널 19차] 97 주차 Min 2024.03.16 50
240 [커널 19차] 96 주차 Min 2024.03.14 32
239 [커널 19차] 95 주차 [2] Min 2024.03.03 111
238 [커널 20차] 32주차 brw 2023.12.16 386
237 [커널 20차] 29주차 brw 2023.11.27 161
236 [커널 20차] 27주차 brw 2023.11.21 86
235 [커널 20차] 26주차 brw 2023.11.21 48
234 [커널 20차] 28주차 이민찬 2023.11.19 64
233 [커널 20차] 25주차 이민찬 2023.10.30 120
232 [커널 20차] 24주차 이민찬 2023.10.22 744
231 [커널 20차] 23주차 이민찬 2023.10.14 81
230 [커널 20차] 22주차 이민찬 2023.10.08 76
229 [커널 20차] 21주차 이민찬 2023.09.23 116
XE Login