| [1] | 1 | /* | 
|---|
|  | 2 | * rpc.h - RPC related operations | 
|---|
|  | 3 | * | 
|---|
|  | 4 | * Authors Mohamed Karaoui (2015) | 
|---|
|  | 5 | *         Alain Greiner (2016) | 
|---|
|  | 6 | * | 
|---|
|  | 7 | * Copyright (c) UPMC Sorbonne Universites | 
|---|
|  | 8 | * | 
|---|
|  | 9 | * This file is part of ALMOS-MK. | 
|---|
|  | 10 | * | 
|---|
|  | 11 | * ALMOS-MK is free software; you can redistribute it and/or modify it | 
|---|
|  | 12 | * under the terms of the GNU General Public License as published by | 
|---|
|  | 13 | * the Free Software Foundation; version 2.0 of the License. | 
|---|
|  | 14 | * | 
|---|
|  | 15 | * ALMOS-MK is distributed in the hope that it will be useful, but | 
|---|
|  | 16 | * WITHOUT ANY WARRANTY; without even the implied warranty of | 
|---|
|  | 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
|---|
|  | 18 | * General Public License for more details. | 
|---|
|  | 19 | * | 
|---|
|  | 20 | * You should have received a copy of the GNU General Public License | 
|---|
|  | 21 | * along with ALMOS-MK; if not, write to the Free Software Foundation, | 
|---|
|  | 22 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 
|---|
|  | 23 | */ | 
|---|
|  | 24 |  | 
|---|
|  | 25 | #ifndef _RPC_H_ | 
|---|
|  | 26 | #define _RPC_H_ | 
|---|
|  | 27 |  | 
|---|
|  | 28 | #include <errno.h> | 
|---|
|  | 29 | #include <types.h> | 
|---|
|  | 30 | #include <bits.h> | 
|---|
|  | 31 | #include <atomic.h> | 
|---|
|  | 32 | #include <spinlock.h> | 
|---|
|  | 33 | #include <remote_fifo.h> | 
|---|
|  | 34 | #include <kernel_config.h> | 
|---|
|  | 35 |  | 
|---|
|  | 36 | /**********************************************************************************/ | 
|---|
|  | 37 | /**************  structures for Remote Procedure Calls ****************************/ | 
|---|
|  | 38 | /**********************************************************************************/ | 
|---|
|  | 39 |  | 
|---|
|  | 40 | /*********************************************************************************** | 
|---|
|  | 41 | *  This enum defines all RPC indexes (must be consistent with array in rpc.c) | 
|---|
|  | 42 | **********************************************************************************/ | 
|---|
|  | 43 |  | 
|---|
|  | 44 | typedef enum | 
|---|
|  | 45 | { | 
|---|
|  | 46 | RPC_PMEM_GET_PAGES         = 0, | 
|---|
|  | 47 | RPC_PROCESS_PID_ALLOC      = 1, | 
|---|
|  | 48 | RPC_PROCESS_MIGRATE        = 2, | 
|---|
|  | 49 | RPC_THREAD_USER_CREATE     = 3, | 
|---|
|  | 50 | RPC_VFAT_ALLOC_FAT_ENTRY   = 4, | 
|---|
|  | 51 | RPC_VFAT_CLUSTER_COUNT     = 5, | 
|---|
|  | 52 | RPC_VFS_LOOKUP_CHILD       = 6, | 
|---|
|  | 53 | RPC_MAX_INDEX              = 7 | 
|---|
|  | 54 | } | 
|---|
|  | 55 | rpc_index_t; | 
|---|
|  | 56 |  | 
|---|
|  | 57 | /*********************************************************************************** | 
|---|
|  | 58 | *  This structure defines the RPC descriptor | 
|---|
|  | 59 | **********************************************************************************/ | 
|---|
|  | 60 |  | 
|---|
|  | 61 | typedef struct rpc_desc_s | 
|---|
|  | 62 | { | 
|---|
|  | 63 | rpc_index_t       index;      // index of requested RPC service | 
|---|
|  | 64 | volatile uint32_t response;   // response valid when 0 | 
|---|
|  | 65 | uint64_t          args[7];    // input/output arguments buffer | 
|---|
|  | 66 | } | 
|---|
|  | 67 | rpc_desc_t; | 
|---|
|  | 68 |  | 
|---|
|  | 69 | /*********************************************************************************** | 
|---|
|  | 70 | *  This structure defines the RPC fifo, the associated light lock, | 
|---|
|  | 71 | *  and the intrumentation counter. | 
|---|
|  | 72 | **********************************************************************************/ | 
|---|
|  | 73 |  | 
|---|
|  | 74 | typedef struct rpc_fifo_s | 
|---|
|  | 75 | { | 
|---|
|  | 76 | spinlock_t lock;          // spinlock for the readers | 
|---|
|  | 77 | uint64_t          count;  // total number of received RPCs (instrumentation) | 
|---|
|  | 78 | remote_fifo_t     fifo;   // embedded remote fifo | 
|---|
|  | 79 | } | 
|---|
|  | 80 | rpc_fifo_t; | 
|---|
|  | 81 |  | 
|---|
|  | 82 |  | 
|---|
|  | 83 | /**********************************************************************************/ | 
|---|
|  | 84 | /******* Generic functions supporting RPCs : client side **************************/ | 
|---|
|  | 85 | /**********************************************************************************/ | 
|---|
|  | 86 |  | 
|---|
|  | 87 | /*********************************************************************************** | 
|---|
|  | 88 | * This blocking function executes on the client core. | 
|---|
|  | 89 | * It puts one RPC extended pointer in the remote fifo. | 
|---|
|  | 90 | * It sends an IPI if fifo is empty, and waits until RPC response available. | 
|---|
|  | 91 | * The RPC descriptor must be allocated in the caller's stack | 
|---|
|  | 92 | * and initialised by the caller.  Exit with a Panic message if remote fifo | 
|---|
|  | 93 | * is still full after (CONFIG_RPC_PUT_MAX_ITERATIONS) retries. | 
|---|
|  | 94 | * @ cxy   : server cluster identifier | 
|---|
|  | 95 | * @ desc  : local pointer on RPC descriptor in client cluster | 
|---|
|  | 96 | **********************************************************************************/ | 
|---|
|  | 97 | void rpc_send_sync( cxy_t        cxy, | 
|---|
|  | 98 | rpc_desc_t * desc ); | 
|---|
|  | 99 |  | 
|---|
|  | 100 | /*********************************************************************************** | 
|---|
|  | 101 | * This non blocking function is called by the scheduler of the client core | 
|---|
|  | 102 | * to detect RPC completion. | 
|---|
|  | 103 | * @ ptr   : local pointer on the RPC descriptor in client cluster. | 
|---|
|  | 104 | * @ return true if the client thread must resume (RPC completed). | 
|---|
|  | 105 | **********************************************************************************/ | 
|---|
|  | 106 | static bool_t rpc_callback( void * ptr ); | 
|---|
|  | 107 |  | 
|---|
|  | 108 |  | 
|---|
|  | 109 |  | 
|---|
|  | 110 | /**********************************************************************************/ | 
|---|
|  | 111 | /******* Generic functions supporting RPCs : server side **************************/ | 
|---|
|  | 112 | /**********************************************************************************/ | 
|---|
|  | 113 |  | 
|---|
|  | 114 | /*********************************************************************************** | 
|---|
|  | 115 | * This function initialises the local RPC fifo and the lock protecting readers. | 
|---|
|  | 116 | * The number of slots is defined by the CONFIG_REMOTE_FIFO_SLOTS parameter. | 
|---|
|  | 117 | * Each slot contains an extended pointer on the RPC descriptor. | 
|---|
|  | 118 | * @ rf     : pointer on the local RPC fifo. | 
|---|
|  | 119 | **********************************************************************************/ | 
|---|
|  | 120 | void rpc_fifo_init( rpc_fifo_t * rf ); | 
|---|
|  | 121 |  | 
|---|
|  | 122 | /*********************************************************************************** | 
|---|
|  | 123 | * This function is the entry point for RPC handling on the server side. | 
|---|
|  | 124 | * It can be executed by any thread running (in kernel mode) on any CPU. | 
|---|
|  | 125 | * It first checks the CPU private RPC fifo, an then the cluster shared RPC fifo. | 
|---|
|  | 126 | * It calls the rpc_activate_thread() function to activate a dedicated RPC thread, | 
|---|
|  | 127 | * after registration of the selected RPC fifo in the selected thread descriptor. | 
|---|
|  | 128 | * @ returns true if at least one RPC found / false otherwise. | 
|---|
|  | 129 | **********************************************************************************/ | 
|---|
|  | 130 | bool_t rpc_check(); | 
|---|
|  | 131 |  | 
|---|
|  | 132 | /*********************************************************************************** | 
|---|
|  | 133 | * This function contains the loop to execute all pending RPCs on the server side. | 
|---|
|  | 134 | * It should be called with irq disabled and after light lock acquisition. | 
|---|
|  | 135 | * @ rpc_fifo  : pointer on the local RPC fifo | 
|---|
|  | 136 | * @ returns 0 if success | 
|---|
|  | 137 | **********************************************************************************/ | 
|---|
|  | 138 | error_r rpc_execute_all( rpc_fifo_t * rpc_fifo ); | 
|---|
|  | 139 |  | 
|---|
|  | 140 | /*********************************************************************************** | 
|---|
|  | 141 | * This function is acting as a demultiplexor on the server side. | 
|---|
|  | 142 | * Depending on the RPC index stored in the RPC descriptor, | 
|---|
|  | 143 | * it calls the relevant rpc_*_server() function. | 
|---|
|  | 144 | * @ xptr : extended pointer on the RPC descriptor. | 
|---|
|  | 145 | **********************************************************************************/ | 
|---|
|  | 146 | void rpc_handle( xptr_t * xp ); | 
|---|
|  | 147 |  | 
|---|
|  | 148 | /********************************************************************************** | 
|---|
|  | 149 | * This function activates one RPC thread to handle the pending RPC(s) contained | 
|---|
|  | 150 | * in one RPC fifo (shared or private). It is called by any thread detecting | 
|---|
|  | 151 | * a non-empty RPC fifo. | 
|---|
|  | 152 | * It gets the first free RPC thread from the free-list, or creates a new one | 
|---|
|  | 153 | * if the RPC thread free-list associated to the current cpu is empty. | 
|---|
|  | 154 | * Finally, the calling thread immediately switches to the RPC thread. | 
|---|
|  | 155 | * @ rpc_fifo : pointer on the non-empty RPC fifo. | 
|---|
|  | 156 | * @ return 0 if success / return ENOMEM if error. | 
|---|
|  | 157 | **********************************************************************************/ | 
|---|
|  | 158 | error_t rpc_activate_thread( rpc_fifo_t * rpc_fifo ); | 
|---|
|  | 159 |  | 
|---|
|  | 160 | /*********************************************************************************** | 
|---|
|  | 161 | * This function defines the infinite loop executed by each RPC thread. | 
|---|
|  | 162 | **********************************************************************************/ | 
|---|
|  | 163 | void * rpc_thread(); | 
|---|
|  | 164 |  | 
|---|
|  | 165 | /********************************************************************************** | 
|---|
|  | 166 | * This call-back function must be registered in the RPC thread descriptor. | 
|---|
|  | 167 | * It is executed by the scheduler when the thread makes a sched_sleep() call, | 
|---|
|  | 168 | * when the "before_sleep" field in thread descriptor is not NULL. | 
|---|
|  | 169 | * It releases the light lock and print a debug message. | 
|---|
|  | 170 | * @ thread  : local pointer on thread. | 
|---|
|  | 171 | **********************************************************************************/ | 
|---|
|  | 172 | void rpc_before_sleep( thread_t * thread ); | 
|---|
|  | 173 |  | 
|---|
|  | 174 | /********************************************************************************** | 
|---|
|  | 175 | * This call-back function must be registered in the RPC thread descriptor. | 
|---|
|  | 176 | * It is executed by the scheduler when the thread makes a wakeup(), | 
|---|
|  | 177 | * when the "after_wakeup" field in thread descriptor is not NULL. | 
|---|
|  | 178 | * It print a debug message. | 
|---|
|  | 179 | * @ thread  : local pointer on thread. | 
|---|
|  | 180 | **********************************************************************************/ | 
|---|
|  | 181 | void rpc_after_wakeup( thread_t * thread ); | 
|---|
|  | 182 |  | 
|---|
|  | 183 | /**********************************************************************************/ | 
|---|
|  | 184 | /******* Marshalling functions attached to the various RPCs ***********************/ | 
|---|
|  | 185 | /**********************************************************************************/ | 
|---|
|  | 186 |  | 
|---|
|  | 187 | /*********************************************************************************** | 
|---|
|  | 188 | * The RPC_PMEM_GET_PAGES allocates one or several pages in a remote cluster, | 
|---|
|  | 189 | * and returns the PPN of the first allocated page. | 
|---|
|  | 190 | * @ cxy     : server cluster identifier | 
|---|
|  | 191 | * @ order   : [in]  ln2( number of requested pages ) | 
|---|
|  | 192 | * @ status  : [out] error status (0 if success) | 
|---|
|  | 193 | * @ ppn     : [out] first physical page number | 
|---|
|  | 194 | **********************************************************************************/ | 
|---|
|  | 195 | void rpc_pmem_get_pages_client( cxy_t      cxy, | 
|---|
|  | 196 | uint32_t   order, | 
|---|
|  | 197 | uint32_t * status, | 
|---|
|  | 198 | uint32_t * ppn ); | 
|---|
|  | 199 |  | 
|---|
|  | 200 | void rpc_pmem_get_pages_server( xptr_t xp ); | 
|---|
|  | 201 |  | 
|---|
|  | 202 | /*********************************************************************************** | 
|---|
|  | 203 | * The RPC_PROCESS_PID_ALLOC allocates one new PID in a remote cluster, registers | 
|---|
|  | 204 | * the new process in the remote cluster, and returns the PID, and an error code. | 
|---|
|  | 205 | * @ cxy     : server cluster identifier. | 
|---|
|  | 206 | * @ process : [in]  pointer on process descriptor in client cluster. | 
|---|
|  | 207 | * @ status  : [out] error status (0 if success). | 
|---|
|  | 208 | * @ pid     : [out] new process identifier. | 
|---|
|  | 209 | **********************************************************************************/ | 
|---|
|  | 210 | void rpc_process_pid_alloc_client( cxy_t       cxy, | 
|---|
|  | 211 | process_t * process, | 
|---|
|  | 212 | error_t   * status, | 
|---|
|  | 213 | pid_t     * pid ); | 
|---|
|  | 214 |  | 
|---|
|  | 215 | void rpc_process_pid_alloc_server( xptr_t xp ); | 
|---|
|  | 216 |  | 
|---|
|  | 217 | /*********************************************************************************** | 
|---|
|  | 218 | * The RPC_PROCESS_MIGRATE creates a process descriptor copy, in a remote cluster | 
|---|
|  | 219 | * and initializes if from information found in the reference process descriptor. | 
|---|
|  | 220 | * This remote cluster becomes the new reference cluster. | 
|---|
|  | 221 | * @ cxy     : server cluster identifier. | 
|---|
|  | 222 | * @ xp_ref  : [in]  extended pointer on reference process descriptor. | 
|---|
|  | 223 | * @ status  : [out] error status (0 if success). | 
|---|
|  | 224 | **********************************************************************************/ | 
|---|
|  | 225 | void rpc_process_migrate_client( cxy_t       cxy, | 
|---|
|  | 226 | xptr_t      xp_ref, | 
|---|
|  | 227 | error_t   * status ); | 
|---|
|  | 228 |  | 
|---|
|  | 229 | void rpc_process_migrate_server( xptr_t xp ); | 
|---|
|  | 230 |  | 
|---|
|  | 231 | /*********************************************************************************** | 
|---|
|  | 232 | * The RPC_VFS_LOOKUP_CHILD returns in the lpr structure information on the | 
|---|
|  | 233 | * the inode identified by the dentry name and the lkp structure. | 
|---|
|  | 234 | * @ cxy     : server cluster identifier | 
|---|
|  | 235 | * @ lkp     : [in]   pointer on input structure in client cluster | 
|---|
|  | 236 | * @ name    : [in]   dentry name | 
|---|
|  | 237 | * @ lpr     : [out]  pointer on output structure in client cluster | 
|---|
|  | 238 | **********************************************************************************/ | 
|---|
|  | 239 | void rpc_vfs_lookup_child_client( cxy_t                    cxy, | 
|---|
|  | 240 | vfs_lookup_t          *  lkp, | 
|---|
|  | 241 | char                  *  name, | 
|---|
|  | 242 | vfs_lookup_response_t *  lpr ); | 
|---|
|  | 243 |  | 
|---|
|  | 244 | void rpc_vfs_lookup_child_server( xptr_t xp ); | 
|---|
|  | 245 |  | 
|---|
|  | 246 | /*********************************************************************************** | 
|---|
|  | 247 | * The RPC_THREAD_USER_CREATE creates an user thread in the server cluster, | 
|---|
|  | 248 | * as specified by the pthread_attr_t argument. It returns an extended pointer | 
|---|
|  | 249 | * on the thread descriptor in server cluster and an error code. | 
|---|
|  | 250 | * @ cxy     : server cluster identifier. | 
|---|
|  | 251 | * @ attr    : [in]   pointer on pthread_attr_t in client cluster. | 
|---|
|  | 252 | * @ error   : [out] error status (0 if success). | 
|---|
|  | 253 | * @ thread  : [out] extended pointer on thread descriptor. | 
|---|
|  | 254 | **********************************************************************************/ | 
|---|
|  | 255 | void rpc_thread_user_create_client( cxy_t             cxy, | 
|---|
|  | 256 | pthread_attr_t *  attr, | 
|---|
|  | 257 | error_t        *  error, | 
|---|
|  | 258 | xptr_t         *  new_thread ); | 
|---|
|  | 259 |  | 
|---|
|  | 260 | void rpc_thread_user_create_server( xptr_t xp ); | 
|---|
|  | 261 |  | 
|---|
|  | 262 |  | 
|---|
|  | 263 |  | 
|---|
|  | 264 | #endif | 
|---|