Réglage fin de la swap

Palaiseau, le dimanche 29 mars 2020

Cher Journal,

Avec la priorité mise sur les tâches dédiées à la recherche médicale, j'ai un certain nombre de jobs résiduels qui sont coincés en attente d'exécution. Néanmoins, ces jobs ayant déjà démarré, dans la mesure du possible, je n'ai pas envie de perdre leurs résultats. D'autant plus que, manifestement, probablement vu que leur échéance est plus tardive que les jobs Rosetta, ils reçoivent peu de tranches de temps pour s'exécuter. Ils sont donc partis pour rester là un bon bout de temps.

État des lieux

Extraits de la page de surveillance ce jour à 19:30, les jobs en question apparaissaient comme suit dans la commande top :

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
[...]
   1283 boinc     39  19 1406992   1.3g  18620 T   0.0   8.5   5949:22 hadam4_+
 445888 boinc     39  19 1026044 996.4m   2580 S   0.0   6.2   1093:07 einstei+
 457107 boinc     39  19  612236 606372   2484 S   0.0   3.7 478:13.30 einstei+
 458372 boinc     39  19 1227972   1.2g   2612 S   0.0   7.4 484:00.81 einstei+
[...]

Quand au client boinc, vis-à-vis de ces jobs, il les rapportait comme tels dans la table :

JobProjectStateProgressDeadline
1climatepredictionSUSPENDED47%2021-02-27T04:43:17 +0100
2einsteinSUSPENDED63%2020-04-08T13:48:10 +0200
3einsteinSUSPENDED31%2020-04-08T13:48:14 +0200
4einsteinSUSPENDED37%2020-04-10T00:33:06 +0200
5einsteinUNINITIALIZED0%2020-04-10T00:33:06 +0200
...............

À noter, le job en état uninitialized n'a jamais démarré, donc n'est rattaché à aucun processus Unix, donc ne consomme pas de mémoire. Sinon, ces processus sont en train de consommer au bas mot environs 4 Gio de mémoire vive, et je n'ai aucune envie de les tuer. Il y a notamment neuf jours de calcul dans la tâche climateprediction, actuellement en état stoppé, et ce serait dommage de les perdre.

Mitigation des effets de la mémoire paginée

À une époque révolue où la mémoire vive me semblait infinie avec 4 Gio, je ne mettais pas de swap et m'en accommodait très bien. Sauf que quand le système commence à utiliser une quantité de mémoire non négligeable devant la taille disponible, alors il devient excessivement lent, et ce avant que l'OOM killer n'ait une chance de se déclencher pour permettre à la machine de respirer. Plusieurs stratégies sont possibles pour limiter les chutes de performances liées à la swap :

Ma stratégie favorite à l'heure actuelle consiste à utiliser la zswap avec la configuration suivante, et ajouter à cela une petite partition de swap de 1 Gio sur le disque.

$ cd /sys/module/zswap/parameters
$ grep . *
compressor:lz4hc
enabled:Y
max_pool_percent:20
same_filled_pages_enabled:Y
zpool:zbud

Une partition de 1 Gio, c'est bien pour évacuer les bricoles qui n'ont rien à faire en mémoire vive, mais qui y sont tout de même, et si un processus accapare toute la mémoire vive, il ne va pas non plus falloir attendre de remplir des gigaoctets de disque dur avant que l'OOM killer ne soit appelé. Sauf que là, potentiellement, les bricoles en question que sont ces jobs en sommeil ne rentreront pas dans la swap.

Partitions de swap hétérogène

Je n'avais plus de place sur le disque après avoir augmenté récemment la partition non cachée /mnt/disk, justement pour faire de la place pour Boinc. Du coup, je n'ai pas pu étendre ma swap existante sur ce disque, ou seulement de 520 Mio. Par contre il me restait pas mal d'espace non utilisé du côté du SSD. J'y ai donc créée un volume de 4 Gio, nommé fastswap étant donné ses performances au regard de ce que la swap sur disque lvswap m'apporte actuellement au moment de restaurer les pages en mémoire.

Les différentes swap d'un même système ont des ordres de priorité : celles avec les valeurs les plus élevées sont utilisées en premier, et si deux swap on même priorité, alors les pages sont envoyées alternativement sur l'une et l'autre partition. Ce point est documenté dans la page de manuel de swapon(8). En temps normal, Linux est capable de faire la distinction entre les supports SSD à accès aléatoire rapide, et les disques rotatifs, qui ont beaucoup plus de latence, et va adapter les priorités en conséquence, voir la sortie de la commande dmesg :

Adding 4194300k swap on /dev/mapper/vgcache-fastswap.  Priority:-2 extents:1 across:4194300k SSDscFS
Adding 1581052k swap on /dev/mapper/vgcache-lvswap.  Priority:-3 extents:1 across:1581052k FS

Sauf que pour une raison qui était finalement documentée dans swapon(2) (les partitions de swap ajoutées après coup sont toujours moins prioritaires que les partitions de swap existantes), les priorités étaient à l'envers lorsque j'ai activé la swap de mon SSD pour la première fois. Ma swap initiale de 1 Gio avait la priorité -2, qui était plus haute que celle du SSD, de priorité -3 à l'activation. Il est possible de changer les priorités des partitions de swap dans le fichier /etc/fstab, avec les options pri= :

UUID=1366d652-103e-4800-9906-05ca471e485d / xfs relatime,discard 0 1
/dev/vgcache/lvhome   /mnt/data  xfs    relatime,discard         0 2
/dev/vgcache/lvdisk   /mnt/disk  xfs    relatime                 0 2
/dev/vgcache/fastswap none       swap   sw,discard,pri=5         0 0
/dev/vgcache/lvswap   none       swap   sw,pri=1                 0 0
tmpfs                 /tmp       tmpfs  defaults                 0 0

À partir ce moment, la swap va avoir ces priorités élevées lors de la mise en route avec swapon, en témoigne dmesg :

Adding 4194300k swap on /dev/mapper/vgcache-fastswap.  Priority:5 extents:1 across:4194300k SSDscFS
Adding 1581052k swap on /dev/mapper/vgcache-lvswap.  Priority:1 extents:1 across:1581052k FS

Le manuel indique que les valeurs de priorité valides vont entre -1 et 32767. D'après mes observations, quand -1 est indiqué, alors le noyau va appliquer la valeur qui lui semble la plus adéquate, ici -2 pour le disque quand le SSD a une valeur de priorité positive ou nulle.

Bref, on verra si ce montage tient bien sur la durée. Qui aurait cru que gérer de la swap pouvait être aussi sinueux ?

[ICO]NameLast modifiedSize
[PARENTDIR]Parent Directory  -

  —