1 points par GN⁺ 2025-02-18 | 1 commentaires | Partager sur WhatsApp
  • Sur un desktop Linux basé sur une AMD RX 570, la mise en veille avec une forte utilisation de la RAM provoquait de façon répétée un écran noir ou un système ne répondant plus au réveil, ce qui a conduit à remonter bien au-delà d’un simple problème d’affichage, jusqu’au flux de gestion d’alimentation du noyau
  • La cause principale se situait dans le fait qu’amdgpu, qui doit sauvegarder la VRAM dans la RAM système avant une veille S3, ne parvenait pas à exploiter correctement le swap disque quand la RAM libre manquait, et finissait en OOM
  • Un premier patch avançant l’éviction de la VRAM de dpm_suspend() vers dpm_prepare() a réduit la compétition avec l’extinction du SSD, mais pm_restrict_gfp_mask() désactivait déjà le swap, si bien qu’un manque de mémoire contiguë restait possible
  • Ensuite, le fait de passer par register_pm_notifier() pour appeler amdgpu_device_evict_resources() au moment de PM_SUSPEND_PREPARE a permis de sauvegarder la VRAM tant que le swap et le disque restaient actifs, ce qui a permis, dans l’environnement de test, de réussir la mise en veille même avec une forte consommation de RAM et de VRAM
  • Ce changement a bien été fusionné dans l’arbre amdgpu, mais a été annulé en 2025-06 à cause d’une possibilité de deadlock : sur les chemins de veille qui ne figent pas d’abord les processus utilisateurs, une application 3D peut recharger la VRAM vers le GPU et empêcher l’éviction

Échecs répétés de mise en veille et erreur de diagnostic initiale

  • Le desktop était configuré en dual boot Windows/Linux, et sous Linux, quand l’utilisation de la RAM était élevée, une tentative de mise en veille faisait souvent planter le système
    • Au réveil, on ne voyait parfois qu’un écran noir avec un curseur mobile, ou bien aucune sortie vidéo, le système ne réagissant plus qu’à magic SysRq ou à un reset matériel
    • Dans certains cas, l’horloge de l’écran de verrouillage KDE continuait à se mettre à jour en temps réel, mais toute tentative de connexion ou d’interaction finissait par geler
  • L’environnement de test était composé d’une carte mère Gigabyte B550M DS3H, d’un GPU AMD RX 570, d’un SSD NVMe Kingston A2000 1 To, d’Arch Linux, de systemd-boot et de Linux 6.4
  • En consultant les logs du démarrage précédent avec journalctl --system -b -1, des erreurs OOM sont apparues dans le code noyau sous amdgpu_device_suspend lors de certaines tentatives de veille
  • De nombreux cas d’échec se terminaient par les logs suivants, sans aucune trace de réveil du système planté
    • systemd-sleep: Entering sleep state 'suspend'...
    • kernel: PM: suspend entry (deep)
  • Au départ, le mode d’économie d’énergie NVMe APST a été soupçonné, et plusieurs essais ont été faits avec nvme_core.default_ps_max_latency_us=0, iommu=soft, une mise à jour du firmware du SSD, puis le remplacement du SSD de démarrage 2 To, sans résoudre le problème

Outils de débogage ayant permis de circonscrire l’emplacement de l’échec

  • Le fait que systemd essaye plusieurs modes de veille à la suite pouvait créer du bruit dans les logs et dégrader l’état du noyau, donc SuspendState=mem a été ajouté à /etc/systemd/sleep.conf
    • Le débogage est devenu plus simple, mais la cause profonde restait inchangée
  • echo 1 > /sys/power/pm_trace a servi à suivre l’endroit où la veille échouait
    • pm_trace enregistre l’état d’avancement de la séquence veille/réveil dans l’horloge système
    • Grâce à l’effet secondaire qui désactive la veille asynchrone, il a aussi été possible d’observer des cas où, après un échec de suspension d’amdgpu, le système se rétablissait au lieu de se figer complètement
  • Le paramètre noyau systemd.debug_shell a été ajouté pour obtenir un shell root sur Ctrl-Alt-F9 sans passer par un login KDE ou TTY
  • Un clavier PS/2 a été utilisé au cas où le contrôleur USB et le clavier cesseraient de fonctionner, puis une console série a été mise en place
    • Paramètres noyau : no_console_suspend console=tty0 console=ttyS0,115200 loglevel=8
    • Les logs étaient capturés en continu depuis un laptop via sudo minicom --device /dev/ttyUSB0 --baudrate 115200
    • La console série permettait encore d’exécuter des commandes et de collecter les logs même après la panne de l’affichage et du réseau, avec toutefois des limites de débit et de gestion des couleurs ou de la taille d’écran

