Aller au contenu
La Lettre IT
Retour aux synthèses
4 min de lecture

Optimiser le coût CPU d'eBPF avec memoization : une stratégie de cache par inode

En bref

  • Un agent de sécurité eBPF a réduit son coût CPU de 90% en cachant l'association entre inode et politique de sécurité, plutôt que de recalculer le chemin à chaque accès fichier.
  • Le cache utilise un LRU HashMap avec pour clé le couple (mount namespace ID, mount ID, inode), ce qui évite de remonter l'arborescence de dentries pour chaque ouverture de fichier.
  • Le code ignore volontairement les fichiers ayant plusieurs liens physiques (hardlinks) pour garantir l'exactitude des résultats en cache.
  • La solution reste interne à l'agent et n'impose aucune modification aux politiques utilisateur.

Ce que dit la source

L'auteur expose un goulot d'étranglement du profil d'eBPF : l'étape la plus coûteuse n'est pas l'application d'une politique allow/deny, mais la détermination de quelle politique s'applique à une ouverture de fichier donnée. Cette détermination repose sur une remontée complète de l'arborescence (walk up parent dentries) pour chaque accès, ce qui se répète inutilement quand plusieurs accès ciblent le même fichier ou le même sous-arbre (par exemple, les requêtes répétées de Postgres vers /var/lib/postgres/data/base/X). La solution : mettre en cache l'association inode-politique pour éviter cette remontée répétée.

  • Le cache utilise trois champs comme clé : mount namespace ID, mount ID et inode number, car les numéros d'inode ne sont uniques que dans un arbre de montage spécifique.
  • La valeur du cache stocke deux éléments : un access_index (position du bit correspondant à la politique) et un état, encodés sur 32 + 8 bits pour compactité.
  • Un LRU HashMap d'une capacité de 10 000 entrées évite les fuites mémoire et limite l'usage RAM.
  • Les fichiers ayant plusieurs liens (i_nlink > 1) sont volontairement exclus du cache et redirigent vers le chemin lent pour garantir l'exactitude : c'est un compromis assumé plutôt qu'une vraie solution.
  • La réduction observée : 28 milliards de cycles noyau ramenés à 3,03 milliards lors d'un benchmark ouvrant le même fichier 200 000 fois consécutives.

Dans les commentaires

Débat partagé : le cache en lui-même est une optimisation classique, mais la mise en œuvre face aux limites d'eBPF et de la sémantique du système de fichiers Linux est intéressante. Plusieurs commentateurs contestent cependant la portée réelle du gain : le benchmark teste un cas très favorable (même fichier ouvert 200 000 fois), et plusieurs édgecases non résolus (suppression de fichiers, déplacement de répertoires, changement de permissions) reposeraient sur des mécanismes d'invalidation non documentés.

  • Un commentateur souligne que le gain de 90% cache un compromis mémoire/CPU non mesuré explicitement : l'auteur quantifie la réduction de CPU mais ne publie pas la consommation RAM supplémentaire du cache.
  • Plusieurs questionnent les conditions réelles d'utilisation : le benchmark teste l'accès répété au même fichier 200 000 fois, ce qui est un cas de charge favorable et peu représentatif des workloads variés (ouvrir plusieurs fichiers différents à chaque itération ralentirait probablement le système avec le cache).
  • Des limites de sécurité sont relevées : suppression de fichier, déplacement de répertoires, ajout de hardlinks, ou changement de permissions utilisateur après mise en cache pourraient invalider les entrées sans mécanisme d'invalidation visible.
  • L'article titre sur « memoization » (terme générique depuis 40 ans) plutôt que sur le problème vraiment intéressant : construire une clé de cache robuste pour un chemin de fichier dans les contraintes d'eBPF et de la sémantique Linux.
  • Le contournement pour les hardlinks (exclusion du cache quand i_nlink > 1) est reconnu par l'auteur comme un compromis « plus un workaround qu'une vraie solution ».

Notre lecture

L'optimisation fonctionne pour ce qu'elle est : une cache d'inode pour réduire les remontées répétées dans l'arborescence. Sur une charge froide (fichiers différents à chaque accès), le surcoût du cache risque d'écraser le gain. Sur une charge chaude (accès répétés aux mêmes chemins, typique chez Postgres), les 90% de réduction sont plausibles et intéressants. En revanche, l'architecture n'adresse pas explicitement l'invalidation (fichiers supprimés, permissions changeantes) : le cache reste localisé à l'eBPF, mais comprendre comment les événements VFS interagissent avec un cache LRU de 10 000 entrées exigerait plus de détail. Pour une équipe déployant un agent eBPF de sécurité en production, c'est un pattern à explorer (et à mesurer sur son workload réel, comme le souligne un commentateur). Intéressant techniquement, mais pas une révolution : c'est une application pragmatique de cache classique face à des contraintes système spécifiques.

Le brief, dans votre boîte mail

Recevez chaque jour la sélection et l'analyse La Lettre IT, sans avoir à repasser sur le site.

  • Un email par jour, synthèse de ce qui compte réellement sur Hacker News
  • Le débat technique décrypté, pas juste résumé, et ce que La Lettre IT en pense
  • Zéro spam, désabonnement en un clic sur chaque email