Changes between Version 1 and Version 2 of rpc_implementation


Ignore:
Timestamp:
Jun 1, 2016, 1:21:30 PM (8 years ago)
Author:
alain
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • rpc_implementation

    v1 v2  
     1= Communication par RPC =
    12
     3[[PageOutline]]
    24
    35Les différentes instances du noyau communiquent entre elles sur le modèle client/serveur au moyen de RPCs (Remote Procédure Call.
    46Cette section décrit le mécanisme RPC implémenté dans ALMOS-MK.
    57
    6 Rappelons qu'un cluster possède deux index:
    7  * CID est un index codé sur 32 bits. Il permet d'indexer de façon continue, de 0 à N-1, l'ensemble des clusters contenant au moins un processeur, c'est à dire l'ensemble des instances du noyau. Cet index est - pour l'instant - défini dans le fichier arch_info. 
     8Le 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. 
     9Ce 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.
     10Les macros permettant la manipulation des pointeurs étendus sont définies dans le fichier type.h.
     11
     12Rappelons 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:
     13 * 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. 
    814 * 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.
    915
     16== 1) Point d'accès unique dans chaque cluster ==
     17
     18Rappelons 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.
     19
    1020N'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
    11 cluster server, identifié par son index CXY.
     21cluster serveur. Le serveur est identifié par son index CXY.
     22Il 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.
     23 * 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.
     24 * 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.
    1225
     26== 2) Traitement parallèle des RPCs ==
    1327
     28Les 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
     29avant 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.
    1430
     31== 3) Format d'une RPC ==
     32
     33Il existe différents types de RPC :
     34 * Une RPC ''simple bloquante'' est envoyée à un seul serveur, et attend une seule réponse.
     35 * Une RPC ''broadcast bloquante'' est envoyée à N serveurs, et attend N réponses.
     36 * Une RPC ''simple non bloquante'' est envoyée à un seul serveur et n'attend pas de réponse.
     37 * Une RPC ''broadcast non bloquante'' est envoyée à N serveurs et n'attend pas de réponse.
     38
     39Chaque 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. 
     40Un descripteur de RPC possède un format fixe comportant les informations suivantes:
     41 * Le champs '''index''' définit le type de service demandé (de façon similaire à un index d'appel système).
     42 * Le champs '''response''' est un entier qui défini le nombre de réponses attendues.
     43 * Le champs '''args''' est un tableau de 32 uint32_t contenant les arguments d'entrée et de sortie.
     44L'utilisation et l'interprétation du tableau '''args''' dépend de chaque type de RPC.
     45
     46== 4) Introduction d'une nouvelle RPC ==
     47
     48L'introduction d'un nouveau service nécessite de modifier le code de ALMOS-MK de la façon suivante opérations suivantes.
     49 * 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.
     50 * La nouvelle doit être enregistrée dans l'enum ''rpc_index_t'' (fichier rpc.h) et dans le tableau ''rpc_exec[]'' (fichier rpc.c).
     51 * 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.
     52 * 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.
     53