Changes between Version 14 and Version 15 of rpc_implementation


Ignore:
Timestamp:
Mar 11, 2017, 6:39:46 PM (7 years ago)
Author:
alain
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • rpc_implementation

    v14 v15  
    33[[PageOutline]]
    44
    5 Pour renforcer la localité des accès et éviter la contention, 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.
     5Pour renforcer la localité des accès pour des opérations complexes (c'est a dire nécessitant un grand nombre d'accès a des structures de données distantes), les différentes instances du noyau peuvent communiquer 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.
    66
    77Le code et les différentes structures de données utilisées pour les RPCs sont définis dans les fichiers rpc.c et rpc.h. 
    88Ce 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.
    9 Les macros permettant la manipulation des pointeurs étendus sont définies dans le fichier type.h, qui est spécifique à l'architecture visée.
     9Les macros permettant la manipulation des pointeurs étendus sont définies dans le fichier hal_types.h, qui est spécifique à l'architecture visée.
    1010
    1111== 1) Hypothèses concernant la plate-forme matérielle ==
    1212
    13 L'architecture cible est généralement clusterisée, ce qui signifie que l'espace d'adressage physique est partagé par tous les CPUs, mais qu'il est partitionné entre les différents clusters. Le nombre de clusters, ainsi que le contenu de chaque cluster sont décrits dans le fichier ''arch-info''. ALMOS-MK supporte les architectures cibles respectant les contraintes suivantes:
     13L'architecture cible est généralement clusterisée, ce qui signifie que l'espace d'adressage physique est partagé par tous les CPUs, mais qu'il est partitionné entre les différents clusters. Le nombre de clusters, ainsi que le contenu de chaque cluster sont décrits dans le fichier ''arch-info''. ALMOS-MKH supporte les architectures cibles respectant les contraintes suivantes:
    1414 * Les adresses physiques, aussi appelées adresses étendues, sont codées sur 64 bits.
    15  * La taille maximale de l'espace adressable physique accessible dans un unique cluster est définit par le paramètre global CONFIG_CLUSTER_SPAN qui est une puissance de 2. Elle vaut 4 Goctets pour TSAR, mais peut posséder une valeur différente (plus grande) pour d'autres architectures. Une adresse physique est donc divisée en deux parties: le champs '''PTR''' est l'adresse locale dans un cluster, et le champs '''CXY''' est le numéro identifiant un cluster particulier.
     15 * La taille maximale de l'espace adressable physique accessible dans un unique cluster est définit par le paramètre global CONFIG_CLUSTER_SPAN qui est une puissance de 2. Elle vaut 4 Goctets pour TSAR, mais peut posséder une valeur plus grande pour d'autres architectures. Une adresse physique est donc divisée en deux parties: le champs '''LPA''' est l'adresse physique locale dans un cluster, et le champs '''CXY''' est le numéro identifiant un cluster particulier.
    1616 * Chaque cluster 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). Pour chaque périphérique et pour le banc mémoire, le fichier ''arch_info''  définit l'adresse locale de base, et la longueur du segment associé.
    1717 * Il existe une instance du noyau dans tout cluster contenant au moins un CPU, un contrôleur d'interruptions, et un banc mémoire physique, ce qui n'est pas forcément le cas de tous les clusters.
     
    2020== 2) Point d'accès unique dans chaque cluster ==
    2121
    22 Rappelons que toutes les variables globales définies dans le segment KDATA du noyau sont répliquées dans tous les clusters. Deux variables de même nom peuvent avoir des valeurs différentes dans deux clusters différents, mais elles sont rangées à des adresses locales PTR identiques. Cette propriété est fondamentale, puisqu'elle permet à une instance du noyau dans un cluster K d'accéder directement  aux données globales des autres instance du noyau dans un cluster L, en fabricant une adresse physique à partir de l'adresse PTR (commune à tous les clusters) et de l'identifiant CXY du cluster cible.
     22Dans ALMOS_MKH, toutes les variables globales définies dans le segment KDATA du noyau sont répliquées dans tous les clusters. Deux variables de même nom peuvent avoir des valeurs différentes dans deux clusters différents, mais elles sont rangées à des adresses locales LPA identiques. Cette propriété est fondamentale, puisqu'elle permet à une instance du noyau dans un cluster K d'accéder directement  aux données globales des autres instance du noyau dans un cluster L, en fabricant une adresse physique à partir de l'adresse LPA (commune à tous les clusters) et de l'identifiant CXY du cluster cible.
    2323
    2424N'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, identifié par son index CXY.
    25 Il existe donc dans chaque cluster une FIFO logicielle, appelée RPC_FIFO, et possédant à priori N écrivains et M lecteurs. N est le nombre de thread clients, a priori non borné. M est le nombre de thread serveurs dont le nombre maximal dans un cluster est un paramètre de configuration.
     25
     26Il existe dans chaque cluster une FIFO logicielle, appelée RPC_FIFO, et possédant à priori N écrivains et M lecteurs. N est le nombre de thread clients, a priori non borné. M est le nombre de thread serveurs dont le nombre maximal dans un cluster est défini par le paramètre de configuration CONFIG_RPC_THREAD_MAX.
    2627 * 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.
    27  * 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.
     28 * 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. Ce verrou est non bloquant, puisque tout échec signifie qu'un autre lecteur a gagné, et se charge d'effectuer le traitement.
    2829
    2930== 3) Traitement parallèle des RPCs ==
    3031
    31 Les threads serveurs 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.
     32Les threads serveurs chargé de traiter les RPCs  appartiennent à un ''pool'' de  threads spécialisés appelés RPC_THREAD. Un RPC_THREAD du cluster serveur est activé chaque fois que l'O.S. détecte que la RPC_FIFO est non-vide, et qu'il parvient à acquérir la propriété de la FIFO grâce au mécanisme de ''light-lock''. Le RPC_THREAD s'exécute alors 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 libérer la FIFO. Si un RPC_THREAD doit attendre la disponibilité d'une ressource, il se bloque sur la condition particulière associée à cette ressource, et déclenche une opération d'ordonnancement, après avoir libéré la RPC_FIFO, pour permettre le traitement d'autres RPCs. Il y a donc à tout instant au plus un RPC_THREAD propriétaire  de la RPC_FIFO, et possédant le droit de consommer une nouvelle RPC. Mais il peut donc exister plusieurs RPC_THREAD actifs, traitant chacun une RPC en cours de traitement.
     33
     34L'activation/désactivation d'un RPC_THREAD est implémentée comme un bit particulier du vecteur de bit représentant les causes de blocages d'un thread.
    3235
    3336== 4) Format d'une RPC ==
     
    3942 * Une RPC ''multicast non bloquante'' est envoyée à N serveurs et n'attend pas de réponse.
    4043
    41 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. 
     44Chaque case d'une RPC_FIFO contient un pointeur étendu (xptr_t) sur un descripteur de RPC (rpc_desc_t), qui est stocké dans la mémoire du cluster client. 
    4245Un descripteur de RPC possède un format fixe comportant les informations suivantes:
    4346 * Le champs '''index''' définit le type de service demandé (de façon similaire à un index d'appel système).
     
    5154== 5) Introduction d'une nouvelle RPC ==
    5255
    53 L'introduction d'une nouvelle RPC nécessite de modifier le code de ALMOS-MK de la façon suivante:
     56L'introduction d'une nouvelle RPC nécessite de modifier le code de ALMOS-MKH de la façon suivante:
    5457 * Il faut définir ou identifier la fonction système ''my_kernel_service()'' qu'on souhaite exécuter à distance. Le nombre de paramètres d'entrée ou de sortie ne doit pas être supérieur à 8.
    55  * La nouvelle RPC doit être enregistrée dans l'enum ''rpc_index_t'' (fichier rpc.h) et dans le tableau ''rpc_exec[]'' (fichier rpc.c).
     58 * La nouvelle RPC doit être enregistrée dans l'enum ''rpc_index_t'' (fichier rpc.h) et dans le tableau ''rpc_server[]'' (fichier rpc.c).
    5659 * 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.
    5760 * 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, (4) signaler la terminaison.