Merkwürdiges Verhalten mit nicht auslagerbarem Cache (Linux-Kernel)

Merkwürdiges Verhalten mit nicht auslagerbarem Cache (Linux-Kernel)

Ich beobachte ein Verhalten, das ich auf meinem eingebetteten Linux-Ziel (initramfs undkein Tauschen).

Da kein Swapping stattfindet, würde ich erwarten, dass alles in /tmp (tmpfs) als nicht auslagerbar gekennzeichnet wird. Stattdessen beobachte ich Folgendes, wenn ich das folgende Skript verwende:

#!/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
  • Beim Schreiben vieler Dateien mit 10 MB wächst der Shmem linear, aber der nicht auslagerbare Speicher springt sehr schnell von 0 KB auf ~200 MB:

    #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
    
  • Wenn ich alle Nulldateien lösche, bleibt der nicht auslagerbare Speicher auf demselben Niveau. Bedeutet das, dass ich den gesamten RAM verloren habe? Es sieht so aus, als wäre der OOM-Killer früher aufgerufen worden. Wie kann ich ihn zurückgewinnen?

    # rm /tmp/zero*
    # cat /proc/meminfo | grep 'Unevictable\|Shmem'
    Unevictable:      288372 kB
    Shmem:             48412 kB
    
  • Mit Blöcken von 100 MB statt 10 MB:

    #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
    

Kann jemand das beobachtete Verhalten erklären, das für mich nach einem Kernel-Fehler aussieht?

Danke

Antwort1

Ich vermute, es ist kein TMPFS, sondern ein RAMFS.

Die Liste der nicht räumbaren Seiten befasst sich mit den folgenden Klassen nicht räumbarer Seiten:

  • Die von Ramfs.

  • Diese werden in SHM_LOCKgemeinsam genutzte Speicherbereiche abgebildet.

  • Diese wurden in VM_LOCKED[mlock()ed] VMAs abgebildet.

Die Infrastruktur kann möglicherweise auch mit anderen Bedingungen umgehen, die dazu führen, dass Seiten künftig entweder per Definition oder aufgrund der Umstände nicht mehr gelöscht werden können.

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

Als Antwort auf Ihre Frage:Roter Hutfassen Sie "Unevictable" wie folgt zusammen: "Die Speichermenge in Kibibyte,entdeckt durch den Pageout-Code, das nicht gelöscht werden kann, da es durch Benutzerprogramme im Speicher gesperrt ist."

Wenn man das gesamte Dokument liest, klingt es so, als würden ramfsdie Zuordnungen aus irgendeinem Grund auf der normalen LRU-Liste beginnen Inactive(anon). Sobald der freie Speicher aufgebraucht ist und Sie eine Rückforderung (Auslagerung) auslösen, werden die Listen gescannt und die VM „entdeckt“ den gesperrten Speicher und verschiebt ihn in die Liste der nicht auslagerbaren Speicher.

In diesem Zusammenhang gibt es auch eineKernel-Kommentarwas darauf schließen lässt, dass das Feld „Mlocked“ gesperrte Seiten möglicherweise nicht sofort berücksichtigt. (Vielleicht ist das in manchen Fällen der Fall, ich habe es nicht überprüft).

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

Ich gehe nicht davon aus, dass der Kernel die gesamte Liste auf einmal scannt, aber ich gehe davon aus, dass er sie in großen Stapeln scannt.

Das Problem mit dieser Theorie ist, dass ich nicht weiß, warum/wie Ihr Kernel die "anon"-Listen scannen würde, wenn Sie keinen Swap konfiguriert haben. Ich habe sogar dieCode-

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

verwandte Informationen