Ontwikkelaars van Cloudflare hebben gewerkt aan de optimalisatie van de prestaties van schijfversleuteling in de Linux-kernel. Dit resulteerde in de subsystemen en Crypto API, die het mogelijk maakten om in synthetische tests de doorvoer bij lezen en schrijven meer dan verdubbelen, en tegelijkertijd de latentie met de helft te verlagen. Bij tests op echte hardware konden de overheadkosten van versleuteling bijna worden verlaagd tot het niveau dat waargenomen wordt met een schijf zonder versleuteling.
Cloudflare gebruikt dm-crypt voor de versleuteling van gegevens op opslagmedia die worden gebruikt voor het cachen van content in het CDN-netwerk. Dm-crypt werkt op blokapparaatniveau en voert versleuteling uit voor schrijf-I/O-aanvragen en decryptie voor leeraanvragen, en fungeert als een laag tussen het blokapparaat en de besturingssystemen voor bestandssystemen.
Om de prestaties van dm-crypt te evalueren, werd het pakket gebruikt om de snelheid van versleutelde en niet-versleutelde partities op een RAM-schijf die in het RAM is geplaatst te meten om fluctuaties in de prestaties van schijven te elimineren en te focussen op de prestaties van de code. Voor niet-versleutelde partities was de lees- en schrijfprestaties 1126 MB/s, maar bij inschakeling van versleuteling daalde de snelheid met 7 keer tot 147 MB/s.
Aanvankelijk was er vermoeden van inefficiƫnte algoritmen in de cryptosystemen van de kernel. Maar in de tests werd het snelste algoritme aes-xts met een 256-bit sleutels gebruikt, waarvan de prestaties tijdens de 'cryptsetup benchmark' meer dan twee keer zo hoog waren als het resultaat verkregen bij de RAM-schijftests. Experimenten met dm-crypt-vlaggen voor prestatie-afstemming leverden geen resultaten op: het gebruik van de vlag '--perf-same_cpu_crypt' verlaagde de prestaties zelfs tot 136 MB/s, terwijl met de vlag '--perf-submit_from_crypt_cpus' de prestaties slechts toenamen tot 166 MB/s.
Een dieper inzicht in de logica van de werking toonde aan dat dm-crypt niet zo eenvoudig is als het lijkt ā bij het ontvangen van een schrijf verzoek van de FS-driver, verwerkt dm-crypt het niet onmiddellijk, maar plaatst het in de 'kcryptd' wachtrij, die niet direct wordt afgehandeld, maar pas wanneer het een geschikt moment is. Vanuit de wachtrij wordt het verzoek naar de Linux Crypto API gestuurd voor encryptie. Maar aangezien de Crypto API een asynchroon uitvoeringsmodel gebruikt, vindt de encryptie ook niet meteen plaats, maar wordt het omgeleid via nog een wachtrij. Na het voltooien van de encryptie kan dm-crypt proberen de wachtende schrijf verzoeken te sorteren, gebruikmakend van een zoekboom. . Aan het einde pakt een aparte kernel thread weer met een bepaalde vertraging de opgestelde invoer-/uitvoer verzoeken en stuurt ze naar de stapel van het blokapparaat.
Bij het lezen voegt dm-crypt aanvankelijk een verzoek voor het verkrijgen van gegevens van het opslagapparaat toe aan de 'kcryptd_io' wachtrij. Na een tijdje worden de gegevens beschikbaar en worden ze naar de 'kcryptd' wachtrij gestuurd voor ontsleuteling.
Kcryptd stuurt een verzoek naar de Linux Crypto API, die de informatie in asynchrone modus ontsleutelt. Verzoeken gaan niet altijd door alle wachtrijen, maar in het slechtste scenario blijft een schrijf verzoek tot 4 keer in wachtrijen hangen, terwijl een lees verzoek tot 3 keer kan vastlopen. Elke keer dat een verzoek in een wachtrij terechtkomt, ontstaan vertragingen, wat de belangrijkste oorzaak is van de aanzienlijke vermindering van de prestaties van dm-crypt.
Het gebruik van queues is het gevolg van de noodzaak om te werken onder omstandigheden waarin onderbrekingen optreden. In 2005, toen het huidige werkmodel van dm-crypt op basis van queues werd geïmplementeerd, was de Crypto API nog niet asynchroon. Na de overstap van de Crypto API naar een asynchroon uitvoeringsmodel werd in feite dubbele bescherming toegepast. Queues werden ook geïntroduceerd om het gebruik van de kernelstack te minimaliseren, maar na de verhoging hiervan in 2014 verloren deze optimalisaties hun relevantie. Een extra queue, 'kcryptd_io', werd ingevoerd om een knelpunt te overwinnen dat leidde tot wachtenden voor geheugentoewijzing bij een grote hoeveelheid aanvragen. In 2015 werd ook een sorteerstap toegevoegd, aangezien versleuteling aanvragen op multiprocessorsystemen soms niet in de verzendvolgorde kon worden voltooid (in plaats van sequentiële toegang tot de schijf, werd er willekeurig toegang verkregen, en bovendien werkte de CFQ-scheduler niet effectief). Tegenwoordig heeft de sortering bij het gebruik van SSD's zijn betekenis verloren, en de CFQ-scheduler wordt niet meer gebruikt in de kernel.
Gezien het feit dat moderne opslagmedia sneller en slimmer zijn geworden, is het systeem voor hulpbronnenverdeling in de Linux-kernel herzien en zijn sommige subsystemen opnieuw ontworpen, Cloudflare-ingenieurs in dm-crypt een nieuwe werkwijze, vrijgesteld van het gebruik van overbodige queues en asynchrone oproepen. De modus kan worden ingeschakeld met een aparte vlag 'force_inline' en brengt dm-crypt in de vorm van een eenvoudige proxy die binnenkomende aanvragen versleutelt en ontsleutelt. De interactie met de Crypto API is geoptimaliseerd door expliciet algoritmen voor versleuteling te kiezen die in synchroniemodus werken en geen aanvragen in queues gebruiken. Voor synchronisatie met de Crypto API was er een module die het gebruik van FPU/AES-NI mogelijk maakt voor versnelling en aanvragen voor versleuteling en ontsleuteling direct doorgeeft.
Uiteindelijk is het gelukt om tijdens het testen van een RAM-schijf de prestaties van dm-crypt meer dan te verdubbelen ā de prestaties stegen van 294 MB/s (2 x 147 MB/s) naar 640 MB/s, wat zeer dicht bij de prestaties van pure versleuteling (696 MB/s) ligt.
Bij het testen van de belasting op echte servers toonde de nieuwe implementatie een prestatie die zeer dicht in de buurt kwam van de configuratie die zonder encryptie werkte, en het inschakelen van encryptie op servers met Cloudflare-cache had geen invloed op de responstijd. In de toekomst is Cloudflare van plan om de voorbereide patches in de hoofdversie van de Linux-kernel op te nemen, maar daarvoor moeten ze worden herwerkt, omdat ze zijn geoptimaliseerd voor specifieke belasting en niet alle toepassingsgebieden dekken, bijvoorbeeld encryptie op energiezuinige embedded apparaten.
Bron: opennet.ru
