• [^] # Re: OS de base

    Posté par . En réponse à la dépêche Firewall toujours en fonction sur un Linux arrêté!. Évalué à 10.

    La notion de tache n'existe pas non plus à l'intérieur du noyau linux.
    Qu'est-ce pour toi qu'une tâche ?

    Un processus, dans ce cas il est normal que le noyau ne soit pas un processus à part entière car son rôle est justement de gérer les processus (donc qui le gérerait lui si c'en était un).

    Il y a aussi des processus qui résident dans l'espace d'adressage du noyau (au lieu de l'espace d'addressage utilisateur), on appelle ça des threads kernel, je crois que les démons commençant par un k (comme kswapd) sont comme ça.

    Le noyau est réentrant, donc si à un instant donné, plusieurs processus appellent une routine du noyau alors, il y a plusieurs exécutions concurrentes au sein du noyau.

    Celà ne peut arriver que sur une machine SMP puisque sur une machine monoprocesseur un seul processus tourne à chaque instant, simplement à expiration de la tranche de temps (10 ms par exemple), l'ordonanceur commute d'un processus à un autre donnant une impression d'exécution simultanée à l'échelle humaine.

    Le noyau linux standard est non préemptible, ce qui veut dire qu'une boucle "while(1)" dans le noyau ne sera pas interrompue si sa tranche de temps est écoulée par contre elle peut-être interrompue par une interruption matérielle.

    Les problèmes de concurrence sur une machine non-SMP, ne peuvent donc survenir qu'entre une routine traitant une interruption matérielle, et une routine "standard" du noyau.

    Une routine traitant une interruption ne peut elle-même être interrompue par une autre interruption (car les processeurs Intel masquent automatiquement toutes les interruptions lors du traitement de l'une d'entre-elles).

    Or les routines d'interruptions sont généralement très courte, lorsqu'elles doivent faire quelque chose de compliqué, elles enregistrent un callback qui sera appelé plus tard.

    De plus si une routine standard doit modifier une structure de donnée qui est affectée par un handler d'interruption (rare puisque les handler sont très très court), elle peut bloquer les interruptions temporairement avec un CLI().

    Donc, les problèmes de concurrence au niveau du noyau sur une machine non-SMP sont minimes, par contre ce système de callback implique que le noyau soit non-préemptible car lorsque la tranche de temps arrive à expiration, il se déclenche une IRQ timer, dont le handler qui doit rester très court, ne peut lancer directement un autre processus, non il ne peut qu'enregistrer un callback dans une file d'attente pour rappeler qu'il faut appeller le scheduler.

    Or ce callback ne sera exécuté que lorsque quelqu'un ira regarder le contenu de cette fichu file d'attente, une solution serait donc d'aller regarder de temps en temps si elle contient quelque chose. C'est la technique dite des points de préemptions, qui consiste à insérer un peu partout dans le kernel à des points clés des bout de code pour faire cela.

    Une solution serait de dire que toute cette histoire de callback enregistré maintenant, pour être appelé plus tard, c'était pour que les routines du kernel puisse garder continuer de se reposer sur l'assertion "les handler d'interruptions ne modifient pas grand chose donc pas beaucoup (quasiment pas) de problème de concurrence à gérer et quand il y en a (très rarement) on fait un CLI()".

    Or de toute façon, les problèmes de concurrence on est bien obligé de se les taper en mode SMP, et donc les routines de verouillage qui protégent les structure du noyau elles existent mais dans la version SMP.

    Une idée serait donc, je compile mon noyau monoprocesseur en mode SMP et j'appelle la routine de callback tout de suite, juste après avoir réactivé les interruptions dans le handler et avant de faire le return, et j'ai un kernel préemptible.
    Je crois que c'est plus ou moins ça que fait le patch kernel préemptible.

    Donc quand tu dis qu'un while(1) dans le noyau bloque tout, je dirais :
    - sur une machine monoprocesseur avec un kernel standard (SMP ou pas) ou avec des points de préemption : ça bloque la machine
    - en mode SMP sur une machine multiprocesseur, ça bloque un processeur mais les autres tournent normalement
    - avec le patch kernel préemptible, ça fait rien de plus qu'un "while(1)" dans la libc, le processus concerné est bloqué pour toujours et ne pourra plus recevoir de signaux mais tout le reste continue de tourner normalement.