Le lien entre l’éviction de VRAM d’amdgpu et l’OOM

  • Les logs de crash pointaient généralement vers le chemin d’éviction des buffers TTM d’amdgpu
    • amdgpu_device_evict_resources()
    • amdgpu_ttm_evict_resources()
  • D’après des rapports de bug connexes, « evict » désignait ici le fait de copier la VRAM vers la RAM système, ou de pousser ensuite la RAM système vers le swap
  • Quand le desktop entre en veille S3, l’alimentation du GPU PCIe est coupée et les données stockées dans les puces VRAM disparaissent
    • Le pilote GPU doit donc copier vers la RAM système la VRAM en cours d’utilisation avant la mise en veille
    • Au réveil, il doit restaurer ces données depuis la RAM
  • Le pilote Linux amdgpu avait un problème : lorsqu’il n’y avait pas assez de RAM libre pour contenir toute la VRAM utilisée, il pouvait planter par manque de mémoire au lieu de déporter correctement la RAM système vers le swap disque
  • Si Linux rencontre un OOM pendant la veille, il annule la suspension et tente de redémarrer les périphériques, mais certains pilotes peuvent déjà être dans un état incohérent ou provoquer un nouvel OOM pendant la veille ou le réveil
    • Le risque est encore plus élevé avec la veille asynchrone activée
    • La veille peut même réussir, mais un OOM peut survenir ensuite au redémarrage des périphériques pendant le réveil

Première tentative de correction : avancer le moment de la sauvegarde de la VRAM

  • Mario Limonciello a suggéré d’activer /sys/power/pm_print_times et /sys/power/pm_debug_messages puis d’examiner les logs de veille
  • Les logs montraient que les pilotes NVMe et amdgpu entraient en parallèle dans pci_pm_suspend pendant la veille
  • La première piste a consisté à chercher comment faire suspendre le GPU avant le SSD, puis à examiner le mécanisme Linux d’ordonnancement de suspension des périphériques
    • Ce mécanisme semblait davantage conçu pour synchroniser des périphériques étroitement liés que pour suspendre systématiquement tous les GPU avant tous les disques système
  • Mario a proposé d’éjecter la VRAM pendant l’étape prepare de la veille Linux, puis a écrit un patch noyau déplaçant l’éviction de VRAM de dpm_suspend() vers dpm_prepare()
  • Avant et après la modification, le flux était le suivant
    • Avant : la sauvegarde de la VRAM s’exécutait au moment de dpm_suspend(), avec un risque de chevauchement avec l’extinction du SSD
    • Après : la sauvegarde de la VRAM était tentée dès dpm_prepare(), et en cas d’échec, la veille était interrompue avant la suspension des autres périphériques
  • Cette modification améliorait la situation, mais les échecs persistaient sous forte pression mémoire parce que pm_restrict_gfp_mask() désactivait déjà le swap avant dpm_prepare()
    • amdgpu_ttm_evict_resources() pouvait encore échouer faute de mémoire contiguë
    • Même si toute la VRAM tenait en RAM, un OOM pouvait survenir pendant l’endormissement ou le réveil s’il ne restait pas assez de marge pour les allocations ultérieures du pilote

