Les développeurs de Cloudflare ont réalisé des travaux d'optimisation des performances du chiffrement disque dans le noyau Linux. En conséquence, ils ont préparé pour la sous-système et Crypto API, permettant d'augmenter la bande passante lors des tests synthétiques de plus de deux fois pour la lecture et l'écriture, tout en réduisant également les latences de moitié. Lors des tests sur du matériel réel, les frais généraux liés au chiffrement ont pu être réduits presque au niveau observé en travaillant avec un disque sans chiffrement des données.
Cloudflare utilise dm-crypt pour le chiffrement des données sur les disques utilisés pour le caching de contenu dans le réseau CDN. Dm-crypt opère au niveau de l'appareil de bloc et gère le chiffrement des requêtes d'entrée/sortie pour les écritures et le déchiffrement des requêtes de lecture, agissant comme une couche intermédiaire entre l'appareil de bloc et le pilote de système de fichiers.
Pour évaluer la performance de dm-crypt à l'aide du paquet il a été mesuré la vitesse de traitement des partitions chiffrées et non chiffrées sur un disque RAM, placé en RAM pour éviter les fluctuations de performance des disques et se concentrer sur les performances du code. Pour les partitions non chiffrées, les performances de lecture et d'écriture ont atteint 1126 MB/s, mais avec l'activation du chiffrement, la vitesse a chuté de 7 fois et a été de 147 MB/s.
Au départ, il y avait des suspicions sur l'utilisation d'algorithmes inefficaces dans le système de chiffrement du noyau. Mais lors des tests, l'algorithme le plus rapide aes-xts avec une clé de 256 bits a été utilisé, dont les performances lors de l'exécution de « cryptsetup benchmark » étaient plus de deux fois supérieures à celles obtenues lors des tests sur disque RAM. Les expériences avec les flags de dm-crypt pour l'optimisation des performances n'ont pas donné de résultats : l'utilisation du flag « —perf-same_cpu_crypt » a même diminué la performance à 136 MB/s, tandis que l'utilisation du flag « —perf-submit_from_crypt_cpus » n'a augmenté qu'à 166 MB/s.
Une analyse plus approfondie de la logique de fonctionnement a révélé que dm-crypt n'est pas aussi simple qu'il y paraît. Lorsqu'une demande d'écriture est émise par le pilote du système de fichiers, dm-crypt ne la traite pas immédiatement, mais la place dans la file d'attente « kcryptd », qui n'est pas traitée instantanément, mais lors d'un moment opportun. À partir de la file d'attente, la demande est envoyée à l'API Crypto de Linux pour effectuer le chiffrement. Cependant, comme l'API Crypto utilise un modèle d'exécution asynchrone, le chiffrement n'est également pas effectué immédiatement, en contournant une autre file d'attente. Une fois le chiffrement terminé, dm-crypt peut tenter de trier les demandes d'écriture en attente en utilisant un arbre de recherche. . À la fin, un thread séparé du noyau récupère à nouveau les demandes d'entrée/sortie accumulées avec un certain délai et les envoie à la pile du périphérique de bloc.
Lors de la lecture, dm-crypt ajoute d'abord à la file d'attente « kcryptd_io » une demande d'obtention de données du stockage. Après un certain temps, les données deviennent disponibles et sont placées dans la file d'attente « kcryptd » pour le déchiffrement.
Kcryptd envoie la demande à l'API Crypto de Linux, qui déchiffre l'information en mode asynchrone. Les demandes ne passent pas toujours par toutes les files d'attente, mais dans le pire des cas, une demande d'écriture peut rester dans les files d'attente jusqu'à 4 fois, tandis qu'une demande de lecture jusqu'à 3 fois. Chaque passage dans la file d'attente entraîne des délais, qui sont la principale cause de la réduction significative des performances de dm-crypt.
L'utilisation des queues est due à la nécessité de fonctionner en cas d'interruptions. En 2005, lorsque le modèle de fonctionnement actuel de dm-crypt basé sur les queues a été mis en œuvre, le Crypto API n'était pas encore asynchrone. Après la transition du Crypto API vers un modèle d'exécution asynchrone, une double protection a été en fait mise en place. Les queues ont également été introduites pour économiser la consommation de la pile du noyau, mais après son augmentation en 2014, ces optimisations ont perdu leur pertinence. Une queue supplémentaire « kcryptd_io » a été introduite pour surmonter un goulet d'étranglement entraînant des attentes pour l'allocation de mémoire lors de l'arrivée d'un grand nombre de requêtes. En 2015, une phase de tri a également été introduite, car les requêtes de chiffrement sur les systèmes multiprocesseurs pouvaient se terminer sans respecter l'ordre d'envoi (au lieu d'un accès séquentiel au disque, un accès aléatoire était effectué, et le planificateur CFQ ne fonctionnait pas efficacement). Actuellement, avec l'utilisation de disques SSD, le tri a perdu son sens, et le planificateur CFQ n'est déjà plus utilisé dans le noyau.
Étant donné que les disques modernes sont devenus plus rapides et plus intelligents, le système de répartition des ressources dans le noyau Linux a été revu et certaines sous-systèmes ont été retravaillées, les ingénieurs de Cloudflare dans dm-crypt, un nouveau mode de fonctionnement, exempt de l'utilisation de queues superflues et d'appels asynchrones. Le mode est activé par un drapeau distinct « force_inline » et transforme dm-crypt en une simple passerelle, chiffrant et déchiffrant les requêtes entrantes. L'interaction avec le Crypto API a été optimisée par le choix explicite d'algorithmes de chiffrement fonctionnant en mode synchrone et n'utilisant pas de queues de requêtes. Pour un fonctionnement synchrone avec le Crypto API, un module a été créé, permettant d'utiliser le FPU/AES-NI pour accélérer et transmettre directement les requêtes de chiffrement et de déchiffrement.
En fin de compte, lors des tests sur un disque RAM, il a été possible d'augmenter la performance de dm-crypt de plus de deux fois — la performance est passée de 294 Mo/s (2 x 147 Mo/s) à 640 Mo/s, ce qui est très proche de la performance du chiffrement pur (696 Mo/s).
Lors des tests de charge sur des serveurs réels, la nouvelle implémentation a montré des performances très proches de la configuration fonctionnant sans chiffrement, et l'activation du chiffrement sur les serveurs avec le cache Cloudflare n'a pas affecté le temps de réponse. Par la suite, Cloudflare prévoit de transmettre les patchs préparés au noyau principal de Linux, mais ils devront être retravaillés, car ils sont optimisés pour une charge spécifique et ne couvrent pas tous les cas d'utilisation, par exemple, le chiffrement sur des dispositifs embarqués peu puissants.
Source : opennet.ru
