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