Unevictable 캐시의 이상한 동작(Linux 커널)

Unevictable 캐시의 이상한 동작(Linux 커널)

내 임베디드 Linux 대상(initramfs 및교환 없음).

스왑이 없기 때문에 /tmp(tmpfs)에 있는 모든 항목이 제거 불가능으로 표시될 것으로 예상합니다. 대신 다음 스크립트를 사용할 때 다음 사항을 관찰합니다.

#!/bin/sh
count=1
while true; do
    echo "#$count"
    dd if=/dev/zero of=/tmp/zero$count bs=1M count=10 && cat /proc/meminfo | grep 'Unevictable\|Shmem'
    count=`expr $count + 1`
    sleep 3
done
  • 10MB의 많은 파일을 쓰는 경우 Shmem은 선형적으로 커지지만 피할 수 없는 메모리는 0KB에서 ~200MB로 매우 빠르게 점프합니다.

    #40
    10+0 records in
    10+0 records out
    10485760 bytes (10.0MB) copied, 0.102484 seconds, 97.6MB/s
    Unevictable:           0 kB
    Shmem:            453776 kB
    #41
    10+0 records in
    10+0 records out
    10485760 bytes (10.0MB) copied, 0.047640 seconds, 209.9MB/s
    Unevictable:           0 kB
    Shmem:            464196 kB
    #42
    10+0 records in
    10+0 records out
    10485760 bytes (10.0MB) copied, 0.101833 seconds, 98.2MB/s
    Unevictable:         884 kB
    Shmem:            474616 kB
    #43
    10+0 records in
    10+0 records out
    10485760 bytes (10.0MB) copied, 0.051686 seconds, 193.5MB/s
    Unevictable:      234612 kB
    Shmem:            485040 kB
    #44
    10+0 records in
    10+0 records out
    10485760 bytes (10.0MB) copied, 0.052157 seconds, 191.7MB/s
    Unevictable:      238568 kB
    Shmem:            495572 kB
    #45
    10+0 records in
    10+0 records out
    10485760 bytes (10.0MB) copied, 0.043332 seconds, 230.8MB/s
    Unevictable:      245332 kB
    Shmem:            505892 kB
    #46
    10+0 records in
    10+0 records out
    10485760 bytes (10.0MB) copied, 0.042653 seconds, 234.4MB/s
    Unevictable:      245332 kB
    Shmem:            516312 kB
    #47
    10+0 records in
    10+0 records out
    10485760 bytes (10.0MB) copied, 0.048478 seconds, 206.3MB/s
    Unevictable:      248384 kB
    Shmem:            526724 kB
    
  • 0개 파일을 모두 삭제해도 제거할 수 없는 메모리는 같은 수준으로 유지됩니다. RAM을 모두 잃어버렸다는 뜻인가요? OOM 킬러가 더 일찍 호출된 것으로 보입니다. 어떻게 되찾을 수 있나요?

    # rm /tmp/zero*
    # cat /proc/meminfo | grep 'Unevictable\|Shmem'
    Unevictable:      288372 kB
    Shmem:             48412 kB
    
  • 10MB 대신 100MB 청크로:

    #1
    100+0 records in
    100+0 records out
    104857600 bytes (100.0MB) copied, 0.422820 seconds, 236.5MB/s
    Unevictable:           0 kB
    Shmem:            150168 kB
    #2
    100+0 records in
    100+0 records out
    104857600 bytes (100.0MB) copied, 0.471385 seconds, 212.1MB/s
    Unevictable:           0 kB
    Shmem:            252516 kB
    #3
    100+0 records in
    100+0 records out
    104857600 bytes (100.0MB) copied, 0.444059 seconds, 225.2MB/s
    Unevictable:           0 kB
    Shmem:            354888 kB
    #4
    100+0 records in
    100+0 records out
    104857600 bytes (100.0MB) copied, 0.414981 seconds, 241.0MB/s
    Unevictable:           0 kB
    Shmem:            457368 kB
    #5
    100+0 records in
    100+0 records out
    104857600 bytes (100.0MB) copied, 5.538392 seconds, 18.1MB/s
    Unevictable:      288264 kB
    Shmem:            559700 kB
    #6
    dd: writing '/tmp/zero6': No space left on device
    

누군가 나에게 커널 버그처럼 보이는 관찰된 동작을 설명할 수 있습니까?

감사합니다

답변1

나는 그것이 tmpfs가 아니라 ramfs라고 생각합니다.

제거 불가능한 목록은 다음과 같은 제거 불가능한 페이지 클래스를 다룹니다.

  • Ramfs가 소유한 것입니다.

  • SHM_LOCK공유 메모리 영역 에 매핑된 것입니다 .

  • VM_LOCKED[mlock()ed] VMA 에 매핑된 것입니다 .

인프라는 정의에 따라 또는 상황에 따라 향후 페이지를 피할 수 없게 만드는 다른 조건도 처리할 수 있습니다.

https://www.kernel.org/doc/Documentation/vm/unevictable-lru.txt

귀하의 질문에 대한 답변으로,빨간 모자"Unevictable"을 "키비바이트 단위의 메모리 양"으로 요약합니다.페이지아웃 코드에 의해 발견됨, 사용자 프로그램에 의해 메모리에 잠겨 있기 때문에 제거할 수 없습니다."

ramfs전체 문서를 읽어보면 어떤 이유로 할당이 일반 LRU 목록에서 시작되는 것처럼 들립니다 Inactive(anon). 사용 가능한 메모리가 부족하고 회수(페이지 아웃) 트리거가 시작되면 목록이 검색되고 VM은 잠긴 메모리를 "검색"하여 제거할 수 없는 목록으로 이동합니다.

관련 메모에도커널 코멘트이는 "Mlocked" 필드가 잠긴 페이지를 즉시 설명하지 못할 수도 있음을 의미합니다. (어떤 경우에는 그럴 수도 있는데 확인해보지는 않았습니다.)

NR_MLOCK,       /* mlock()ed pages found and moved off LRU */

커널이 전체 목록을 한 번에 스캔한다고 가정하지는 않지만 대규모 배치로 스캔할 것으로 예상합니다.

이 이론의 문제점은 스왑이 구성되어 있지 않은 경우 커널이 "anon" 목록을 스캔하는 이유/방법을 모른다는 것입니다. 나는 심지어 그것을 발견했다암호-

/* If we have no swap space, do not bother scanning anon pages. */
if (!sc->may_swap || mem_cgroup_get_nr_swap_pages(memcg) <= 0) {
    scan_balance = SCAN_FILE;
    goto out;
}

관련 정보