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
    
  • 如果我刪除所有零文件,不可清除的記憶體將保持在同一水平。這是否意味著我丟失了所有 RAM?看起來好像 OOM 殺手似乎更早被調用了。我怎樣才能收回它?

    # rm /tmp/zero*
    # cat /proc/meminfo | grep 'Unevictable\|Shmem'
    Unevictable:      288372 kB
    Shmem:             48412 kB
    
  • 使用 100MB 而不是 10MB 的區塊:

    #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

在回答你的問題時,紅帽將「不可避免」總結為「內存量,以千位元組為單位,由頁面輸出程式碼發現,這是不可驅逐的,因為它被用戶程式鎖定到記憶體中。

閱讀完整的文檔,聽起來由於某種原因ramfs分配是從正常的 LRU 列表開始的Inactive(anon)。一旦用完可用記憶體並開始觸發回收(頁出),就會掃描列表,VM 將「發現」鎖定的記憶體並將其移至不可清除列表。

與此相關的是,還有一個內核註釋這表示「Mlocked」欄位可能不會立即解釋鎖定的頁面。 (也許在某些情況下會這樣,我沒有檢查過)。

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

我並不假設內核會立即掃描整個列表,但我希望它會大批量地掃描它。

這個理論的問題是,如果您沒有配置任何交換,我不知道您的核心為什麼/如何掃描“匿名”列表。我什至找到了程式碼-

/* 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;
}

相關內容