티스토리 뷰

4.6 페이지 할당자 (356P)

노드별 활성화 된 존에서 페이지 할당이 실패한 경우에 대비해 fallback 에 대한 후보 존 리스트를 만든다.

4.6.2 NUMA 메모리 정책 (358P)
Interleave: 해당 태스크에 구성된 노드 세트에서 순서대로 할당을 수행함 ..
bind
preferred
default

 

4-81

__build_all_zonelists -> 최초 실행시 모든 노드에 생성, 각 cpu 별 per-cpu 프레임 캐시 환경 구성

 

4-82

 

build_zonelists
모든 zone 을 돌면서 zone list 를 초기화

다른 노드를 순회하기 위해 비트마스킹으로, while 순회
 * void nodes_clear(mask) clear all bits

* node_order 에 node 를 쌓아뒀다가, build_zonelists_in_zone_order 이런곳에서 사용
* node_load : find_next_best_node 에서 node_load 값을 사용해서 구함. 이 의미는 같은 거리에 있는 node 는 node_load 가 동일하고, 멀리있을수록 load 가 낮아져 그룹화됨. 결국 find_next_best_node 를 구현하기 위해 필요함

 

while ((node = find_next_best_node(local_node, &used_mask)) >= 0) {
  if (node_distance(local_node, node) !=
    node_distance(local_node, prev_node))
    node_load[node] = load;

  load--;


find_next_best_node 로 가까운 노드를 가져옴

build_zonelists_in_node_order 노드 우선 fallback 구성인 경우, 노드0 (존4321) , 노드1(존4321) 같이 가까운 노드 와 존의 역순으로 구성된다.

build_thisnode_zonelists -> 자기 노드껄로만 zonelists[1] 구성

__GFP_THISNODE 값에 따라 zonelists[0], zonelists[1] 사용 여부 결정됨


4.6.5 NUMA 메모리 정책 초기화 (370P)


4-86  numa_policy_init 


kmem_cache -> slab 할당자로 작은 객체를 관리
 - 슬랩 할당자의 기본 아이디어는 비슷한 크기의 객체들을 미리 만들어 놓은 캐시(slab cache)에 저장해 두고, 필요할 때 이 캐시에서 메모리를 재사용하는 것입니다

헉 그러면 kmem_cache_create 이 동작은 실제로 할당받는게 아니라, 큰 블록을 하나 가져와서 이 구조체를 사용할 풀 같은걸 만드는거구나!

부팅시 사용하는 태스크에서는 기본으로 interleave 정책을 사용하는듯 함

NUMA Balancing의 개념
자동 NUMA 밸런싱(Auto NUMA Balancing) 기능은 커널이 NUMA 시스템에서 CPU와 메모리 간의 불균형을 감지하고 조정하는 것입니다. 기본 아이디어는 CPU가 자주 접근하는 메모리 페이지를 CPU가 속한 노드로 옮겨 NUMA 비용을 줄이는 것입니다

 

특징 `MPOL_F_MOF` (Migrate On Fault) `MPOL_F_MORON` (Migrate On `PROT_NONE` Reference)
페이지 이동 트리거 페이지 폴트 발생 시  PROT_NONE` 보호된 메모리에 접근할 때
페이지 이동 상황 프로세스가 메모리에 처음 접근하거나 페이지 폴트가 발생하는 경우 메모리 보호 기능을 사용해 차단된 페이지에 접근하려고 할 때
적용 대상 페이지 일반적인 페이지 폴트가 발생한 메모리 페이지  `PROT_NONE` 설정된 보호된 메모리 페이지
사용 목적 페이지 폴트 시 메모리를 이동하여 **성능 최적화** 보호된 페이지의 접근을 감지하여 **메모리 이동 및 성능 최적화** 

 


4-87 do_set_mempolicy

 

NODEMASK_SCRATCH(scratch) scratch 변수 선언, 두개의 마스크 사용함. NUMA 노드가 256 개 초과하면 별도 메모리 할당해서 사용.  그리고 flag 도 이때 사용 . nodemask_t 가 MAX_NUMNODES 만큼이라 너무 큰 메모리 사용할때

typedef struct { DECLARE_BITMAP(bits, MAX_NUMNODES); } nodemask_t;

struct nodemask_scratch {
nodemask_t mask1;
nodemask_t mask2;
};

scratch 는 임시로 사용하는 공간을 말하는듯..
 
mpol_new -> NUMA 정책과 노드를 같이 넣어서 mempolicy 생성

// policy 에 맞는 bitmap 반환
mpol_set_nodemask {
 
// mask1 에 node 중 살아있는 비트맵과, 현재 허가된 비트맵을 & 하여 set
nodes_and(nsc->mask1, cpuset_current_mems_allowed, node_states[N_MEMORY]);
}



il_next는 이후 메모리 페이지 할당 시 현재 프로세스가 어떤 NUMA 노드에서 메모리를 할당할지를 결정하는 데 사용될 것입니다.

4.6.6 페이지 할당


NUMA 의 alloc_pages_current 는, zonelist 를 가지고 UMA 에서 사용하는 alloc_pages_node 를 호출함.
해당 zone 을 바로 찾은 경우 fastpath, 그렇지 않고 복잡한 로직을 거치는 경우 slowpath 라 한다.

리눅스의 gfp 는 Get Free Pages

 

4-88 (375P)


__alloc_pages_nodemask
high_zoneidx -> 받은 zone 이하 페이지에서만 할당하도록 제한
복잡하지만 fastpath 에서 찾고, slowpath 에서 찾는다 정도
zonelist 는 zoneref 로 구성되고, zoneref 는 zone 과 zone idx 를 사용

 

4-90 (380P)

 

for_each_zone_zonelist_nodemask -> zonelist 에서 해당하는 zone 모두 순회

ALLOC_CPUSET -> cpuset 검사 플래그
cpuset_zone_allowed -> hardwall 같은 cpu 의 설정에 따라 해당 zone 을 상용할수 있는지 gfp 와 비교

ALLOC_FAIR: zone 의 preferred_zone 과 할당 받고싶은 zone 의 노드가 다르면 break 해버렸다.. 왜지?. 근데 나주에 실패하면 ALLOC_FAIR 를 지우고 다시 시도 한다고 함. preferred 를 우선적으로 받고 싶나봄. (fast path 에서 사용)

ZONE_FAIR_DEPLETED 플래그는 해당 존이 공정한 메모리 분배를 위한 자원이 고갈되었음을 나타냅니다. 이존에서 할당받지 못하나보다. 어디서 초기화 되려나? 프리페이지가 없어 페이지 할당을 할 수 없을때 해당 플래그 사용

존의 dirty 상한선을 제한하는 코드
if (ac->spread_dirty_pages && !zone_dirty_ok(zone))
  continue;

zone_allows_reclaim -> node 간의 거리가 너무 멀지 않을 때 true

reclaim은 리눅스 커널에서 메모리 관리의 중요한 개념으로, 사용되지 않거나 더 이상 필요한 메모리 페이지를 해제(reclaim)하여 시스템에 재사용 가능한 메모리 공간을 확보하는 과정을 나타냅니다.

reclaim 모드인 경우, 내꺼에서 재할당 하지 않고 다른 곳꺼 가져온다.

ALLOC_HARDER -> buffered_rmqueue 에서 메모리가 없는 상황일때 비상상황으로 MIGRATE_HIGHATOMIC 요거로 찾아왔었음.
그래서 page_alloc 할때 이런 정보를 담기 위해서 소량의 페이지 블록을 준비한다.

댓글