Un autre crash amdgpu identifié avec Ghidra

  • Pendant les tests, une erreur BUG: unable to handle page fault for address: fffffffffffffffc est apparue, ressemblant à un déréférencement de pointeur presque nul
  • Le log de crash pointait vers dm_resume+0x200, mais sans numéro de ligne dans le code source
  • Après avoir sauvegardé et extrait le module noyau amdgpu.ko, Ghidra a été utilisé pour le décompiler et faire correspondre l’emplacement du crash dans dm_resume avec les lignes du code source du noyau
  • Le problème se produisait dans la macro for_each_new_crtc_in_state(dm->cached_state, crtc, new_crtc_state, i)
    • dm->cached_state n’était pas un pointeur valide mais fffffffffffffff4
    • La lecture du champ [RSI + 0x8] provoquait ensuite une page fault à l’adresse fffffffffffffffc
  • La cause venait du fait que dm_suspend() stockait directement dans un pointeur la valeur de retour de drm_atomic_helper_suspend()
    • drm_atomic_helper_suspend() peut renvoyer soit un pointeur valide, soit ERR_PTR(err)
    • En cas d’OOM, -ENOMEM (-12) avait été renvoyé, puis le code de suspension amdgpu l’avait déréférencé comme s’il s’agissait d’un pointeur valide
  • Mario a corrigé ce problème en ajoutant un test sur la valeur de retour d’échec et en interrompant la suspension dans ce cas

Piste abandonnée : autoriser le swap pendant prepare()

  • Si les échecs de veille persistaient sous forte utilisation de RAM, c’est parce qu’amdgpu sauvegardait bien la VRAM dans dpm_prepare(), mais que pm_restrict_gfp_mask() y avait déjà désactivé le swap disque
  • Une tentative a consisté à autoriser le swap pendant dpm_prepare(), puis à ne le désactiver qu’au moment où dpm_suspend() s’apprête à couper les disques
  • Pour cela, un essai a déplacé l’appel à pm_restrict_gfp_mask() depuis enter_state() vers l’intérieur de dpm_suspend_start(), plus en profondeur dans le flux
  • Les contraintes pratiques étaient importantes
    • pm_restrict_gfp_mask() est déclaré dans kernel/power/power.h et appelé depuis kernel/power/suspend.c
    • L’endroit visé pour le nouvel appel était drivers/base/power/main.c, un fichier qui n’inclut normalement pas les en-têtes de kernel/power/
    • Un hack temporaire a consisté à ajouter #include <../kernel/power/power.h>, mais une telle structure aurait été difficile à faire accepter en upstream
  • Il y avait aussi un problème de justesse avec la veille hybride
    • La veille hybride enregistre une image du système, appelle pm_restrict_gfp_mask(), puis invoque suspend_devices_and_enter() alors que le swap est déjà désactivé
    • Réappeler la même fonction déclenchait un avertissement, et pm_restore_gfp_mask() pouvait ensuite ne pas réactiver correctement le swap
  • Les tests ont bien réduit la fréquence des échecs ou des crashs, sans les éliminer complètement, et comme cela touchait fragiquement le cœur de la gestion d’alimentation, aucune tentative upstream n’a été faite

Contournement en espace utilisateur : amdgpu-sleep

  • En 2024-10, après avoir quitté SuperTuxKart puis mis la machine en veille, le réveil s’est soldé par un écran noir
    • D’après les logs, la première tentative de veille avait échoué par OOM dans dpm_prepare(), puis la tentative suivante s’était terminée par un crash d’allocation mémoire d’amdgpu dans bw_calcs() pendant le réveil
  • Une solution a été inspirée du mécanisme de sauvegarde de VRAM de NVIDIA en espace utilisateur
    • NVIDIA utilise un service exécuté avant et après l’appel de systemd à la veille noyau, qui écrit dans /proc/driver/nvidia/suspend pour sauvegarder et restaurer la VRAM
  • À partir de là, le paquet Arch Linux amdgpu-sleep a été créé
    • Avant la veille, il lit /sys/kernel/debug/dri/1/amdgpu_evict_vram
    • Ce point d’entrée debug demande à amdgpu de stocker toute la VRAM dans la RAM système
    • systemd attend la fin de l’éviction de la VRAM du GPU avant de lancer la veille noyau
  • Lors de la mise en veille du desktop, cela permettait de copier rapidement la VRAM en mémoire puis, si nécessaire, de repousser de la RAM vers le swap pour réussir l’opération
  • En revanche, quand plusieurs applis 3D tournaient, elles continuaient à rendre des frames et à recharger la VRAM vers le GPU, ce qui provoquait un livelock de tir à la corde avec amdgpu_evict_vram
    • Cet état pouvait durer plus de 70 secondes avant que amdgpu_evict_vram n’abandonne
    • systemd lançait alors la veille noyau et, une fois l’espace utilisateur figé, l’éviction de VRAM réussissait au niveau noyau
  • Ce script a continué à être utilisé, car la fréquence de ces livelocks n’était pas inférieure à celle des crashs noyau observés quand le script était désactivé

