# Interruptions - Ordonnancement - partie 1 : [interruptions](interruptions.md) - partie 2 : [Ordonnamcement](ordonnancement.md) #### Ex1 : Linux fournit les compteurs d'interruptions dans : ```bash cat /proc/interrupts ``` Exécutez : ```bash cat /proc/interrupts ``` Vous devriez obtenir un tableau comportant notamment une colonne par CPU. Pour connaître le nombre de processeurs logiques : ```bash nproc ``` Vous pouvez également utiliser : ```bash lscpu ``` 1. Combien de processeurs logiques possède votre machine ? 2. Combien de colonnes correspondant aux CPU observez-vous dans `/proc/interrupts` ? 3. À quoi correspond chaque ligne du tableau ? 4. Pourquoi les compteurs sont-ils différents selon les CPU ? #### Ex2 Une interruption matérielle peut être générée lorsqu'un périphérique demande l'attention du processeur. Sur un PC traditionnel, le clavier est associé à l'IRQ 1. Recherchez les informations relatives au clavier : ```bash grep -i keyboard /proc/interrupts ``` Vous pouvez également rechercher le contrôleur `i8042` : ```bash grep i8042 /proc/interrupts ``` Sur de nombreuses machines, vous observerez une ligne semblable à : ```text 1: ... IR-IO-APIC 1-edge i8042 ``` Le numéro `1` est le numéro d'IRQ. Le suffixe : ```text 1-edge ``` indique que cette interruption est configurée en mode déclenché sur front (*edge-triggered*). Dans un terminal, lancez : ```bash watch -n 1 'grep "^ *1:" /proc/interrupts' ``` Puis appuyez plusieurs fois sur des touches. 1. Le compteur de l'IRQ 1 augmente-t-il lorsque vous utilisez le clavier ? 2. Sur quel CPU le compteur augmente-t-il ? 3. Pourquoi le clavier n'a-t-il pas besoin d'être interrogé en permanence par le processeur ? 4. Quelle différence faites-vous entre : - une interruption ; - une interrogation périodique (*polling*) ? #### Ex3 Linux permet de contrôler les processeurs auxquels une IRQ peut être distribuée. Pour l'IRQ 1 : ```bash cat /proc/irq/1/smp_affinity ``` Vous pouvez également utiliser : ```bash cat /proc/irq/1/effective_affinity ``` et : ```bash cat /proc/irq/1/effective_affinity_list ``` 1. Quel est le masque d'affinité pour l'IRQ 1 sur votre machine ? 2. Quel(s) CPU(s) est(sont) séléctionné(s) pour la gérer ? 3. Y-a-t-il un interêt à la gérer toujours sur le même cpu ? #### Ex4 Sur une machine multicœur, un processeur peut avoir besoin de demander une action à un autre processeur. Linux utilise alors des **IPI** (*Inter-Processor Interrupts*). Examinez : ```bash cat /proc/interrupts ``` Recherchez notamment les lignes : ```text LOC RES CAL TLB ``` Les significations importantes sont : - `LOC` : interruptions du timer local ; - `RES` : demandes de réordonnancement ; - `CAL` : appels de fonctions entre CPU ; - `TLB` : invalidations de TLB entre CPU. ##### `LOC` : timer local `LOC` correspond aux interruptions du timer local de chaque CPU. Elles permettent notamment au noyau d'effectuer certaines opérations liées : - à la gestion du temps ; - à la comptabilisation du temps CPU ; - à l'ordonnancement. 1. Pourquoi chaque CPU possède-t-il son propre compteur `LOC` ? ##### `RES` : rescheduling Une ligne `RES` correspond à des demandes de réordonnancement transmises entre CPU. Par exemple, un CPU peut devoir signaler à un autre CPU qu'il doit réévaluer le processus actuellement exécuté. 1. Pourquoi un CPU peut-il avoir besoin de demander à un autre CPU de réévaluer son ordonnancement ? ##### `TLB` — TLB shootdown Le TLB (*Translation Lookaside Buffer*) contient des traductions récentes : ```text adresse virtuelle → adresse physique ``` Supposons qu'un CPU modifie les tables de pages d'un processus. Un autre CPU peut encore posséder dans son TLB une ancienne traduction. Linux doit alors demander à ce CPU d'invalider l'entrée correspondante. Il peut utiliser une IPI. Le mécanisme est souvent appelé : > **TLB shootdown** 1. Pourquoi une modification des tables de pages peut-elle nécessiter une action sur un autre CPU ? 2. Pourquoi le TLB doit-il être invalidé ? 3. Une IPI TLB provient-elle d'un périphérique matériel externe ? #### Ex4 Pour déclencher l’exception `Illegal instruction` , il faut exécuter du code invalide pour le processeur employé. C’est difficile avec les architectures actuelles car les pages de code sont verrouillées en lecture seule (donc impossible de modifier des fonctions existantes) et les pages de données ne sont pas exécutables (donc impossible d’y dérouter l’exécution). La solution consiste à générer un code assembleur invalide et à l’insérer manuellement dans un programme C, comme c’est fait dans le fichier illegal.c (les instructions sont invalides pour un processeur x86, il faudra peut-être changer les valeurs si on le teste sur une autre architecture). 1. Observez l'effet avec ```bash strace ./illegal ``` Comment l'exception s'est traduite au niveau du processus fautif ?