워터마크 값은 Zone 관리하는 메모리 영역이 얼마나 남았는가를 알려주는 값이다.

 

Linux Kernel에서는 kswapd 라는 데몬이 존재하며 해당 데몬이 free page 부족할 회수를 진행한다.

여기서 데몬이 동작하기 위한 트리거로 워터마크를 활용하며 최소 min_free_kbytes 만큼의 free page 확보하기위해 노력한다.

 

 

1. Free 메모리 여유정도 확인

 

/mm/page_alloc.c

/*
 * Return true if free base pages are above 'mark'. For high-order checks it
 * will return true of the order-0 watermark is reached and there is at least
 * one free page of a suitable size. Checking now avoids taking the zone lock
 * to check in the allocation paths if no pages are free.
 */
bool __zone_watermark_ok(struct zone *z, unsigned int order, unsigned long mark,
 int highest_zoneidx, unsigned int alloc_flags,
 long free_pages)
{
long min = mark;
int o;
const bool alloc_harder = (alloc_flags & (ALLOC_HARDER|ALLOC_OOM));


/* free_pages may go negative - that's OK */
free_pages -= __zone_watermark_unusable_free(z, order, alloc_flags);


if (alloc_flags & ALLOC_HIGH)
min -= min / 2;


if (unlikely(alloc_harder)) {
/*
 * OOM victims can try even harder than normal ALLOC_HARDER
 * users on the grounds that it's definitely going to be in
 * the exit path shortly and free memory. Any allocation it
 * makes during the free path will be small and short-lived.
 */
if (alloc_flags & ALLOC_OOM)
min -= min / 2;
else
min -= min / 4;
}


/*
 * Check watermarks for an order-0 allocation request. If these
 * are not met, then a high-order request also cannot go ahead
 * even if a suitable page happened to be free.
 */
if (free_pages <= min + z->lowmem_reserve[highest_zoneidx])
return false;


/* If this is an order-0 request then the watermark is fine */
if (!order)
return true;


/* For a high-order request, check at least one suitable page is free */
for (o = order; o < MAX_ORDER; o++) {
struct free_area *area = &z->free_area[o];
int mt;


if (!area->nr_free)
continue;


for (mt = 0; mt < MIGRATE_PCPTYPES; mt++) {
if (!free_area_empty(area, mt))
return true;
}


#ifdef CONFIG_CMA
if ((alloc_flags & ALLOC_CMA) &&
    !free_area_empty(area, MIGRATE_CMA)) {
return true;
}
#endif
if (alloc_harder && !free_area_empty(area, MIGRATE_HIGHATOMIC))
return true;
}
return false;
}

function 현재 free page 개수가 워터마크 값의 기준보다 충분한지 아닌지를 판단하는 함수이다.

kernel function 통해서 현재 남은 공간 free 공간이 여유로운지 아니면 데몬을 동작시켜 free확보가 필요한지를 판단할 있다.

 

function에서 여유정도를 판단할 때는 정확한 판단을위해 CMA on/off 메모리 셋업 설정에 따라 계산을 다르게하여 오류를 최소화한다.

 

 

 

 

  • CMA

CMA 연속된 물리메모리를 사용해서 메모리 할당을 하기위한 방법이다.

미리 연속적인 physical memory에할당할 있도록 Linux 부팅이후 CMA라는 별도의 예약공간을 메모리에 할당한다.

이러한 이유로 CMA영역을 따로할당하고 해당 영역을 별도로 관리한다면 워터마크 function에서 해당 공간을 제외하고 계산하여 오차를 줄인다.

 

 

 

 

2. 워터마크 Setup

아래 totalreserve_pages 결국에 kernel에서 사용하는 노드별 할당가능한 모든 reserve page 갯수정도로 보면된다.

/*
 * This is a per-node reserve of pages that are not available
 * to userspace allocations.
 */
unsigned long                totalreserve_pages;

기본적으로 부팅초반에 ZONE HIGHMEM여부 등을 바탕으로 min, max 물론 min_free_kbytes 등을 모두 계산한다.

해당 값들을 계산함으로써 워터마크는 셋업이 된다. 이후에는 셋업된 워터마크를 바탕으로 메모리가 부족한지 여유로운지 판단할 있고

daemon 통해서 free메모리 확보등을 진행할 있다.

 

 

 

 

 

3. 워터마크와 Free메모리 확보를 위한 동작

  • Count 갯 계산

Zone에서 할당된 count(통계) 구하는데 있어서는 zone counter 값과 per-cpu counter값을 더해야 정확한 counter값을 있다. 이는 작은 size 경우 per-cpu 통해 성능을 극대화하는 Linux Kernel 메모리 할당 성격 때문이다.

하지만 매번 per-cpu에 접근하여 개수를 판단하는것은 오히려 성능저하라는 per-cpu 사용하는 의미가 없어지기 때문에 일종의 threshold 잡고 해당 threshold기준이하가 되면 cpu counter 셈으로써 성능과 counter 정확성의 균형을 맞추어 동작한다.

 

 

 

  • ref

코드로 알아보는 ARM 리눅스 커널

https://elixir.bootlin.com/linux/v5.14.16/source/...

+ Recent posts