Patch final : notifier de gestion d’alimentation

  • En 2024-11, Mario a demandé de tester un patch permettant l’éviction tant que le swap restait actif
  • Le patch reposait sur un appel à register_pm_notifier() et sur l’API de notifier de gestion d’alimentation de Linux
  • Le callback recevait les messages PM_HIBERNATION_PREPARE et PM_SUSPEND_PREPARE, puis appelait amdgpu_device_evict_resources()
  • PM_SUSPEND_PREPARE est émis dans enter_state() → suspend_prepare() via pm_notifier_call_chain_robust(PM_SUSPEND_PREPARE, PM_POST_SUSPEND)
    • PM_SUSPEND_PREPARE est transmis aux pilotes qui ont enregistré un callback notifier
    • En cas d’échec, PM_POST_SUSPEND est envoyé aux pilotes déjà préparés et la veille est interrompue
  • En évacuant la VRAM à cet endroit, pm_restrict_gfp_mask() n’a pas encore désactivé le swap, et les disques ne sont pas encore figés
  • Le flux corrigé devient donc
    • suspend_prepare()
    • PM_SUSPEND_PREPARE
    • amdgpu_device_pm_notifier() → amdgpu_device_evict_resources()
    • pm_restrict_gfp_mask()
    • dpm_prepare()
    • dpm_suspend()
  • Après compilation d’un noyau personnalisé intégrant le pilote amdgpu modifié, les tests ont montré qu’aucune erreur ne survenait malgré de multiples mises en veille avec une forte utilisation de RAM et de VRAM
  • Un effet secondaire est toutefois apparu : amdgpu sauvegardait la VRAM avant que PipeWire ou le noyau n’aient coupé les haut-parleurs, ce qui pouvait faire boucler l’audio pendant quelques secondes
  • Après plusieurs revues de code, le changement a été fusionné dans l’arbre amdgpu, marquant enfin une vraie résolution du bug après plus d’un an d’essais

Mise à jour 2025-06 et annulation

  • Au départ, il était prévu que ce changement soit intégré au noyau Linux stable 6.14, mais il a ensuite été annulé à cause d’un deadlock possible
  • Le nouveau problème se produit quand systemd appelle la mise en veille système sans d’abord figer tous les processus utilisateurs
    • Le noyau essaie alors d’évacuer la VRAM vers la RAM système avant d’avoir lui-même figé les processus
    • En parallèle, si un programme 3D recharge la VRAM vers le GPU, le processus d’éviction de la veille peut se retrouver bloqué en deadlock
  • Cela ressemble au livelock déjà rencontré avec le contournement utilisateur amdgpu_evict_vram
  • Le mainteneur Linux PM a proposé de déplacer l’appel à pm_restrict_gfp_mask() à l’intérieur de suspend_devices_and_enter()
    • Cette idée rejoint la direction déjà expérimentée consistant à autoriser le swap pendant prepare()
  • Il n’est pas prévu de l’implémenter ni de la soumettre directement
    • Le GPU AMD a été déplacé vers une ancienne machine plus lente avec 8 Go de mémoire, et il n’est plus vraiment envisageable d’y lancer des compilations noyau
  • Le PC principal a été mis à niveau vers un Intel Arc B570, mais le même type de problème s’y produit aussi avec 10 Go de VRAM
    • Le bug correspondant a été signalé dans le bug tracker noyau drm/xe

