dadv: (chuck)
Choose your future ([personal profile] dadv) wrote2013-12-15 05:19 am

Криптоакселерация

Домашним роутером работает у меня FreeBSD 9.2/i386 на безвентилляторной системе IPC2U NISE-3120-LX8 (чипсет Geode CS5536, форм-фактор PCI-104). В ней есть криптоакселератор, который поддерживается FreeBSD:

# dmesg | egrep 'CPU|glxsb'
CPU: Geode(TM) Integrated Processor by AMD PCS (499.91-MHz 586-class CPU)
glxsb0: <AMD Geode LX Security Block (AES-128-CBC, RNG)> mem 0xef01c000-0xef01ffff at device 1.2 on pci0

Решил сравнить производительность подсистемы crypto с программным шифрованием и с аппаратным.

Для этого в OpenSSL 0.9.8y есть команда openssl speed -evp, которая выполняет тестирование указанного алгоритма. По умолчанию, эта команда замеряет только user time, а при использовании криптоакселератора основная работа идёт не в пользовательском коде, поэтому нужно выполнять тест на незагруженной системе и использовать ключ -elapsed для учёта реального времени.

Выполняем команду openssl speed -evp aes-128-cbc -elapsed без загруженного модуля адра cryptodev (поддержка аппаратного ускорения) трижды, получаем примерно одинаковые значения:

type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
aes-128-cbc       4737.17k     5312.96k     5494.46k     5544.68k     5553.33k
aes-128-cbc       4741.90k     5308.79k     5493.78k     5535.09k     5561.57k
aes-128-cbc       4741.39k     5318.00k     5495.19k     5536.29k     5559.38k

Этот CPU может шировать пять с половиной мегабайт в секунду алгоритмом AES-128-CBC.

Вот что при этом показывал top -SHPI:

CPU: 98.9% user,  0.0% nice,  1.1% system,  0.0% interrupt,  0.0% idle
Mem: 72M Active, 721M Inact, 135M Wired, 6464K Cache, 88M Buf, 54M Free
Swap:
   
  PID USERNAME      THR PRI NICE   SIZE    RES STATE    TIME   WCPU COMMAND
14030 root            1  71    0 11120K  3060K RUN      0:12 98.18% openssl

Повторяем тест после kldload cryptodev (появляется файл устройства /dev/crypto). Можно добавлять флаг -engine cryptodev, можно не добавлять - поддержка подхватывается автоматически:

type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
aes-128-cbc        500.13k     1939.22k     6782.57k    18173.68k    30275.02k
aes-128-cbc        501.09k     1951.16k     6817.56k    18193.03k    30291.28k
aes-128-cbc        502.21k     1943.75k     6790.59k    18180.74k    30328.81k

Результат неоднозначный: на 16-байтных блоках использование аппаратного ускорителя даёт замедление в 9.4 раза, на 64-байтных блоках замедление в 2.7 раза, на 256-байтных ускорение в 1.24 раза, на килобайтных ускорение в 3.2 раза и на 8-килобайтных ускорение в 5.4 раза. Показания top -SHPI:

CPU:  2.0% user,  0.0% nice, 97.0% system,  1.0% interrupt,  0.0% idle
Mem: 73M Active, 722M Inact, 135M Wired, 6464K Cache, 88M Buf, 53M Free
Swap:
  PID USERNAME     PRI NICE   SIZE    RES STATE    TIME   WCPU COMMAND
14051 root          62    0 11120K  3052K RUN      0:03 41.90% openssl
   10 root         155 ki31     0K     8K RUN     55.4H 28.42% idle
    0 root         -92    0     0K    72K -        2:37 26.12% kernel{glxsb0 taskq}
    2 root           8    -     0K     8K crypto   0:26  4.64% crypto
14050 root          40    0  9808K  2004K RUN      0:00  0.38% top

Разгадка проста, достаточно сравнить вывод top -m io для программного прогона:

  PID USERNAME       VCSW  IVCSW   READ  WRITE  FAULT  TOTAL PERCENT COMMAND
14076 root              1   2250      0      0      0      0   0.00% openssl

И при использовании ускорителя:

  PID USERNAME       VCSW  IVCSW   READ  WRITE  FAULT  TOTAL PERCENT COMMAND
14083 root          62265    653      0      0      0      0   0.00% openssl

Тут VCSW это voluntary context switches, а IVCSW - involuntary. В данном случае принудительные переключения контекста (IVCSW) выполнял системный планировщик по истечении квантов времени процесса, а безумное количество VCSW соответствует безумному количеству системных вызовов ioctl(), при помощи которых происходит общение приложения с криптоускорителем и накладные расходы на которые и съели производительность в случае мелких блоков.

[identity profile] mega-mosk.livejournal.com 2013-12-15 12:21 pm (UTC)(link)
Весьма занимательно, но откуда там столько ioctl?

[identity profile] dadv.livejournal.com 2013-12-15 12:23 pm (UTC)(link)
Не разбирался. Не исключено, что каждая операция шифрования блока это отдельный сисколл.

[identity profile] andrey elsukov (from livejournal.com) 2013-12-18 10:15 am (UTC)(link)
Про сисколы - вполне логично, а ещё есть мнение, что использовать эти девайсы не безопасно :)
http://arstechnica.com/security/2013/12/we-cannot-trust-intel-and-vias-chip-based-crypto-freebsd-developers-say/