Разработчиците от компания Cloudflare информираха за работата по оптимизацията на производителността на дисковото криптиране в ядрото на Linux. В резултат бяха подготвени за подсистемата и Crypto API, които позволиха в синтетичен тест да се увеличи пропускната способност при четене и запис повече от два пъти, като същевременно значително намалят забавянето. При тестване на реално оборудване, разходите от криптиране успяха да бъдат сведени почти до нивото, наблюдавано при работа с диск без криптиране на данни.
Cloudflare използва dm-crypt за криптиране на данни на устройствата, използвани за кеширане на съдържание в мрежата на CDN. Dm-crypt работи на ниво блоковото устройство и изпълнява криптиране на заявки за запис и декриптиране на заявки за четене, като действа като слой между блоковото устройство и системния драйвер на файловата система.
За оценка на производителността на dm-crypt с помощта на пакета бяха извършени измервания на скоростта на работа с криптирани и некриптирани дялове на RAM-диск, разположен в оперативната памет, за да се изключат флуктуации в производителността на дисковете и да се фокусира върху производителността на кода. За некриптираните дялове производителността на четене и запис се поддържаше на ниво 1126 MB/s, но при включване на криптиране скоростта намаля седем пъти и достигна 147 MB/s.
Първоначално имаше съмнение за използването на неефективни алгоритми в криптосистемата на ядрото. Но в тестовете беше използван най-бързият алгоритъм aes-xts с 256-битов ключ за криптиране, чиято производителност при изпълнението на „cryptsetup benchmark“ е повече от два пъти по-висока от получените резултати от тестовете на RAM-диска. Експериментите с флаговете на dm-crypt за настройка на производителността не доведоха до резултати: при използване на флага „—perf-same_cpu_crypt“ производителността дори спадна до 136 MB/s, а при указване на флага „—perf-submit_from_crypt_cpus“ нарасна само до 166 MB/s.
По-дълбокото разглеждане на логиката на работа показа, че dm-crypt не е толкова прост, колкото изглежда. При получаване на запитване за запис от драйвера на файловата система, dm-crypt не го обработва незабавно, а го поставя в опашката 'kcryptd', която не се обработва веднага, а при удобен момент. От опашката запитването се изпраща в Linux Crypto API за извършване на криптиране. Но тъй като Crypto API използва асинхронен модел на изпълнение, криптирането също не се извършва незабавно, а минава през още една опашка. След приключване на криптирането, dm-crypt може да се опита да извърши сортиране на изчакващите запитвания за запис, използвайки дърво на търсене. . В края на краищата, отделен поток от ядрото отново с определено забавяне приема натрупаните запитвания за вход/изход и ги изпраща в стека на блочното устройство.
При четене в началото dm-crypt добавя в опашката 'kcryptd_io' запитване за получаване на данни от носителя. След известно време данните стават достъпни и се поставят в опашката 'kcryptd' за декриптиране.
Kcryptd изпраща запитването в Linux Crypto API, който декриптира информацията в асинхронен режим. Запитванията не винаги преминават през всичките опашки, но в най-лошия сценарий запитването за запис задържа в опашките до 4 пъти, а запитването за четене до 3 пъти. Всяко преминаване през опашка води до възникване на забавяния, които са основната причина за значителното намаляване на производителността на dm-crypt.
Използването на опашки е продиктувано от необходимостта да работи в условия на прекъсвания. През 2005 година, когато беше реализирана текущата модел на работа на dm-crypt на базата на опашки, Crypto API все още не беше асинхронен. След преминаването на Crypto API към асинхронен модел на изпълнение, всъщност се наложи двойна защита. Опашките също бяха въведени за спестяване на потреблението на стека на ядрото, но след увеличаването му през 2014 година, тези оптимизации загубиха актуалност. Допълнителна опашка „kcryptd_io“ беше въведена, за да се преодолее тясното място, което водеше до чакане за заделяне на паметта при голям брой входящи заявки. През 2015 година допълнително беше въведена фаза на сортиране, тъй катоrequests за шифроване при многопроцесорни системи можеха да завършват, без да спазват реда на изпращане (вместо последователен достъп до диска, се осъществяваше достъп в случайния ред, а също така планировникът CFQ не работеше ефективно). В момента, при използване на SSD устройства, сортирането загуби смисъл, а планировникът CFQ вече не се използва в ядрото.
Като се има предвид, че съвременните устройства станаха по-бързи и по-умни, системата за разпределение на ресурси в ядрото на Linux беше преразгледана и някои подсистеми бяха преработени, инженерите на Cloudflare в dm-crypt нов режим на работа, освободен от използването на излишни опашки и асинхронни повиквания. Режимът се активира с отделен флаг „force_inline“ и превръща dm-crypt в просто прокси, което шифрова и дешифрова входящите заявки. Взаимодействието с Crypto API беше оптимизирано чрез явен избор на алгоритми за шифроване, работещи в синхронен режим и не използващи опашки от заявки. За синхронна работа с Crypto API беше модул, който позволява използването на FPU/AES-NI за ускорение и директно пробразуващ заявки за шифроване и дешифриране.
В резултат на това, при тестване на RAM диска, производителността на dm-crypt беше увеличена повече от два пъти — производителността се увеличи от 294 MB/s (2 x 147 MB/s) на 640 MB/s, което е много близо до производителността на чистото шифроване (696 MB/s).
При теста за натовареност на реални сървъри новата реализация показа производителността много близка до конфигурацията, работеща без криптиране, а включването на криптиране на сървъри с кеширане от Cloudflare не повлия на времето за отговор. В бъдеще Cloudflare планира да предаде подготвените пачове в основното ядро на Linux, но преди това те трябва да бъдат преработени, тъй като са оптимизирани за определено натоварване и не обхващат всички области на приложение, например криптиране на слабо мощни вградени устройства.
Източник: opennet.ru
