Skip to content
/linux-syscalls

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

ArchitectureNuméroABIPoint d'entrée
x86 (i386)219i386sys_madvise
x64 (x86_64)28commonsys_madvise
ARM64 (aarch64)233—sys_madvise

Historique noyau

Introduit dans Linux 2.4.0.

  1. 2.4.0

    madvise() a livré en 2.4 avec le jeu de conseils POSIX de base (NORMAL, RANDOM, SEQUENTIAL, WILLNEED).

  2. 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 ».

  3. 4.5

    MADV_FREE a été ajouté — version paresseuse de MADV_DONTNEED évitant le zérotage inconditionnel. Gain de performance majeur pour les allocateurs.

  4. 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. 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) = 0

madvise() 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.

Syscalls liés