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