Le Coin Wiki
d'Olivier Dalle
$WikiTagline
 

Prog Systme avance - Sance de TP4

Utilisation de diffrents allocateurs

Dans cet exercice vous devrez repartir d’un pilote comportant une gestion de liste chane que vous avez crit pour l’un des deux TP prcdents.

L’objectif de l’exercice est de modifier le pilote de faon remplacer les appels =kmalloc= et =kfree= par des appels aux nouveaux allocateurs que vous avez vus dans le cours 6. Normalement, vous avez du utiliser les allocations dynamiques pour allouer deux types d’objets :

  • Les structures de chanage
  • Les tampons de stockage de donnes

Partie 0 : terminer une liste chane !

Si vous n’tes pas encore arriv faire fonctionner au moins l’un des pilotes comportant une gestion de liste chane dans les TP prcdents, alors prenez le temps de la faire maintenant, ne vous lancez pas immdiatement dans la suite de cet exercice ! (Pour la suite de cet exercice vous devez travailler sur un pilote que *vous* avez crit vous-mme.

Partie 1 : Utilisation du Slab Allocator

Comme les structures de chanage sont toujours de la mme taille, vous utiliserez le Slab Allocator de faon crer un cache de ces structures.

Une fois que vous aurez termin, testez cette version intermdiaire de votre pilote. Utilisez en particulier le fichier /proc/slabinfo pour contrler l’tat de vos allocations. Pensez en particulier librer le contenu du cache et la dtruire avant d’autoriser le dchargement du module.

Partie 2 : Utilisation du Buddy Allocator

Il s’agit maintenant de remplacer la mthode d’allocation des tampons de stockage de donnes. Pour cela vous allez directement utiliser le Buddy Allocator pour allouer des pages. Attention cependant : le BA vous retourne des pages compltes, et il faut faire attention ne pas les gaspiller (cad viter la fragmentation interne) :

  • Si vous avez besoin de stocker 10 octets dans premier temps, puis 20 octets la fois suivante, il n’est pas question d’allouer deux pages.
  • Vous devrez d’abord finir de remplir compltement une page avant d’en rclamer une autre.

Vous devrez de plus trouver un moyen de grer correctement la libration de ces pages. Comme il y a de grandes chances que vous ayez utilis chaque page pour stocker les donnes de plusieurs critures successives (par exemple 10 puis 20 octets), alors vous ne devrez librer cette page (la rendre au systme) que lorsque tout ce que vous y avez mis aura disparu de la FIFO. Plusieurs solutions existent pour cela. Vous pouvez par exemple choisir d’utiliser les premiers octets de chaque page pour stocker un compteur d’utilisations de la page, qui augmente chaque fois que vous ajoutez un objet dans la page, et diminue chaque fois que vous en retirez un. Pour retrouver l’adresse de dbut d’une page, souvenez-vous que les pages ont une taille fixe : pour une adresse quelconque donne, le dbut de la page s’obtient par un simple calcul de modulo. Ou par des oprations arithmtiques binaires puisque la taille d’une page est une puissance de 2.

Enfin, rflchissez aussi aux cas particuliers suivants :

  • “Grosses” critures : si une criture dans la FIFO est demande pour une quantit suprieure la taille d’une page
  • Ecritures cheval sur deux pages

Souvenez-vous que votre pilote est libre de n’crire que la quantit qu’il souhaite et pas forcment celle demande. Ca peut simplifier pas mal les choses…

Testez soigneusement votre pilote, et en particulier avec de grosses critures et ou en remplissant la FIFO avec une quantit de donnes suprieure la taille d’une page (constante PAGE_SIZE )

FIFO Synchrone (a finir pour la prochaine fois)

L’objectif de l’exercice est d’crire un pilote pour un pseudo-priphrique caractre qui implmente un FIFO synchrone, autrement dit fonctionnant selon le principe du producteur/consommateur, sans bufferisation.

Voici de faon pus prcise les spcifications de cette nouvelle FIFO :

  • Il faut que 2 processus soient en mme temps en train de faire une lecture et une criture pour que le transfert des donnes puisse fonctionner.
  • Comme il n’est pas possible de faire en sorte que deux processus lancent ces deux oprations exactement au mme moment, il faut les synchroniser: le processus qui dclenche son opration de lecture ou criture le premier doit tre endormi en attendant qu’un second processus ralise l’opration inverse.
  • Lorsque le second processus ralise l’opration inverse, il doit rveiller le premier, qui tait endormi en l’attendant.
  • Pour endormir un processus, vous utiliserez le mcanisme des wait_queue qui vous t prsent en cours.
  • Vous choisirez un mode d’endormissement interruptible :
    • Attention, cela signifie que lorsque le processus se rveille deux situations sont possibles :
      • Soit le processus est rveill normalement par le second processus qui vient d’arriver
      • Soit le processus est rveill cause d’une interruption. Dans ce cas, son appel doit se terminer avec une erreur =-EINTR=.
  • Transfert des donnes :
    • Il y a quand mme besoin de bufferiser temporairement les donnes:
      1. Les donnes doivent tre recopies depuis l’espace mmoire du processus crivain vers une zone mmoire tampon du noyau
      2. Les donnes doivent tre recopies depuis la zone mmoire tampon vers l’espace mmoire du processus lecteur.
    • Pour simplifier le protocole de synchronisation, vous ferez en sorte que si le processus crivain est le premier raliser son opration, alors il n’attend pas l’arrive du lecteur pour copier les donnes dans la zone tampon. en revanche, il doit forcment attendre l’arrive du lecteur (autrement dit s’endormir) une fois qu’il a termin le transfert vers la zone tampon.
    • Le transfert ne retournera au lecteur que le minimum entre la quantit de donnes lues et la quantit de donnes crites
  • Attention ne pas vous tromper de processus : si ce sont deux lecteurs qui arrivent au rendez-vous, alors le second ne doit pas rveiller le premier. Seul un redacteur doit rveiller un lecteur (et vice-versa). Pour simplifier les choses au dbut, vous pouvez interdire une deuxime opration du mme type quand une premire est dj en cours (retourner directement une erreur au second).
  • Tests. Pensez vrifier les diffrents cas de figure:
    • Un lecteur arrive le premier
    • Un rdacteur arrive le premier
    • Le lecteur et le rdacteur ne lisent pas la mme quantit de donnes
    • Deux lecteurs au lieu d’un lecteur puis un rdacteur