Skip to main content

Module ring_buffer

Module ring_buffer 

Source
Expand description

Le consommateur d’un tampon circulaire BPF (BPF_MAP_TYPE_RINGBUF).

Un programme eBPF écrit des enregistrements (bpf_ringbuf_output) ; l’espace utilisateur les lit en projetant la carte, sans appel système par enregistrement. Le protocole est celui de Documentation/bpf/ringbuf.rst et de kernel/bpf/ringbuf.c :

offset 0          une page      position CONSOMMÉE (u64) — écrite par nous
offset page       une page      position PRODUITE (u64)  — écrite par le noyau
offset 2 × page   2 × taille    les données, projetées DEUX FOIS à la suite

La double projection fait qu’un enregistrement à cheval sur la fin de la zone reste contigu : on le lit d’un seul tenant. Chaque enregistrement commence par un en-tête de 8 octets — sa longueur sur 32 bits, dont deux bits d’état (BUSY : en cours d’écriture ; DISCARD : jeté), puis 32 bits propres au noyau —, et sa taille totale est arrondie à 8.

§Pourquoi en couche 0

Lire une mémoire que le noyau écrit en même temps demande des accès atomiques sur des adresses brutes : c’est intrinsèquement unsafe, et l’unsafe d’Air vit en couche 0, nulle part ailleurs. Au-dessus, BpfRingBufferConsumer::consume ne rend que des tranches d’octets déjà publiées.

§L’ordre des accès

  • la position produite se lit en acquérir : ce qui la précède est alors visible ;
  • la longueur d’un en-tête se lit en acquérir : le noyau l’écrit en libérer quand il publie l’enregistrement, et c’est ce qui rend ses données visibles ;
  • la position consommée s’écrit en libérer : le noyau ne réutilise la place qu’après.

Structs§

BpfRingBufferConsumer
Le consommateur d’un tampon circulaire BPF, projeté en mémoire.