wiki:rpc_implementation

Version 2 (modified by alain, 8 years ago) (diff)

--

Communication par RPC

Les différentes instances du noyau communiquent entre elles sur le modèle client/serveur au moyen de RPCs (Remote Procédure Call. Cette section décrit le mécanisme RPC implémenté dans ALMOS-MK.

Le code et les différentes structures de données utilisés pour les RPC sont définis dans les fichiers rpc.c et rpc.h. Ce code utilise une bibliothèque de fonctions d'accès à une FIFO logicielle définie dans les fichiers remote_fifo.c et remote_fifo.h. Les macros permettant la manipulation des pointeurs étendus sont définies dans le fichier type.h.

Rappelons que l'architecture cible est décrite dans le fichier arch_info. Cette architecture est généralement clusterisée, et un cluster possède deux index:

  • CID est un index codé sur 32 bits. Il permet d'indexer de façon continue, de 0 à N-1, l'ensemble des clusters de l'architecture cible, définis dans le fichier arch_info. Chaque peut contenir un nombre quelconque de CPUs (y compris 0), un nombre quelconque de périphériques, et un banc mémoire physique de longueur quelconque (y compris 0). Il n'existe une instance du noyau que dans les clusters contenant au moins un CPU, un contrôleur d'interruptions, et un banc mémoire physique, ce qui n'est pas le cas de tous les clusters.
  • CXY est un index codé sur 32 bits. Il représente l'extension d'adresse physique qu'il faut concaténer aux 32 bis de l'adresse locale pour accéder à la mémoire ou aux périphériques contenus dans un cluster. Dans le cas particulier de l'architecture TSAR, cet index CXY possède un format fixe qui permet d'extraire les coordonnées (X,Y) du cluster dans le mes 2D, mais ceci n'est pas vrai pour toutes les architectures visées par ALMOS. Je pense que cet index devrait lui aussi être explicitement défini, dans le fichier arch_info.

1) Point d'accès unique dans chaque cluster

Rappelons que toutes les variables globales définies dans le segment KDATA du noyau sont répliquées dans tous les clusters. On fait - pour l'instant - l'hypothèse que deux variables de même nom peuvent avoir des valeurs différentes dans deux clusters différents, mais qu'elles sont rangées à des adresses locales (adresses 32 bits) identiques.

N'importe quel thread client s'exécutant sur n'importe quel CPU de n'importe quel cluster peut envoyer une RPC vers n'importe quel cluster serveur. Le serveur est identifié par son index CXY. Il existe donc dans chaque cluster une RPC_FIFO logicielle possédant à priori N écrivains et M lecteurs. N est le nombre de thread clients, M est le nombre de thread serveurs.

  • Pour synchroniser les accès concurrents entre écrivains, la RPC_FIFO imlémente un mécanisme de ticket garantissant que les clients pourront stocker leurs requêtes dans l'ordre d'attribution des tickets.
  • pour synchroniser les accès concurrents entre lecteurs, ALMOS-MK implémente un light-lock, qui est un verrou non bloquant enregistrant l'identité du premier lecteur qui obtient le verrou.

2) Traitement parallèle des RPCs

Les threads chargé de traiter les RPCs appartiennent à un pool de thread spécialisés appelés RPC_THREAD. Un RPC_THREAD est activé sur un des CPUs du cluster serveur chaque fois que le noyau détecte que la FIFO est non-vide. Un RPC_THREAD s'exécute avec la priorité la plus élevée et se charge de traiter toutes les requêtes RPC présentes dans la RPC_FIFO avant de rendre le verrou. Si un RPC_THREAD doit s'endormir pour attendre la disponibilité d'une ressource, il libère le verrou pour permettre le traitement d'autres RPCs.

3) Format d'une RPC

Il existe différents types de RPC :

  • Une RPC simple bloquante est envoyée à un seul serveur, et attend une seule réponse.
  • Une RPC broadcast bloquante est envoyée à N serveurs, et attend N réponses.
  • Une RPC simple non bloquante est envoyée à un seul serveur et n'attend pas de réponse.
  • Une RPC broadcast non bloquante est envoyée à N serveurs et n'attend pas de réponse.

Chaque case d'une RPC_FIFO contient un pointeur étendu (xptr_t) sur un descripteur de RPC (rpc_desc_t), qui est toujours stocké dans la mémoire du cluster client. Un descripteur de RPC possède un format fixe comportant les informations suivantes:

  • Le champs index définit le type de service demandé (de façon similaire à un index d'appel système).
  • Le champs response est un entier qui défini le nombre de réponses attendues.
  • Le champs args est un tableau de 32 uint32_t contenant les arguments d'entrée et de sortie.

L'utilisation et l'interprétation du tableau args dépend de chaque type de RPC.

4) Introduction d'une nouvelle RPC

L'introduction d'un nouveau service nécessite de modifier le code de ALMOS-MK de la façon suivante opérations suivantes.

  • Il doit exister une fonction système my_kernel_service() possédant un nombre quelconque (inférieur à 32) de paramètres d'entrée ou de sortie.
  • La nouvelle doit être enregistrée dans l'enum rpc_index_t (fichier rpc.h) et dans le tableau rpc_exec[] (fichier rpc.c).
  • Il faut écrire explicitement la fonction de marshaling rpc_my_kernel_service_client() qui est exécutée du côté client pour (1) enregistrer les arguments d'entrée dans le descripteur de RPC, (2) poster la RPC dans la RPC_FIFO, (3) récupérer les arguments de sortie dans le descripteur de RPC.
  • Il faut écrire explicitement a fonction de marshaling rpc_my_kernel_service_server() qui est exécutée du côté serveur pour (1) récupérer les arguments d'entrée dans le descripteur de RPC, (2) appeler la fonction my_kernel_service(), (3) écrire les arguments de sortie dans le descripteur de RPC.