web-dev-qa-db-fra.com

DM-CRYPT ABYSMAL DM-CRYPT (LUKS) Ecrire des performances

J'échège un problème dans lequel le cryptage d'un dispositif de bloc impose un énorme Pénalité de performance lorsque écrire. Les heures de lecture et d'expériences sur Internet ne m'ont pas fourni une bonne compréhension, sans parler d'une solution.

La question en bref : Pourquoi est-ce que je reçois des vitesses d'écriture parfaitement rapides lors de la mise sur un dispositif de blocage (~ 170 Mo/s), tandis que la vitesse d'écriture pleure (~ 20 Mo/s) lorsque vous mettez Un DM-Crypt/Luks entre le système de fichiers et le dispositif de bloc, bien que le système soit plus que capable de maintenir un débit de cryptage suffisamment élevé?

Scénario

/home/schlimmchen/random est un fichier de 4,0 Go rempli de données de /dev/urandom plus tôt.

dd if=/dev/urandom of=/home/schlimmchen/Documents/random bs=1M count=4096

Lire c'est super rapide:

$ dd if=/home/schlimmchen/Documents/random of=/dev/null bs=1M
4265841146 bytes (4.3 GB) copied, 6.58036 s, 648 MB/s
$ dd if=/home/schlimmchen/Documents/random of=/dev/null bs=1M
4265841146 bytes (4.3 GB) copied, 0.786102 s, 5.4 GB/s

(la deuxième fois, le fichier a évidemment lu dans le cache).

Btrf non chiffré

L'appareil est directement formaté avec BTRFS (aucune table de partition sur le dispositif de bloc).

$ Sudo mkfs.btrfs /dev/sdf
$ Sudo mount /dev/sdf /mnt
$ Sudo chmod 777 /mnt

La vitesse d'écriture devient jusqu'à ~ 170 Mo/s:

$ dd if=/home/schlimmchen/Documents/random of=/mnt/dd-test1 bs=1M conv=fsync
4265841146 bytes (4.3 GB) copied, 27.1564 s, 157 MB/s
$ dd if=/home/schlimmchen/Documents/random of=/mnt/dd-test2 bs=1M conv=fsync
4265841146 bytes (4.3 GB) copied, 25.1882 s, 169 MB/s
$ dd if=/home/schlimmchen/Documents/random of=/mnt/dd-test3 bs=1M conv=fsync
4265841146 bytes (4.3 GB) copied, 29.8419 s, 143 MB/s

La vitesse de lecture est bien supérieure à 200 Mo/s.

$ dd if=/mnt/dd-test1 of=/dev/null bs=1M
4265841146 bytes (4.3 GB) copied, 19.8265 s, 215 MB/s
$ dd if=/mnt/dd-test2 of=/dev/null bs=1M
4265841146 bytes (4.3 GB) copied, 19.9821 s, 213 MB/s
$ dd if=/mnt/dd-test3 of=/dev/null bs=1M
4265841146 bytes (4.3 GB) copied, 19.8561 s, 215 MB/s

BTRF chiffré sur le périphérique de blocage

L'appareil est formaté avec LUKS et le dispositif résultant est formaté avec BTRFS:

$ Sudo cryptsetup luksFormat /dev/sdf
$ Sudo cryptsetup luksOpen /dev/sdf crypt
$ Sudo mkfs.btrfs /dev/mapper/crypt
$ Sudo mount /dev/mapper/crypt /mnt
$ Sudo chmod 777 /mnt
$ dd if=/home/schlimmchen/Documents/random of=/mnt/dd-test1 bs=1M conv=fsync
4265841146 bytes (4.3 GB) copied, 210.42 s, 20.3 MB/s
$ dd if=/home/schlimmchen/Documents/random of=/mnt/dd-test2 bs=1M 
4265841146 bytes (4.3 GB) copied, 207.402 s, 20.6 MB/s

La vitesse de lecture souffre que marginalement (pourquoi est-ce tout?):

$ dd if=/mnt/dd-test1 of=/dev/null bs=1M
4265841146 bytes (4.3 GB) copied, 22.2002 s, 192 MB/s
$ dd if=/mnt/dd-test2 of=/dev/null bs=1M
4265841146 bytes (4.3 GB) copied, 22.0794 s, 193 MB/s

