| 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 | 
|---|