Q&A 게시판

리눅스 커널에 대한 Q&A 게시판 입니다. (비밀글 체크는 꼭 필요한 경우에만)

ZONE_MOVABLE에서 unmovable 페이지를 피하는 방법이 궁금합니다.

작성자
ZZonZzon
작성일
2022-09-08 16:21
조회
133
안녕하세요?
항상 잘 정리해주신 자료 너무 감사하고 유용하게 보고 있습니다.

한 가지 질문이 있습니다.
http://jake.dothome.co.kr/kboard/?mod=document&uid=26 설명에서
ZONE_MOVABLE을 설정하면 커널에서 할당 요청하는 unmovable 페이지 요청들이 ZONE_MOVABLE을 피한다고 설명해 주셨는데
어떠한 원리로 피하는지 추가 설명 부탁 드려도 될까요??

ZONE_MOVABLE이 최상위 주소에 존재하고, 커널 할당 요청은 낮은 주소 (lowmem)에서 부터 시작되기때문에 피할 수 있는건가요?

항상 감사합니다^^
전체 4
  • 2022-09-13 15:05
    안녕하세요? ZZonZzon님,

    추석 명절로 인해 답변이 늦어졌습니다. 양해해주시길 바랍니다. ^^

    movable 페이지는 크게 2개의 사용처가 있습니다.
    1) user application이 메모리를 요청하면 heap 관리자가 필요시 커널로 메모리를 요청하는 anon 페이지
    2) 사용자의 파일 access 시마다 커널 백그라운드에서 할당하는 페이지 캐시

    잘 아시겠지만, 위의 movable 페이지와 다르게 커널 내부에서 커널이 필요해서 할당하는 페이지는 unmovable 페이지이고 당연히 이동할 수 없습니다. 버디 시스템은 각각의 mobility 속성(unmovable, reclaimable, movable, ..)에서 오더(order) 페이지 단위로 페이지들을 관리합니다. 버디 시스템에서 페이지의 단편화에 악영향을 주는 것이 높은 오더 페이지와 unmovable 등의 페이지들입니다. 따라서 가능하면 커널은 movable 블럭에 unmovable 페이지가 섞이지 않도록 알고리즘을 사용합니다. 될 수 있으면 메모리가 부족해지지 않으면 같은 mobility 속성 내에서만 페이지를 할당해줍니다. 즉 movable 페이지 블럭내에는 1개 이상의 여러 movable 페이지들로 가득 찰겁니다.

    물론 메모리가 부족해지는 경우 movable 페이지 블럭에서 일부 페이지를 steal하여 unmovable로 할당할 수도 있습니다.
    커널이 사용하는 unmovable 페이지들은 타입이 아주 많지만 그래도 가장 많이 사용하는 용도는 주로 페이지 테이블들과 DMA 페이지들입니다. 그 중 DMA 페이지들은 보통 CMA 영역이나 DMA용 reserve 영역으로 분리하여 사용하므로 큰 문제는 없습니다.


    즉 질문하신 내용처럼 커널이 unmovable 페이지를 요청하면 unmovable이 뭉쳐있는 페이지 블럭내에서 먼저 시도합니다.

    참고로 mm/page_alloc.c 파일에서 메모리 부족시 __rmqueue_fallback() -> find_suitable_fallback() -> can_steal_fallback()을 체크하여 steal 가능한지 확인하는 로직들이 있으므로 참고하시기 바랍니다.

    감사합니다.

    문영일 드림.

  • 2022-09-14 10:53
    영일님께서도 추석 명절 잘 보내셨나요?^^
    친절한 답변 감사합니다^^
    헤매고 있었는데 친절한 답변 덕분에 조금씩 방향을 잡아가고 있는 것 같습니다.^^

    한 가지 더 궁금한 것이 있습니다.
    그렇다면 ZONE_MOVABLE에선 unmovable page block으로부터의 할당이 발생하지 않는 것인가요?
    알려주신 call path를 살펴보았지만 "ZONE_MOVABLE일 때는 unmovable page를 할당하지 않는다"라는 내용의 코드를 찾지 못했습니다 ㅠㅠ
    (제가 분석이 틀렸을 수도 있습니다ㅠ)

    ZONE_NORMAL, ZONE_CMA, 등등에선 설명해 주신 방법처럼
    1) 처음부터 unmovable page 할당 요청 2) fallback-path로 unmovable page 할당이 발생할 수 있는 것이라 이해하였습니다.
    하지만 ZONE_MOVABLE에선 가능하면 unmovable page를 할당하지 않는 것으로 알고 있는데
    어떻게 unmovable page 할당을 피하는지 궁금합니다.

    답변 주셔서 정말 감사드리고, 영일님께서 잘 정리해주신 덕분에 많은 힘 되고 있습니다^^
    감사합니다!

  • 2022-09-15 00:29
    ZONE_MOVABLE은 hot-plug 메모리 등에 사용되어야 하므로 반드시 이동 가능한 메모리만 사용되어야 하므로,
    unmovable 페이지들이 존재할 수 없는 영역인데 이를 설명드립니다.

    먼저 unmovable 페이지 요청은 커널 메모리 할당 요청 시 발생합니다.
    페이지 할당 API 등에 인자로 GFP_ATOMIC, GFP_KERNEL, GFP_DMA, GFP_DMA32 플래그 등을 사용하여 요청합니다.

    코드를 따라가보면
    __alloc_pages(GFP_KERNEL, ...) -> prepare_alloc_pages() 함수에서 GFP 플래그를 분석하여 ac->highest_zoneidx 값을 알아오는데, 이렇게 알아온 존 이하에서만 페이지를 할당하라는 제한입니다.

    예를 들어 두 가지 GFP 플래그 요청을 사용하면 다음과 같이 처리합니다.
    1) __alloc_page(GFP_KERNEL, ...) 형태로 요청하면 GFP_KERNEL 플래그에 대응하는 ZONE_NORMAL 이하의 존에서만 메모리를 할당합니다.
    fallback 존리스트를 통해 ZONE_NORMAL의 메모리가 부족해지면 ZONE_NORMAL -> ZONE_DMA32 -> ZONE_DMA 순으로 존을 이동하여 할당합니다.

    2) __alloc_page(GFP_DMA, ...) 형태로 요청하면 GFP_DMA 플래그에 대응하는 ZONE_DMA 이하의 존에서만 메모리를 할당합니다.
    ZONE_DMA의 인덱스가 최하위이기 때문에 다른 존에서 할당은 불가능합니다.

    감사합니다.

  • 2022-09-15 01:07
    친절한 설명 다시 감사합니다!
    이미 관련 내용도 잘 정리 해주셔서 큰 도움 되었습니다^^
    (http://jake.dothome.co.kr/zone-api/)

    저도 자료를 좀 더 찾아봤는데,
    ZONE_MOVABLE로만 구성된 movable-node가 설정된 상황이라면, 커널 부팅시 사용하는 커널 메모리(memblock)에 대해서도
    최대한 movable-node를 피해가는 내용이 있더라구요
    (https://events.static.linuxfound.org/sites/events/files/lcjpcojp13_chen.pdf ,chap06)
    코드로 치면 setup_arch() -> memblock_set_bottom_up(true); 부분이 관련 있다고 파악하고 있습니다.
    공유 차원에서 남겨 보았습니다.

    감사합니다!