Mémoire · Section 2
madvise(2)
Donne au noyau des indications sur l'usage d'une région mémoire pour qu'il gère cache, prefetch et reclaim en conséquence.
Signature
#include <sys/mman.h>
int madvise(void * addr, size_t length, int advice);- addr
- Début de la région, aligné page.
- length
- Longueur en octets, arrondie à la page.
- advice
- Une constante MADV_*. Le comportement varie radicalement — certaines sont no-op sur certains noyaux, d'autres affectent durablement la sémantique du processus.
Description
madvise() indique au noyau comment le processus prévoit d'utiliser la plage [addr, addr+length) — advice est une constante MADV_*. Certaines indications sont purement consultatives (MADV_RANDOM désactive le readahead, MADV_SEQUENTIAL l'agresse, MADV_WILLNEED déclenche le prefetch) ; d'autres sont destructives (MADV_DONTNEED dit que les pages peuvent être abandonnées — relues à zéro pour anonyme, refault depuis le fichier pour file-backed) ; d'autres définissent une politique (MADV_HUGEPAGE/NOHUGEPAGE pour les huge pages transparentes, MADV_DONTDUMP/DODUMP pour l'inclusion en core dump, MADV_WIPEONFORK pour zéroter dans les enfants, MADV_COLD/PAGEOUT pour vieillir et reclaim proactivement). madvise() retourne 0 en succès, -1 avec errno sinon. La plupart des indications sont alignées page ; le noyau arrondit.
Numéros par architecture
| Architecture | Numéro | ABI | Point d'entrée |
|---|---|---|---|
| x86 (i386) | 219 | i386 | sys_madvise |
| x64 (x86_64) | 28 | common | sys_madvise |
| ARM64 (aarch64) | 233 | — | sys_madvise |
Historique noyau
Introduit dans Linux 2.4.0.
2.4.0
madvise() a livré en 2.4 avec le jeu de conseils POSIX de base (NORMAL, RANDOM, SEQUENTIAL, WILLNEED).
2.6.16
MADV_DONTNEED est devenu canonique et fiable pour les projections anonymes — les versions antérieures avaient une sémantique subtile ; 2.6.16 a standardisé la garantie « pages relues à zéro ».
4.5
MADV_FREE a été ajouté — version paresseuse de MADV_DONTNEED évitant le zérotage inconditionnel. Gain de performance majeur pour les allocateurs.
5.4
MADV_COLD et MADV_PAGEOUT ajoutés pour que l'espace utilisateur pilote le reclaim. Utilisé par Android et certains démons de pression mémoire Linux.
5.10
process_madvise() a été introduit — applique madvise à un autre processus via pidfd. Utilisé par les gestionnaires de pression (oomd, dbus-broker sous systemd) pour vieillir les pages froides d'autres processus.
seccomp & conteneurs
Docker default profile
Autorisé
Podman default profile
Autorisé
madvise() est dans tout profil par défaut et en pratique impossible à bloquer — chaque arène malloc glibc et chaque JIT l'utilise. Le seul filtrage d'arguments significatif serait sur advice — refuser MADV_HWPOISON (qui requiert CAP_SYS_ADMIN de toute façon). Le reste est sûr.
libseccomp
seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(madvise), 0);Exemple strace
$ strace -e madvise bash -c 'true'
madvise(0x7f4c0a3c5000, 8192, MADV_DONTNEED) = 0
madvise(0x7f4c0a3c7000, 16384, MADV_DONTNEED) = 0madvise() dans strace décode advice symboliquement. Le taux d'appels MADV_DONTNEED est un proxy direct du churn malloc ; les processus jemalloc en émettent des dizaines par seconde. -e madvise filtre.
Sécurité & observabilité
madvise() est plus un outil défensif qu'offensif — MADV_DONTDUMP et MADV_WIPEONFORK sont du durcissement standard pour les processus tenant des secrets (sessions TLS, matériel de clé). L'exception notable était CVE-2020-29371 où MADV_HWPOISON permettait un use-after-free non privilégié dans certaines configs ; patché depuis longtemps. Le tracepoint eBPF sys_enter_madvise est à très haut débit et rarement utile en supervision production. Pour la sécurité conteneur, MADV_HUGEPAGE sur des régions JIT est bénin et attendu ; MADV_DODUMP sur une région auparavant DONTDUMP est suspect.
Erreurs
- EACCES
- MADV_REMOVE sur une projection non partagée ou un fd en lecture seule.
- EAGAIN
- —
- EBADF
- —
- EINVAL
- addr ou length non aligné page, advice invalide pour la région, ou non supporté par le noyau.
- EIO
- —
- ENOMEM
- Allocation interne échouée, ou la plage couvre des régions non mappées.
- EPERM
- MADV_HWPOISON ou conseil privilégié sans CAP_SYS_ADMIN.
Drapeaux
- MADV_NORMAL
- 0
- —
- MADV_RANDOM
- 1
- —
- MADV_SEQUENTIAL
- 2
- —
- MADV_WILLNEED
- 3
- —
- MADV_DONTNEED
- 4
- Indique que les pages ne sont pas requises bientôt. Anonyme : pages abandonnées, relues à zéro. File-backed : pages abandonnées, relues depuis le disque. Utilisé par les allocateurs (jemalloc, tcmalloc) pour rendre la mémoire sans démapper.
- MADV_FREE
- 8
- Comme DONTNEED mais paresseux : les pages peuvent ou non être récupérées ; si le processus les touche avant, le contenu est préservé. Moins coûteux que DONTNEED. Ajouté en 4.5.
- MADV_REMOVE
- 9
- —
- MADV_DONTFORK
- 10
- —
- MADV_HUGEPAGE
- 14
- Indique que cette région est candidate aux huge pages transparentes (2 MiB). Utile pour les grands tableaux des bases de données et JIT.
- MADV_NOHUGEPAGE
- 15
- —
- MADV_DONTDUMP
- 16
- Exclut la région des core dumps. Durcissement standard pour la mémoire contenant des secrets (keyrings, tampons de mots de passe).
- MADV_DODUMP
- 17
- —
- MADV_WIPEONFORK
- 18
- Après fork(), l'enfant voit des zéros à la place du contenu parent dans cette région. Utilisé par OpenSSL pour les tampons sensibles afin d'éviter la fuite par inspection mémoire post-fork.
- MADV_COLD
- 20
- —
- MADV_PAGEOUT
- 21
- Page out agressivement la région (Linux 5.4+). Utilisé par les gestionnaires de pression mémoire en espace utilisateur.