luksdump: http://pastebin.com/i9vyrr0p

BTRF chiffré dans le fichier sur BTRFS sur le périphérique de blocage

La vitesse d'écriture "Skyrockets" à plus de 150 Mo/s lorsque vous écrivez dans un fichier crypté. Je mettais un fichier BTRF sur le périphérique de bloc, a attribué un fichier de 16 Go, que je lukfsFormat 'ED et monté.

$ Sudo mkfs.btrfs /dev/sdf -f
$ Sudo mount /dev/sdf /mnt
$ Sudo chmod 777 /mnt
$ dd if=/dev/zero of=/mnt/crypted-file bs=1M count=16384 conv=fsync
17179869184 bytes (17 GB) copied, 100.534 s, 171 MB/s
$ Sudo cryptsetup luksFormat /mnt/crypted-file
$ Sudo cryptsetup luksOpen /mnt/crypted-file crypt
$ Sudo mkfs.btrfs /dev/mapper/crypt
$ Sudo mount /dev/mapper/crypt /tmp/nested/
$ dd if=/home/schlimmchen/Documents/random of=/tmp/nested/dd-test1 bs=1M conv=fsync
4265841146 bytes (4.3 GB) copied, 26.4524 s, 161 MB/s
$ dd if=/home/schlimmchen/Documents/random of=/tmp/nested/dd-test2 bs=1M conv=fsync
4265841146 bytes (4.3 GB) copied, 27.5601 s, 155 MB/s

Pourquoi les performances d'écriture sont-elles augmentées comme celle-ci? Qu'est-ce que cet imbrication particulier des systèmes de fichiers et des dispositifs de blocage réalisés pour faciliter les vitesses d'écriture élevées?

Installer

Le problème est reproductible sur deux systèmes exécutant la même distribution et le même noyau. Cependant, j'ai également observé les bases vitesses d'écriture avec le noyau 3.19.0 sur System2.

  • Dispositif: SanDisk extrême 64 Go USB3.0 USB Stick
  • System1: Intel NUC 5I5RYH, I5-5250U (Broadwell), RAM 8 Go, Samsung 840 Evo 250 Go SSD
  • System2: Lenovo T440P, I5-4300M (HASWELL), RAM 16 Go, SAMSUNG 850 PRO 256GB SSD
  • Distro/noyau: Debian Jessie, 3.16.7
  • cRYPETSEUP: 1.6.6
  • /proc/crypto pour system1: http://pastebin.com/qusgmfis
  • cryptsetup benchmark pour system1: http://pastebin.com/4rXzPfet
  • bTRFS (-Tools) est la version 3.17
  • lsblk -t /dev/sdf: http://pastebin.com/nv49twc

