Gli sviluppatori di Cloudflare sull'ottimizzazione delle prestazioni della crittografia su disco nel kernel Linux. Di conseguenza, sono stati preparati per il sottosistema e Crypto API, che hanno consentito di aumentare di oltre due volte la capacità di throughput nei test sintetici durante la lettura e la scrittura, oltre a ridurre i ritardi di circa la metà. Durante i test su hardware reale, i costi aggiuntivi dovuti alla crittografia sono stati ridotti praticamente ai livelli osservati con un disco senza crittografia.
Cloudflare utilizza dm-crypt per la crittografia dei dati sui dispositivi di memorizzazione impiegati per la memorizzazione nella rete CDN. Dm-crypt opera a livello di dispositivo a blocchi e gestisce la crittografia delle richieste di I/O in scrittura e la decrittazione delle richieste di lettura, fungendo da strato intermedio tra il dispositivo a blocchi e il driver del file system.
Per valutare le prestazioni di dm-crypt è stato utilizzato il pacchetto che ha misurato la velocità di accesso a partizioni crittografate e non crittografate su un disco RAM, posizionato in RAM per escludere fluttuazioni nelle prestazioni dei dischi e concentrarsi sulle prestazioni del codice. Per le partizioni non crittografate, le prestazioni in lettura e scrittura si sono mantenute intorno a 1126 MB/s, ma con l'abilitazione della crittografia la velocità è diminuita di 7 volte portandosi a 147 MB/s.
Inizialmente, si sospettava l'uso di algoritmi inefficienti nel sistema crittografico del kernel. Tuttavia, nei test è stato utilizzato l'algoritmo aes-xts con una chiave di crittografia a 256 bit, la cui prestazione, durante l'esecuzione di "cryptsetup benchmark", è superiore di oltre il doppio rispetto al risultato ottenuto nei test del disco RAM. Esperimenti con le opzioni di dm-crypt per l'ottimizzazione delle prestazioni non hanno portato risultati: utilizzando l'opzione "--perf-same_cpu_crypt" le prestazioni sono diminuite a 136 MB/s, mentre specificando l'opzione "--perf-submit_from_crypt_cpus" sono aumentate solo a 166 MB/s.
Un'analisi più approfondita della logica di funzionamento ha rivelato che dm-crypt non è così semplice come sembra: quando viene ricevuta una richiesta di scrittura dal driver FS, dm-crypt non la elabora immediatamente, ma la mette in coda per «kcryptd», che non si occupa di essa subito, ma quando si verifica un momento opportuno. Dalla coda, la richiesta viene inviata all'API Crypto di Linux per l'esecuzione della crittografia. Tuttavia, poiché l'API Crypto utilizza un modello di esecuzione asincrono, la crittografia non viene eseguita immediatamente, ma passa attraverso un'altra coda. Dopo il completamento della crittografia, dm-crypt può tentare di ordinare le richieste di scrittura in attesa, utilizzando un albero di ricerca. . Alla fine, un thread separato del kernel raccoglie nuovamente, dopo un certo ritardo, le richieste di input/output accumulate e le invia allo stack del dispositivo a blocchi.
Durante la lettura, dm-crypt inizialmente aggiunge alla coda «kcryptd_io» una richiesta per ottenere dati dal supporto di memorizzazione. Dopo un certo tempo, i dati diventano disponibili e vengono inseriti nella coda «kcryptd» per la decrittazione.
Kcryptd invia la richiesta all'API Crypto di Linux, che decrittografa le informazioni in modalità asincrona. Le richieste non sempre attraversano tutte le code, ma nel peggiore dei casi la richiesta di scrittura può rimanere nelle code fino a 4 volte, mentre la richiesta di lettura fino a 3 volte. Ogni passaggio in coda provoca ritardi, che sono la causa principale della significativa diminuzione delle prestazioni di dm-crypt.
L'uso delle code è dovuto alla necessità di lavorare in condizioni di interruzione. Nel 2005, quando è stata implementata l'attuale modalità di funzionamento di dm-crypt basata su code, il Crypto API non era ancora asincrono. Dopo la transizione del Crypto API a un modello di esecuzione asincrono, è stata in sostanza introdotta una doppia protezione. Le code sono state introdotte anche per risparmiare sul consumo dello stack del kernel, ma dopo il suo aumento nel 2014, tali ottimizzazioni hanno perso rilevanza. Una coda aggiuntiva "kcryptd_io" è stata introdotta per superare il collo di bottiglia che causava attese nell'allocazione della memoria a fronte di un grande numero di richieste. Nel 2015, è stata introdotta anche una fase di ordinamento, poiché le richieste di crittografia nei sistemi multiprocessore potevano concludersi senza rispettare l'ordine di invio (invece dell'accesso sequenziale al disco, si effettuava un accesso casuale, e il pianificatore CFQ non funzionava in modo efficace). Al giorno d'oggi, con l'uso degli SSD, l'ordinamento ha perso significato e il pianificatore CFQ non è più utilizzato nel kernel.
Considerando che i moderni dispositivi di memoria sono diventati più veloci e intelligenti, il sistema di distribuzione delle risorse nel kernel Linux è stato rivisto e alcune sottosistemi sono stati ripensati dagli ingegneri di Cloudflare. In dm-crypt, è stata introdotta una nuova modalità operativa, libera dall'uso di code superflue e chiamate asincrone. La modalità si attiva con un'apposita flag "force_inline" e trasforma dm-crypt in una semplice proxy che cripta e decripta le richieste in arrivo. L'interazione con il Crypto API è stata ottimizzata grazie alla selezione esplicita degli algoritmi di crittografia, che operano in modalità sincrona e non utilizzano code di richieste. Per un funzionamento sincrono con il Crypto API, è stato implementato un modulo che consente di utilizzare FPU/AES-NI per accelerare e inoltrare direttamente le richieste di crittografia e decrittografia. modulo che consente di utilizzare FPU/AES-NI per accelerare e inoltrare direttamente le richieste di crittografia e decrittografia.
Di conseguenza, durante i test con un disco RAM, è stato possibile aumentare la performance di dm-crypt di oltre il doppio — la performance è aumentata da 294 MB/s (2 x 147 MB/s) a 640 MB/s, molto vicina alla performance della crittografia nuda (696 MB/s).
Durante i test di carico su server reali, la nuova implementazione ha mostrato prestazioni molto simili a quelle di una configurazione funzionante senza crittografia, e l'attivazione della crittografia sui server con cache Cloudflare non ha influenzato in alcun modo la velocità di risposta. In futuro, Cloudflare prevede di inviare le patch preparate al kernel principale di Linux, ma prima sarà necessario rielaborarle, poiché sono ottimizzate per un carico specifico e non coprono tutti i casi d'uso, ad esempio, la crittografia su dispositivi embedded a bassa potenza.
Fonte: opennet.ru