1 commentaires

 
GN⁺ 2025-02-18
Commentaires Hacker News
  • L’hypothèse selon laquelle, quand un ordinateur de bureau passe en veille S3, l’alimentation du GPU PCIe est coupée n’est pas certaine
    S3 est bien censé couper toute l’alimentation sauf celle de la RAM, mais par exemple les cartes mères Gigabyte Aorus sont tristement célèbres pour un bug de veille des SSD NVMe qui empêche le système de s’endormir ou de se réveiller correctement
    On peut généralement contourner le problème avec une règle udev qui empêche le réveil de tous les ports PCIe : ACTION=="offline", SUBSYSTEM=="pci", DRIVER=="pcieport", ATTR{power/wakeup}="disabled"
    Plus finement, on peut ne cibler que le port PCIe problématique, par exemple avec ATTR{vendor}=="0x8086", ATTR{device}=="0x43bc", et trouver la cause via /proc/acpi/wakeup, /sys/class/pci_bus/*/*/yourWakeupDevicePci/uevent | grep PCI_ID, udevadm info --attribute-walk /dev/whatever
    Au lieu d’udev, on peut aussi basculer /proc/acpi/wakeup depuis un service systemd ou un script d’automatisation, mais c’est moins fiable, et ces problèmes de veille sous Linux sont vraiment usants

    • Sur ma carte mère, j’ai dû mettre ACTION=="add", KERNELS=="0000:00:01.1", ATTR{power/wakeup}="disabled" dans /etc/udev/rules.d/ pour empêcher les réveils spontanés
      Le récepteur Logitech Bolt réveille aussi instantanément plusieurs machines Linux, alors que ce n’est pas le cas sous Windows, et je ne sais pas trop s’il faudrait un analyseur logique ou un outil comme Glasgow pour essayer de capturer l’USB
      À titre provisoire, j’ai ajouté la règle ACTION=="add", SUBSYSTEM=="usb", DRIVERS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c548", ATTR{power/wakeup}="disabled" pour le bloquer
    • J’ai l’impression d’avoir gaspillé quelques kWh à cause de ce problème sur une carte mère Aorus, donc j’espérais que cette solution marcherait, mais dans mon cas elle n’a eu aucun effet
    • J’avais aussi des problèmes de veille sur une X570 Aorus Master ; les exécuter echo GPP0 >> /proc/acpi/wakeup dans une unité systemd au démarrage les a résolus
      Cela dit, après le démarrage, la première mise en veille réveillait toujours immédiatement la machine, mais l’application de la règle udev ci-dessus semble avoir réglé ce problème aussi
    • On en vient à espérer que le matériel puisse détecter s’il s’est réellement endormi, ou que réveiller à nouveau du matériel qui ne s’était pas endormi ne pose pas de problème
      On devrait pouvoir envoyer une commande de veille à un périphérique PCIe, puis mettre le bus lui-même en veille, et au réveil réactiver d’abord le bus avant de réveiller le périphérique
    • J’ai lutté un bon moment avec ce problème, mais cette méthode n’a pas fonctionné non plus ; j’ai résumé ce que j’ai trouvé ici : https://bbs.archlinux.org/viewtopic.php?id=302440
      Dans mon cas, la cause du réveil semble venir de .../devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:45/wakeup/wakeup6, mais je ne comprends pas bien ce que signifie ce chemin
  • En tant qu’auteur de memreserver, l’un des contournements en espace utilisateur mentionnés, j’ai débogué ce problème il y a quelques années
    Le commentaire public que je retrouve rapidement est https://gitlab.freedesktop.org/drm/amd/-/issues/2125#note_17..., et il me semble qu’il y avait aussi eu une discussion sur une mailing list
    Le point essentiel était que Linux ne disposait pas de hooks de suspension par étapes s’exécutant de façon fiable avant le gel du disque et d’une partie du sous-système mémoire ; cela semble désormais possible
    Malheureusement, le GitLab de Freedesktop semble mal indexé, et cette connaissance paraît donc avoir été enterrée

  • Un travail vraiment excellent.
    Si vous vous demandiez pourquoi il est si difficile de faire fonctionner correctement la mise en veille sous Linux, et tout aussi difficile de la déboguer, cet article montre à lui seul combien de points peuvent casser.
    Encore aujourd’hui, sur mon ThinkPad P1G4, le ventilateur ne s’éteint pas automatiquement avant la mise en veille si je ne l’éteins pas manuellement, et récemment, après une sortie de veille, j’ai eu du bruit dans mon casque Bluetooth, au point de devoir aussi désactiver la mise en veille des nœuds PipeWire : https://wiki.archlinux.org/title/PipeWire#Noticeable_audio_d...

    • On est en 2025 et c’est étonnant que le sleep/suspend des portables Linux ne fonctionne toujours pas correctement.
      La première fois que j’ai rencontré ce genre de problème remonte probablement à une quinzaine d’années.
    • La mise en veille, c’est vraiment la loterie, et les erreurs comme celles décrites dans l’article sont très difficiles à déboguer.
      Parmi les contournements proposés pour divers problèmes, certains consistent à désactiver les modes d’économie d’énergie ; or l’intérêt de la mise en veille est généralement d’augmenter l’autonomie sur batterie, donc ce genre d’approche n’est pas très réaliste en pratique, car elle peut réduire fortement le temps d’utilisation réel.
      Cela dit, faire fonctionner la mise en veille S0ix n’est pas impossible.
      J’ai installé Arch Linux sur des appareils portables à base d’AMD 7840U et d’AMD 8840U, à savoir les GPD Win Max 2, GPD Win Mini, GPD Win 4, Minisforum V3 et OneXPlayer X1 Ryzen, et il semble peu probable que ces sociétés les aient conçus ou testés en pensant à la prise en charge de Linux.
      Pourtant, avec seulement quelques ajustements des fausses sources de réveil dans /proc/acpi/wakeup et /sys/devices/*/*/*/power/wakeup, j’ai obtenu une prise en charge S0ix presque parfaite, à l’exception du tout dernier OneXPlayer X1 Ryzen.
      La prise en charge par le noyau Linux standard est également excellente : l’écran tactile, le stylet, le Wi-Fi et le Bluetooth fonctionnent bien, et le seul manque que j’aie vu concerne la prise en charge du lecteur d’empreintes digitales.
      Ces petits fabricants font moins de personnalisation extrême des composants et d’intégration ultra-serrée, ce qui se voit concrètement dans des appareils plus épais de quelques millimètres.
      Ils finissent donc par choisir des composants plus conservateurs, et c’est peut-être pour cela que la prise en charge de Linux y est étonnamment bonne.
    • Pour qu’un utilisateur final puisse profiter facilement d’une bonne mise en veille, la bonne réponse est d’acheter du matériel compatible validé.
      D’après mon expérience, cela fait longtemps que c’est très stable sur les ThinkPad professionnels, et les utilisateurs Windows du même modèle semblent même rencontrer plus souvent des problèmes de mise en veille.
  • Personnellement, je suis vraiment reconnaissant.
    Mon portable principal est un ThinkPad à base de Ryzen sous Linux, et j’utilise souvent la mise en veille et l’hibernation ; je rencontre ce problème par intermittence depuis un moment.
    J’attends Linux 6.14 avec impatience.

  • La raison pour laquelle dm->cached_state a stocké -12 au lieu d’un pointeur est très probablement que, pendant le suspend, dm_suspend() a directement affecté dm.cached_state = drm_atomic_helper_suspend(adev_to_drm(adev)).
    La fonction appelée drm_atomic_helper_suspend() peut retourner soit un pointeur valide, soit un ERR_PTR(err) qui encode une erreur sous forme de pointeur négatif ; l’appelant n’a pas vérifié l’erreur, l’a mis directement dans le pointeur, puis l’a déréférencé au resume.
    Voilà une raison de plus d’introduire Rust dans le noyau : si le traitement du type Result est imposé, ce genre de chose devient beaucoup moins probable.

    • On peut aussi créer des types sommes algébriques avec le préprocesseur C : https://github.com/Hirrolot/datatype99
      Mais les valeurs par défaut comptent, et l’historique du noyau, qui a longtemps repoussé la modernisation des pratiques de codage, joue en défaveur des améliorations côté C.
      Ironiquement, cette même résistance frustre aussi les développeurs Rust, car même remettre en ordre chaque sous-système ou documenter son fonctionnement est mal accepté.
      Quelque chose comme https://github.com/llvm/llvm-project/issues/74205 pourrait aider si cela descend jusqu’au noyau, mais je pense qu’ils continueront malgré tout à choisir la surcharge manuelle de pointeurs plutôt que la sûreté garantie par les types.
  • Comme j’utilise un double démarrage Linux/Windows sur un portable Framework AMD avec le module d’extension GPU, ce travail devrait m’être utile.
    J’aimerais contribuer directement ou faire un don à une association de votre choix ; mes coordonnées sont dans mon profil.

  • Je pensais que les deux plus grands problèmes de l’informatique étaient le nommage, l’invalidation de cache et les erreurs off-by-one, mais maintenant que je connais les problèmes de sleep/wake, ça me semble NP-complet.

    • Je vois le sleep/wake comme un sous-ensemble de l’invalidation de cache.
      Si tous les périphériques n’avaient pas d’état, ce ne serait probablement pas un problème.
    • Seulement sous Linux ; sous Windows c’est O(n²), sous macOS c’est O(log n).
  • Sous Linux, la gestion de la mémoire, et en particulier les situations d’OOM, reste un cauchemar incroyablement pénible
    Je ne rencontre pas ce genre de problème en permanence, mais il m’est clairement déjà arrivé d’échouer en essayant de déboguer un problème similaire, et au final, quand il y a un OOM, on finit généralement par ajouter de la RAM
    C’est du gaspillage et c’est coûteux, mais gérer élégamment les situations d’OOM semble rester un problème difficile à résoudre pour Linux
    Ce travail est excellent, et servira de référence pour déboguer des problèmes similaires à l’avenir
    La fonctionnalité debug-shell de systemd est aussi une bonne surprise, je ne savais pas qu’elle existait
    Cela dit, ma carte X670E Steel Legend ne semble pas avoir de connecteur série, et je me demande comment fonctionnent les ports série intégrés de nos jours
    Sont-ils connectés aux lignes PCIe du chipset ?
    Quand on se plonge dans le noyau Linux, les enregistrements de présentations sur les sous-systèmes du noyau lors d’événements comme FOSDEM ou la Linux Plumbers Conference sont très utiles ; par exemple, la vidéo sur le sous-système mémoire TTM, utilisé par la plupart des pilotes DRM de GPU de bureau, est ici : https://www.youtube.com/watch?v=MG7_tUNKSt0

    • Sous Windows, le port série de ma carte mère apparaît comme connecté à Pci Bus → PCI standard ISA bridge
      Vive DOS
      Je regarderai la vidéo sur TTM quand j’aurai le temps
    • Contenir l’OOM avec des cgroups a plutôt bien fonctionné
      Je ne sais pas vraiment s’il existe des approches modernes de gestion de l’OOM meilleures que ce que fait Linux, et s’il y a des ressources à lire à ce sujet, ça m’intéresse
    • Oui, même en étant gentil, c’est épouvantable
      Linux ne gère pas correctement les situations d’OOM
      Je sais qu’on peut mettre des garde-fous avec les cgroups, installer earlyoom, augmenter le swap ou utiliser zram
      Mais au final, tout cela reste des hacks sales qui peuvent parfois sauver la mise, sans corriger la façon dont ces situations sont traitées
      J’aimerais qu’on arrête de présenter ça comme des solutions
      J’ai vu le noyau échouer à allouer de la mémoire dans dm_crypt, ce qui a fait qu’un volume LUKS s’est monté lui-même en lecture seule ; franchement, il suffit de tuer un processus en espace utilisateur
      L’état actuel est tout simplement inacceptable, et les excuses me fatiguent
    • Je me demande si tu as essayé zswap/zram
      Avec zstd, on peut utiliser 8 Go de RAM comme 20 Go de « RAM » sans trop de problèmes, ou 16 Go comme 40 Go
      On peut même être plus agressif et surcommitter la mémoire au-delà de 100 %, et comme Android fait aussi ça, c’est une approche assez stable
  • Bonne nouvelle
    Le pilote graphique Linux d’AMD a globalement bien fonctionné, mais ce problème était l’exception que j’ai rencontrée plusieurs fois

    • J’ai eu un peu moins de chance
      Le problème que je rencontre récemment, c’est qu’après la sortie de veille, le pilote continue d’écrire dans les logs WARNING: CPU: 12 PID: 11871 at drivers/gpu/drm/amd/amdgpu/../display/dc/dc_helper.c:100 generic_reg_update_ex+0x1d2/0x290 [amdgpu], puis "[drm] scheduler comp_1.0.n is not ready, skipping"
      https://gitlab.freedesktop.org/drm/amd/-/issues/3911
    • Moi aussi, mon expérience est globalement bonne, mais un problème similaire se produit si je débranche le Thunderbolt auquel est connecté l’écran pendant que la machine est en veille
      Cela dit, comme c’est un portable, la configuration du pilote est très différente et il n’y a pas non plus de GPU PCIe
  • Le passage où il sauvegarde et extrait le module noyau amdgpu.ko, le décompile avec Ghidra, puis fait correspondre l’emplacement du crash dans dm_resume à la ligne correspondante du code source du noyau est toujours mon moment préféré dans le débogage