Plan 9 : un système d'exploitation qui a marqué mon parcours

Je viens d'avoir 50. Dans ma tête j'en ai 37. Je suis toujours plus curieux et l'avènement de l'IA générative est un sujet qui me passionne.

Mais bon, 50, c'est un chiffre rond et j'ai souhaité revenir sur l'un des défis techniques qui a marqué mon parcours, celui que j'ai rencontré en travaillant sur 9vx, la version de Plan 9 adaptée à Linux. Ce projet, qui a longtemps fasciné les développeurs du logiciel libre, m'a offert l'opportunité de mettre à l'épreuve ma capacité à analyser, à remettre en question des hypothèses et à proposer des solutions concrètes.

Le bug du "double sleep"

Le problème est apparu lorsqu'un processus du noyau, appelé kproc, restait bloqué dans un état de sommeil sans jamais être réveillé. Après plusieurs échanges avec les contributeurs de la communauté, il est devenu clair que l'origine du blocage résidait dans une supposition faite lors de la conception de 9vx : les développeurs partaient du principe qu'un thread sous Linux pouvait être traité comme un simple équivalent d'un processeur simulé, sans tenir compte du fait que le thread pouvait passer d'un coeur à l'autre. Cette simplification fonctionnait dans de nombreux cas, mais elle ne prenait pas en compte le fait que la fonction qui désactive les interruptions locales pouvait être appelée depuis un thread exécuté sur un processeur différent de celui auquel il était initialement rattaché. Le scheduler, en se basant sur cette hypothèse, laissait le kproc endormi indéfiniment.

Pour les curieux, voici le thread original sur comp.os.plan9 : 9vx, kproc and double sleep.

La méthode : GDB, 40 pages et un surligneur

Pour identifier précisément la source du dysfonctionnement, j'ai adopté une approche très méthodique. J'ai d'abord écrit un petit script GDB capable, à chaque arrêt du scheduler, d'afficher les champs pertinents du processus : l'identifiant du processeur, l'état du processus et les drapeaux d'interruption. Le script redirigeait la sortie vers un fichier texte que j'ai ensuite découpé en quarante pages d'environ deux cents lignes chacune. Cette découpe m'a permis de travailler sur le papier, de parcourir les traces ligne par ligne et de mettre en évidence, à l'aide d'un surligneur, les valeurs hexadécimales qui changeaient de manière inattendue. Les numéros qui apparaissaient en jaune correspondaient systématiquement à des identifiants de CPU différents de celui sur lequel le thread était censé s'exécuter. Cette observation a confirmé que le scheduler appelait la fonction d'interruption depuis le mauvais coeur.

La résistance de la communauté

Lorsque j'ai présenté ma proposition de correction à la communauté, j'ai rencontré une certaine résistance. Certains contributeurs ont estimé que la solution n'était pas immédiatement compréhensible et pouvait introduire de nouvelles complexités. Cette réaction, bien que difficile à accepter à l'époque, a été très enrichissante : elle m'a poussé à clarifier davantage mes arguments et à explorer les limites de mon approche.

Au final, la correction que j'ai proposée a été intégrée et, à ma connaissance, n'a jamais été remplacée dans les versions ultérieures de 9vx. Aujourd'hui, 9vx est peu utilisé, mais le fait que ma solution ait suscité le débat parmi des ingénieurs de haut niveau reste pour moi une source de fierté.

La méthode scientifique appliquée au code

Cette expérience illustre bien le principe même de la méthode scientifique. Proposer une hypothèse, la soumettre à la critique et accepter qu'elle puisse être réfutée est au coeur du progrès. Karl Popper rappelait que, pour qu'une théorie soit scientifique, elle doit être falsifiable ; autrement elle ne peut pas être testée. Dans le domaine du développement logiciel, chaque idée doit être mise à l'épreuve, confrontée aux faits et aux avis d'experts. La résistance que j'ai rencontrée n'est donc pas un obstacle, mais une étape naturelle du processus de validation.

En repensant à ce projet, je mesure à quel point chaque défi, même les plus techniques, contribue à enrichir notre compréhension du fonctionnement des systèmes et à renforcer notre capacité à innover.

Et maintenant ?

Atteindre le demi-siècle n'est qu'une invitation à continuer d'explorer, d'apprendre et de partager. Pour moi aujourd'hui, c'est entre autres, l'implémentation d'un moteur d'inférence LLM en Rust et en assembleurs et quelques projets en FPGA.