Kernel¶
Siehe auch
- Verwandte Artikel
- Offizielle Dokumentation
man modprobe,man modinfo,man sysctl,man tuned-adm
Die Befehle insmod und rmmod zum Laden und Entfernen von Kernel-Modulen sind für Entwickler gedacht; selbst sollte man stattdessen den Befehl modprobe verwenden, der auch Modulabhängigkeiten behandelt. modprobe arbeitet auf Konfigurationsdateien in /etc/modprobe.d/. Ein Modul kann per modprobe --remove entfernt werden, sobald es nicht mehr verwendet wird.
Kernel-Module finden sich unterhalb von /lib/modules/$KERNEL_VERSION, sind komprimiert und enden auf .xz.
Informationen über ein Kernel-Modul lassen sich mit modinfo $KERNEL_MODULE einsehen, inkl. der gesetzten Modul-Parameter. Die Parameter werden unterhalb von /sys/module/$KERNEL_MODULE/parameters abgelegt - pro Parameter eine Datei. Deren eigentliche Bedeutung findet sich im (zu installierenden) Paket kernel-doc unterhalb von /usr/share/doc/kernel-doc-*/Documentation.
Aktuell gesetzten Wert eines Parameters einsehen:
cat /sys/module/$KERNEL_MODULE/parameters/...
Parameter (nur!) beim Laden eines Modules setzen. Diese Einstellungen gelten zur Laufzeit:
modprobe --verbose $KERNEL_MODULE key1=value1 key2=value2
Modul-Parameter dauerhaft setzen (Dateinamen werden in alphabetischer Reihenfolge abgearbeitet). Anschliessend muss das Modul entfernt und neu geladen werden, damit die Einstellungen greifen:
options $KERNEL_MODULE key1=value1 key2=value2
modprobe --verbose --remove $KERNEL_MODULE
modprobe --verbose $KERNEL_MODULE
Kernel-Tuning: Stellschrauben und Mechanismen¶
Worum geht es¶
Der Linux-Kernel exponiert über sysctl, sysfs und weitere Schnittstellen mehrere hundert Tunables. Für klar abgegrenzte Server-Rollen (Datenbank, NFS-Client, Reverse-Proxy, Logging-Backend, Container-Host) weichen Hersteller-Empfehlungen teilweise vom Default ab. Die in der Praxis häufigsten Stellschrauben verteilen sich auf vier Subsysteme: sysctl-Keys unter /proc/sys/, einzelne Knoten unter /sys, die CPUAffinity von systemd und das Transparent-Huge-Pages-Subsystem.
Begriffe¶
Die folgenden Begriffe werden in den weiteren Abschnitten verwendet.
- Anonymous Memory
Vom Userspace per
mallocodermmap(MAP_ANONYMOUS)allokierter Speicher ohne Backing-File. Im Gegensatz zu Page-Cache-Pages, die jederzeit verworfen werden können, müssen Anonymous Pages bei Speicherdruck auf Swap geschrieben werden.- kcompactd
Kernel-Thread, der im Hintergrund Memory-Compaction durchführt, also fragmentierte 4-KiB-Pages so umsortiert, dass zusammenhängende physische Speicherblöcke (zum Beispiel für eine 2-MiB-Huge-Page) entstehen.
- khugepaged
Kernel-Thread, der im Hintergrund versucht, Anonymous-Pages zu 2-MiB-Huge-Pages zusammenzufassen, sobald THP auf
alwaysodermadvisesteht.- LONG_MAX
Grösster vorzeichenbehafteter 64-Bit-Wert:
9223372036854775807. Wird vom Kernel als „faktisch unbegrenzt“ verwendet, wo eine Obergrenze syntaktisch nötig, praktisch aber nicht sinnvoll ist.- NUMA (Non-Uniform Memory Access)
Architektur, bei der jede CPU eine eigene lokale RAM-Bank hat. Zugriffe auf entferntes RAM eines anderen Sockels kosten zusätzliche Latenz.
- OOM-Killer
Komponente im Kernel, die bei tatsächlich aufgebrauchtem Speicher Prozesse abschiesst.
- Page Cache
Kernel-Cache für Datei-I/O. Wird konkurrierend zu Anonymous Memory bewirtschaftet.
- Page Fault
Trap, den die CPU auslöst, wenn ein Prozess auf eine virtuelle Adresse zugreift, deren Mapping in der Page-Table fehlt oder geschützt ist. Der Kernel behandelt den Trap und liefert (oder verweigert) die Seite.
- RPC-Slot
Eintrag in der Slot-Tabelle des Sun-RPC-Transports (NFS). Pro Slot kann genau ein RPC-Request parallel „in-flight“ sein.
- sysctl-Key
Punkt-separierter Schlüssel wie
vm.swappiness. Entspricht 1:1 einem Pfad unter/proc/sys/(im Beispiel/proc/sys/vm/swappiness).- THP (Transparent Huge Pages)
Mechanismus, mit dem der Kernel mehrere 4-KiB-Pages bei Bedarf zu 2-MiB-Pages zusammenfasst. Reduziert den TLB-Druck (siehe TLB).
- TLB (Translation Lookaside Buffer)
Cache in der CPU, der die letzten Übersetzungen von virtuellen auf physische Speicheradressen hält. Ein TLB-Miss zwingt die CPU zum Page-Table-Walk im RAM und kostet Dutzende Zyklen pro Übersetzung. Eine 2-MiB-Huge-Page deckt mit einem einzigen TLB-Eintrag den Adressbereich von 512 normalen 4-KiB-Pages ab.
- tuned-Profil
Verzeichnis unter
/etc/tuned/profiles/<name>/mit einertuned.conf. Definiert[sysctl],[sysfs],[vm](THP),[bootloader],[cpu]und weitere Sektionen.- VMA (Virtual Memory Area)
Eintrag in der Memory-Map eines Prozesses. Jedes
mmapoder eigener Heap-Bereich belegt mindestens eine VMA.
Wo Werte liegen und wie man sie persistiert¶
Linux kennt mehrere, nebeneinander existierende Schnittstellen mit unterschiedlichem Geltungsbereich und unterschiedlicher Persistenz. Ein und derselbe Wert kann gleichzeitig von mehreren Quellen beeinflusst werden, mit unterschiedlichem Vorrang.
- sysctl (
/proc/sys/) Die generische Schnittstelle für Kernel-Tunables. Jeder Pfad unterhalb von
/proc/sys/ist gleichzeitig persysctl <key>lesbar. Werte sind nach demechosofort aktiv, aber flüchtig. Persistenz über Dateien in/usr/lib/sysctl.d/(Distro),/etc/sysctl.d/(Admin) und/etc/sysctl.conf(Legacy), diesystemd-sysctl.servicebeim Boot abarbeitet. Letzter Treffer gewinnt, deshalb hat die alphabetisch grösste Datei das letzte Wort. Inhalt einer Datei:key.with.dots = valuepro Zeile.- sysfs (
/sys/) Direkte Treiber- und Subsystem-Knoten. Im Gegensatz zu
sysctlkeine einheitliche Persistenz: Werte verschwinden beim Reboot, wenn niemand sie wieder setzt. Typische Reanimatoren sind udev-Regeln (für Geräte-spezifisches), eintuned-Profil (für alles Systemweite),systemd-tmpfilesmitw-Direktiven (für einzelne Schalter) oder eigene Service-Units.- Kernel-Kommandozeile (
/proc/cmdline,grub.cfg) Für Parameter, die schon beim Boot greifen müssen oder gar nicht zur Laufzeit umschaltbar sind, zum Beispiel
transparent_hugepage=never,mitigations=off,intel_iommu=on. Persistenz über/etc/default/grub(GRUB_CMDLINE_LINUX) plusgrub2-mkconfigbzw. auf RHEL bequemergrubby --update-kernel=ALL --args="...".- Modul-Parameter (
/sys/module/<name>/parameters/) Treiber-Optionen, die beim Modul-Load gelesen werden. Persistenz über
/etc/modprobe.d/*.confmitoptions <name> key=value. Greift erst nach erneutem Modul-Load.- systemd-Konfiguration (
system.conf, Unit-Drop-ins) Für globale Default-CPU-Affinität,
LimitNOFILE, Speicher-Limits und alles, was Units von PID 1 erben sollen. Persistenz über/etc/systemd/system.conf.d/*.confoder pro Unit übersystemctl edit <unit>.
Die Rolle von tuned¶
tuned ist auf Red Hat und Derivaten seit RHEL 7 das von Red Hat ausgelieferte Werkzeug, um diese Stellschrauben zu bündeln. Es ist auf RHEL 10 per Default installiert und aktiv. Ein Profil ist ein Verzeichnis unter /etc/tuned/profiles/<name>/ (oder mitgeliefert unter /usr/lib/tuned/profiles/) mit einer tuned.conf. Diese Datei deklariert sektionsweise, was beim Profil-Wechsel zu setzen ist:
[sysctl]: Schlüssel-Wert-Paare, die alssysctlgeschrieben werden.[sysfs]: Pfade unter/sysmit den gewünschten Werten.[vm]: Transparent-Huge-Pages-Schalter (transparent_hugepagesundtransparent_hugepages_defrag).[bootloader]: Kernel-Cmdline-Parameter, dietunedüber Grub setzt (erst nach Reboot aktiv).[cpu]: CPU-Governor,min_perf_pctund Verwandtes.[disk],[net],[scheduler], weitere.
Aktivierung per tuned-adm profile <name>, prüfen mit tuned-adm active. Die aktiven Sektionen werden bei jedem Profil-Wechsel und bei jedem Boot neu angewandt. Bei Konflikt mit sysctl.d-Dateien gilt: tuned läuft als Service nach systemd-sysctl.service, überschreibt also eine sysctl.d-Datei. tuned warnt beim Start, wenn es einen Konflikt erkennt.
Stock-Profile aus dem tuned-Paket selbst: balanced (Default), throughput-performance, latency-performance, network-throughput, network-latency, powersave, virtual-guest, virtual-host, hpc-compute, desktop, accelerator-performance, optimize-serial-console, intel-sst, aws. Weitere Profile (zum Beispiel cpu-partitioning, mssql, oracle, postgresql, realtime, sap-hana, openshift) liegen in eigenen tuned-profiles-<name>-Paketen und müssen separat installiert werden. Eigene Profile können per include = throughput-performance darauf aufsetzen und nur die abweichenden Werte überschreiben.
Cheat Sheet¶
# aktives tuned-Profil
tuned-adm active
# alle verfügbaren Profile
tuned-adm list
# eigenes Profil aktivieren
tuned-adm profile <name>
# effektive Profil-Konfiguration einsehen
cat /etc/tuned/profiles/<name>/tuned.conf
# einzelnen sysctl-Wert prüfen
sysctl <key>
# oder direkt aus dem proc-Filesystem
cat /proc/sys/<unterpfad>
# alle sysctl-Werte und ihre Herkunft
systemd-analyze cat-config sysctl.d
sysctl --all
# Transparent Huge Pages: aktive Auswahl steht in eckigen Klammern
cat /sys/kernel/mm/transparent_hugepage/enabled
cat /sys/kernel/mm/transparent_hugepage/defrag
# CPU-Affinity der systemd-PID 1 (= effektive Default-Maske)
taskset --pid 1
# aktive Kernel-Cmdline
cat /proc/cmdline
sysctl-Keys¶
Die folgenden sysctl-Keys werden in Server-Workloads typischerweise vom Default abweichend gesetzt. Persistenz über /etc/sysctl.d/*.conf oder die [sysctl]-Sektion eines tuned-Profils. Sortiert alphabetisch.
fs.aio-max-nr¶
Obergrenze für die Anzahl gleichzeitig aktiver asynchroner I/O-Requests systemweit. Async-I/O kommt überall zum Einsatz, wo eine Anwendung viele Disk- oder Netzwerk-Requests parallel laufen lässt, ohne pro Request einen eigenen Thread aufzumachen. Klassische Konsumenten: MariaDB/MySQL InnoDB, PostgreSQL mit effective_io_concurrency, Oracle, Backup-Tools mit libaio oder io_uring-Backend. Wird die Grenze überschritten, scheitert io_setup(2) mit EAGAIN.
Default 65536 (static unsigned long aio_max_nr = 0x10000 in fs/aio.c, unverändert über die letzten Kernel-Generationen). Manche Distro-Pakete heben diesen Wert über /usr/lib/sysctl.d/ an, zum Beispiel libvirt mit 1048576.
Auf Datenbank- und Backup-Hosts ist 1048576 der übliche Wert. Verifikation: sysctl fs.aio-max-nr, aktuelle Nutzung in cat /proc/sys/fs/aio-nr.
fs.file-max¶
Systemweite Obergrenze für offene File Descriptors (Sockets, Pipes, geöffnete Dateien). Greift über alle Prozesse zusammen. Das Per-Prozess-Limit hingegen wird über RLIMIT_NOFILE (ulimit -n, LimitNOFILE= in systemd-Units) gesetzt; ein Prozess kann nie mehr FDs öffnen als sein eigenes Limit, das Gesamtsystem nie mehr als fs.file-max.
Seit Linux 4.18 (Commit 9b80a184eaad von Eric Biggers) ist der Default LONG_MAX, faktisch also unbegrenzt. Auf RHEL 8 und neuer ist dieses Setting damit nur noch in Ausnahmefällen interessant. Verifikation: sysctl fs.file-max, aktuelle Allokation und Peak in cat /proc/sys/fs/file-nr (drei Felder: allokiert, frei, Max).
net.bridge.bridge-nf-call-iptables und net.bridge.bridge-nf-call-ip6tables¶
Schalten die br_netfilter-Hooks für Linux-Bridges ein. Mit 1 durchläuft jedes IPv4- bzw. IPv6-Paket, das eine Bridge passiert, zusätzlich die iptables/nftables-Filterketten; andernfalls wird Bridge-Traffic transparent durchgereicht, ohne von der Host-Firewall gesehen zu werden. Die Keys existieren nur, wenn das Modul br_netfilter geladen ist; das passiert automatisch, sobald Docker, Podman mit CNI-Bridge oder ein Kubernetes-CNI startet.
Default 1 (static int brnf_call_iptables __read_mostly = 1 in net/bridge/br_netfilter_hooks.c, unverändert). Docker- und Kubernetes-Networking setzen diesen Wert explizit erneut, um auch nach Modul-Reloads sicher zu sein; Quelle: Kubernetes-Networking-Requirements („ensure that the br_netfilter module is loaded and bridge traffic traverses iptables“).
Wer Linux-Bridges ohne Container-Networking betreibt und Bridge-Traffic nicht filtern muss, lässt das Modul ungeladen oder setzt die beiden Keys auf 0 und spart sich den Netfilter-Overhead pro Bridge-Paket. Verifikation: cat /proc/sys/net/bridge/bridge-nf-call-iptables, ...-ip6tables; Modul mit lsmod | grep br_netfilter.
net.core.rmem_max¶
Maximale Grösse des Receive-Buffers pro Socket, die eine Anwendung per setsockopt(SO_RCVBUF) anfordern darf. Limitiert, wie viel TCP-Window oder UDP-Backlog ein einzelner Socket maximal aufbauen kann.
Default 212992 (SK_RMEM_MAX = 212992 in net/core/sock.c) für Kernel der Generation 4.18 bis 6.12. Im Mainline-Kernel wurde der Default zwischen 6.12 und 6.19 auf 4194304 angehoben.
Auf UDP-Heavy-Receivern (Syslog-Empfänger, GELF-UDP-Endpunkt von Graylog, Metrics-Collectors) wird der Wert oft auf 1048576 bis 8388608 gesetzt, damit Empfangs-Bursts keinen Drop produzieren. Quelle: Graylog-Setup-Dokumentation, „Linux kernel parameters / UDP receive buffer size“. Verifikation: sysctl net.core.rmem_max; effektive Werte pro Socket in ss --memory.
net.core.somaxconn¶
Obergrenze für die Backlog-Queue eines listen(2)-Sockets. Bei einem TCP-Server stehen die Verbindungen mit abgeschlossenem TCP-Handshake in dieser Queue, bis die Anwendung sie per accept(2) abholt. Apps, die listen(fd, backlog) mit einem grösseren backlog aufrufen, werden auf net.core.somaxconn gedeckelt.
Default vor Linux 5.4: 128. Seit Linux 5.4 (Commit 19f92a030ca6): 4096. RHEL 8 (4.18) hat damit den alten Wert 128, RHEL 9 (5.14) und RHEL 10 (6.12) bereits 4096.
Auf Reverse-Proxys, TLS-Terminatoren und Webservern unter hoher Connection-Setup-Rate kann eine weitere Anhebung sinnvoll sein, sofern die Anwendung selber ein passendes backlog an listen() übergibt. Verifikation: sysctl net.core.somaxconn, aktuelle Listen-Drops in ss --listening --extended (Spalte Send-Q zeigt den Backlog).
sunrpc.tcp_slot_table_entries¶
Anzahl gleichzeitig offener RPC-Requests pro NFS-TCP-Mount. NFS-Operationen (read, write, getattr, …) werden als RPC-Calls über einen TCP-Transport gefahren. Pro Slot kann genau eine RPC-Operation gleichzeitig in-flight sein; alle weiteren werden serialisiert, bis ein Slot frei wird. Der Key existiert erst, wenn das Modul sunrpc geladen ist; ohne NFS-Mount oder vorheriges modprobe sunrpc meldet sysctl „the parameter does not exist“.
Default 2 (RPC_DEF_SLOT_TABLE in include/linux/sunrpc/xprt.h, unverändert). Auf NFS-Clients mit echten Workloads ist das deutlich zu wenig; Red Hat Solution 2470401 („How to increase the number of parallel NFS RPC requests“) empfiehlt Werte bis 128. Verifikation: cat /proc/sys/sunrpc/tcp_slot_table_entries; Modul-Status mit lsmod | grep sunrpc.
vm.max_map_count¶
Maximale Anzahl Memory-Map-Areas (VMAs) pro Prozess. Jedes mmap, jeder brk-Aufruf für den Heap und jede Shared-Library belegt mindestens eine VMA. JVM-basierte Suchmaschinen (Elasticsearch, OpenSearch) und Logging-Backends (Graylog Data Node) mappen pro Index sehr viele kleine Segmente und kollidieren mit dem Default 65530.
Default 65530 (DEFAULT_MAX_MAP_COUNT in include/linux/mm.h, in der Mainline unverändert). Klassisches Symptom bei zu niedrigem Wert ist die Startup-Meldung max virtual memory areas vm.max_map_count [65530] is too low. Elastic empfiehlt 262144 („Virtual memory“-Section der Elasticsearch-Installationsdokumentation), Graylog 524288. Distro-Pakete können den Wert per /usr/lib/sysctl.d/ anheben (auf Fedora aktuell 1048576). Verifikation: sysctl vm.max_map_count; aktuelle VMA-Zahl eines Prozesses in wc --lines /proc/<pid>/maps.
vm.overcommit_memory¶
Strategie, wie der Kernel auf malloc/mmap-Allokationen reagiert, die zusammengenommen mehr verlangen, als physisch verfügbar ist. Linux überbucht standardmässig, weil ein Prozess oft nicht alles tatsächlich beschreibt.
0(Default): Heuristik des Kernels. „Offensichtlich zu grosse“ Allokationen werden abgelehnt.1: Alles erlauben, kein Check. Anfrage geht immer durch; bei echter Knappheit greift später der OOM-Killer.2: Strikt nachvm.overcommit_ratio. Allokation scheitert, sobald die Summeswap + overcommit_ratio * RAMüberschritten würde.
Details: https://docs.kernel.org/admin-guide/sysctl/vm.html
1 ist die dokumentierte Voraussetzung für Redis, KeyDB, Dragonfly und ähnliche Dienste, die per fork() einen Background-Save schreiben. Mit Default 0 kann fork() mit ENOMEM scheitern, obwohl der Child-Prozess durch Copy-on-Write fast nie wirklich alles physisch allokiert. Quelle: Redis-Admin-Doku, „Background saving fails with a fork error under Linux even if I have a lot of free RAM!“. Preis dafür: bei tatsächlicher Speicher-Knappheit greift der OOM-Killer aggressiver, weil der Kernel die Anfrage nicht vorher abweist.
Verifikation: sysctl vm.overcommit_memory (Strategie), cat /proc/meminfo (Spalte CommitLimit zeigt das Limit für Modus 2).
vm.swappiness¶
Bereitschaft des Kernels, Anonymous Memory aus dem RAM auf Swap auszulagern, gegenüber dem Verwerfen von Page-Cache-Pages. Der Wert ist keine harte Schranke, sondern geht in das Ranking ein, mit dem der Reclaim-Algorithmus entscheidet, welche Pages er als nächstes freigibt.
Wertebereich 0-100 bis Linux 5.8, danach 0-200 (Commit 165e1f9e4032). 0 heisst „nur wenn nichts mehr geht“, Werte über 100 priorisieren Swap-Out gegenüber Page-Cache-Eviction. Default 60 (DEFAULT_SWAPPINESS in mm/vmscan.c, unverändert).
Auf Datenbank-, Mail-, Monitoring- und Cache-Servern mit grossem Working-Set im RAM und Swap nur als Sicherheitsnetz wird oft 10 oder weniger gesetzt; Quelle für 10 als DB-Default: Red Hat Solution 50064 sowie MariaDB- und MySQL-Tuning-Empfehlungen. Preis dafür: bei knapp werdendem RAM kommt der OOM-Killer früher zum Zug, weil Swap später benutzt wird.
Verifikation: sysctl vm.swappiness; aktueller Swap-Druck in vmstat 1 (Spalten si/so), aktuelle Swap-Nutzung in free --human.
sysfs-Knoten¶
Werte unter /sys sind treiber- und subsystem-spezifisch. Persistenz über ein tuned-Profil ([sysfs]-Sektion), eine udev-Regel oder eine systemd-tmpfiles-w-Direktive.
Typische Anwendungsfälle:
I/O-Scheduler eines Block-Devices:
/sys/block/sda/queue/schedulermit den Modimq-deadline,none,bfq.Read-Ahead pro Device:
/sys/block/sda/queue/read_ahead_kb.CPU-Idle-States:
/sys/devices/system/cpu/cpu*/cpuidle/state*/disable.CPU-Side-Channel-Mitigations einzeln umschalten, zum Beispiel
/sys/kernel/debug/x86/pti_enabledfür PTI und/sys/kernel/debug/x86/retp_enabledfür Retpoline.
Übersicht über die aktiven CPU-Mitigations: grep --recursive . /sys/devices/system/cpu/vulnerabilities/.
systemd-CPUAffinity¶
Standard-CPU-Affinitätsmaske für PID 1, vererbt an alle systemd-gestarteten Services, die sie nicht selbst überschreiben. Persistenz über /etc/systemd/system.conf bzw. /etc/systemd/system.conf.d/*.conf (CPUAffinity=). Einzelne Services können sie pro Unit mit CPUAffinity= in einem systemctl edit <unit>-Drop-in überschreiben.
Wertformat: Komma-separierte CPU-Liste oder Range, zum Beispiel 1,3,5,7 oder 0-3. Default leer (alle CPUs verfügbar). Verifikation: taskset --pid 1 zeigt die Maske von PID 1 in Hex, systemctl show --property=CPUAffinity für einzelne Units.
Sinnvoller Einsatz: Isolation von Workloads auf Multi-Socket- bzw. NUMA-Maschinen. Klassisches Muster: CPUs 0-7 für System und Housekeeping reservieren, 8-31 exklusiv für die Datenbank, deren Service-Unit ihrerseits per CPUAffinity=8-31 auf die freien Cores gepinnt wird. Preis: Pinning bindet Threads an die ausgewählten Cores. Sind diese ausgelastet, bleiben die nicht gepinnten Cores ungenutzt, auch wenn der gepinnte Workload mehr CPU brauchen könnte.
Transparent Huge Pages (THP)¶
Zwei zusammengehörende Schalter unter /sys/kernel/mm/transparent_hugepage/. Persistenz über die Kernel-Cmdline (transparent_hugepage=never) oder ein tuned-Profil ([vm]-Sektion, transparent_hugepages = never). In der Ausgabe der /sys-Dateien markieren eckige Klammern den aktiven Modus, zum Beispiel always [madvise] never.
/sys/kernel/mm/transparent_hugepage/enabled (Hauptschalter)¶
Erlaubte Werte:
always: Kernel versucht, jede Allokation als 2-MiB-Page zu bedienen.madvise: Nur wenn die Anwendung permadvise(MADV_HUGEPAGE)ausdrücklich danach fragt.never: Nie automatisch 2-MiB-Pages zusammenstellen.
Default auf RHEL 10 und Fedora 43: madvise (empirisch im UBI10-Container geprüft).
Datenbank- und Cache-Hersteller empfehlen never (MariaDB „Hugepages and InnoDB“, MongoDB „Disable Transparent Huge Pages“, Redis „Latency induced by transparent huge pages“). Begründung in diesen Quellen: khugepaged-Compaction kann Latenz-Spikes im Reclaim-Pfad verursachen, und 2-MiB-Pages können nicht teilweise auf Swap geschrieben werden, was den effektiven Memory-Footprint erhöht. Workloads mit grossen, dichten, langlebigen Memory-Mappings (Analytics, ML-Inferenz, HPC) profitieren dagegen messbar von THP, weil eine 2-MiB-Page einen TLB-Eintrag belegt statt 512.
Verifikation: cat /sys/kernel/mm/transparent_hugepage/enabled.
/sys/kernel/mm/transparent_hugepage/defrag (Compaction-Aggressivität)¶
Wirkt nur, wenn der Hauptschalter nicht auf never steht. Steuert, wie aggressiv der Kernel beim Allokieren einer Huge Page wirklich Speicher kompaktiert, falls nicht genug freie 2-MiB-Blöcke vorhanden sind.
Erlaubte Werte:
always: Synchrone Compaction, blockiert den Page Fault.defer: Allokation fällt auf 4-KiB-Pages zurück,kcompactdarbeitet im Hintergrund.defer+madvise: Synchron nur beiMADV_HUGEPAGE-Allokationen, sonstdefer.madvise: Synchron nur, wenn die Anwendung explizit fragt.never: Keine zusätzliche Compaction.
Default auf RHEL 10 und Fedora 43: madvise. Auf Hosts, auf denen THP eingeschaltet bleiben soll, aber synchrone Compaction im Page-Fault-Pfad vermieden werden muss, ist defer üblich; die Compaction läuft dann asynchron in kcompactd, statt im Page Fault zu blockieren.
Verifikation: cat /sys/kernel/mm/transparent_hugepage/defrag.