Les pensées

  • L'alignement est pas la cause aussi loin que je peux voir. Même si la taille de la page du bâton est de 16kib, le démarrage de la charge utile CryPetUp est aligné sur 2MIB de toute façon.
  • --allow-discards (pour CryptSetup's Luksopen) n'a pas aidé, comme je m'attendais.
  • Tout en faisant beaucoup moins d'expériences avec elle, j'ai observé un comportement très similaire avec un disque dur externe, connecté via un adaptateur USB30.
  • Il me semble que le système écrit des blocs de 64Kib. A script systemtrap J'ai essayé indique qu'au moins. /sys/block/sdf/stat soutient cette hypothèse depuis que beaucoup d'écritures sont fusionnées. Je suppose donc que l'écriture dans des blocs trop petits n'est pas la cause.
  • Pas de chance avec la modification du planificateur de la file d'attente du périphérique de bloc à Noop.
  • Mettre la crypte dans un volume LVM n'a pas aidé.
24
schlimmchen

La réponse (comme je le sais maintenant): Concurrence .

en bref : mon Ecrivez séquentiel, en utilisant dd ou lors de la copie d'un fichier (comme ... Dans une utilisation quotidienne), devient A écrit pseudo-aléatoire (mauvais) car quatre threads fonctionnent simultanément sur la rédaction des données cryptées sur le périphérique de bloc après cryptage simultané (bon).

Atténuation (pour "plus âgés" des noyaux)

L'effet négatif peut être atténué en augmentant la quantité de demandes en file d'attente dans la file d'attente de planificateur IO comme celle-ci:

echo 4096 | Sudo tee /sys/block/sdc/queue/nr_requests

Dans mon cas, il est presque triple (~ 56 Mo/s) le débit pour le test de données aléatoire de 4 Go expliqué dans ma question. Bien entendu, la performance tombe toujours à 100 Mo/s comparé à l'IO non crypté.

Enquête

Multicore blktrace

J'ai également enquêté sur le scénario problématique dans lequel une BTRFS est placée sur un haut d'un dispositif de bloc crypté LUKS. Pour me montrer quelles instructions d'écriture sont émises sur le périphérique de bloc réel, j'ai utilisé blktrace comme celui-ci:

Sudo blktrace -a write -d /dev/sdc -o - | blkparse -b 1 -i - | grep -w D

Ce que cela fait est (autant que j'ai pu comprendre) trace IO demande à /dev/sdc qui sont de type "écrire", puis analysez ceci à la production lisible humaine, mais restreindre davantage La sortie à l'action "[~ # ~] d [~ # ~ ~]", qui est (selon man blkparse) "io délivré au pilote".

Le résultat était comme celui-ci (voir environ 5000 lignes de sortie du journal multicœur ):

8,32   0    32732   127.148240056     3  D   W 38036976 + 240 [ksoftirqd/0]
8,32   0    32734   127.149958221     3  D   W 38038176 + 240 [ksoftirqd/0]
8,32   0    32736   127.160257521     3  D   W 38038416 + 240 [ksoftirqd/0]
8,32   1    30264   127.186905632    13  D   W 35712032 + 240 [ksoftirqd/1]
8,32   1    30266   127.196561599    13  D   W 35712272 + 240 [ksoftirqd/1]
8,32   1    30268   127.209431760    13  D   W 35713872 + 240 [ksoftirqd/1]
  • Colonne 1: majeur, mineur du dispositif de blocage
  • Colonne 2: ID CPU
  • Colonne 3: Numéro de séquence
  • Colonne 4: Time Time
  • Colonne 5: ID de processus
  • Colonne 6: Action
  • Colonne 7: Données RWBS (type, secteur, longueur)

Ceci est une extraction de la sortie produite lors de dd 'ing des données aléatoires de 4 Go sur le système de fichiers monté. Il est clair qu'au moins deux processus sont impliqués. Le journal restant montre que les quatre processeurs y travaillent réellement. Malheureusement, les demandes d'écriture ne sont plus commandées. Bien que la CPU0 écrit quelque part autour du secteur 38038416e, CPU1, qui est prévu après, écrit quelque part autour du secteur 35713872ND. C'est mauvais.

Singlecore blktrace

J'ai fait la même expérience après avoir désactivé le multi-filetage et la désactivation du deuxième noyau de mon processeur. Bien sûr, un seul processeur est impliqué par écrit sur le bâton. Mais plus important encore, la demande d'écriture sont correctement séquentielles, c'est pourquoi les performances d'écriture complètes d'~ 170 Mo/s sont obtenues dans la même configuration.

Jetez un coup d'œil à environ 5000 lignes de sortie dans le journal SingLecore .

Discussion

Maintenant que je connais la cause et les termes de recherche Google appropriés, les informations sur ce problème bouillonnent à la surface. Comme il s'avère, je ne suis pas le premier à remarquer.

Fixé dans les noyaux actuels (> = 4.0.2)

Parce que je (plus tard) trouvé le Bernel Engage évidemment ciblé à ce problème exact, je voulais essayer un noyau mis à jour. [Après la compilation moi-même, puis découvrez qu'il est déjà dans debian/sid] Il s'avère que le problème est en effet corrigé. Je ne connais pas la libération exacte du noyau dans laquelle le correctif est apparu, mais le Engagements originaux donner des indices à quiconque intéressé.

Pour le record:

$ uname -a
Linux t440p 4.0.0-1-AMD64 #1 SMP Debian 4.0.2-1 (2015-05-11) x86_64 GNU/Linux
$ dd if=/home/schlimmchen/Documents/random of=/mnt/dd-test bs=1M conv=fsync
4294967296 bytes (4.3 GB) copied, 29.7559 s, 144 MB/s

Un conseil de chapeau à Mikulas Patocka, qui a rédigé le commit.

21
schlimmchen