861fa3d4524d07ae7b9847e0131fad65399fa3f7
[archipelago] / xseg / xseg / xseg.h
1 /*
2  * Copyright 2012 GRNET S.A. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or
5  * without modification, are permitted provided that the following
6  * conditions are met:
7  *
8  *   1. Redistributions of source code must retain the above
9  *      copyright notice, this list of conditions and the following
10  *      disclaimer.
11  *   2. Redistributions in binary form must reproduce the above
12  *      copyright notice, this list of conditions and the following
13  *      disclaimer in the documentation and/or other materials
14  *      provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  *
29  * The views and conclusions contained in the software and
30  * documentation are those of the authors and should not be
31  * interpreted as representing official policies, either expressed
32  * or implied, of GRNET S.A.
33  */
34
35 #ifndef _XSEG_H
36 #define _XSEG_H
37
38 #ifndef XSEG_VERSION
39 #define XSEG_VERSION 2012022601
40 #endif
41
42 #ifndef XSEG_PAGE_SHIFT
43 #define XSEG_PAGE_SHIFT 12
44 #endif
45
46 #define XSEG_BASE (0x37fd0UL << XSEG_PAGE_SHIFT)
47 #define XSEG_BASE_AS_PTR ((void *)XSEG_BASE)
48 #define XSEG_BASE_AS_BUF ((char *)XSEG_BASE)
49 #define XSEG_OFFSET(base, ptr) ((unsigned long)(ptr) - (unsigned long)(base))
50 #define XSEG_PTR_CONVERT(ptr, src, dst) ((void *)((unsigned long)(dst) + XSEG_OFFSET(src, ptr)))
51 #define XSEG_TAKE_PTR(ptr, base) XSEG_PTR_CONVERT(ptr, XSEG_BASE, base)
52 #define XSEG_MAKE_PTR(ptr, base) XSEG_PTR_CONVERT(ptr, base, XSEG_BASE)
53
54 #include <sys/util.h>
55 #include <xtypes/xq.h>
56 #include <xtypes/xobj.h>
57 #include <xtypes/xhash.h>
58 #include <xtypes/xpool.h>
59
60 typedef uint64_t xserial;
61 typedef uint32_t xport;
62
63 #define NoSerial ((xserial)-1)
64 #define NoPort ((xport) -1)
65
66 #ifndef XSEG_DEF_REQS
67 #define XSEG_DEF_REQS 256
68 #endif
69
70 #ifndef XSEG_DEF_MAX_ALLOCATED_REQS
71 #define XSEG_DEF_MAX_ALLOCATED_REQS 1024
72 #endif
73
74 /* hard limit on max allocated requests per port */
75 //FIXME make this a dynamicly calculated value based
76 //on heap_size and request_h->size
77 #ifndef XSEG_MAX_ALLOCATED_REQS
78 #define XSEG_MAX_ALLOCATED_REQS 10000
79 #endif
80
81 #if XSEG_DEF_MAX_ALLOCATED_REQS > XSEG_MAX_ALLOCATED_REQS
82 #error "XSEG_DEF_MAX_ALLOCATED_REQS should be less than XSEG_MAX_ALLOCATED_REQS"
83 #endif
84
85 #if XSEG_DEF_REQS > XSEG_MAX_ALLOCATED_REQS
86 #error  "XSEG_DEF_REQS should me less than XSEG_MAX_ALLOCATED_REQS"
87 #endif
88
89 #ifndef MAX_PATH_LEN
90 #define MAX_PATH_LEN 32
91 #endif
92
93 #define XSEG_NAMESIZE 256
94 #define XSEG_TNAMESIZE 32
95
96 /* Peers and Segments
97  *
98  *  Segments are memory segments shared among peers.
99  *  Peers are local execution contexes that share a segment.
100  *
101  *  xseg_type and xseg_peer
102  *
103  *  A peer needs an xseg_type in order to
104  *  create or access a certain segment type,
105  *  and it needs an xseg_peer in order to
106  *  communicate with a certain type of peer.
107  *  Both segment and peer types are identified by name strings.
108  *
109  *  Note that each peer (that is, context) type will need
110  *  different code to access the same type of segment or peer.
111  *  Therefore each peer must have its own "customized" version
112  *  of the xseg library.
113  *
114  *  This is accomplished by mechanisms for registering both
115  *  xseg_type's and xseg_peer's. This can be done at both at build time
116  *  and at runtime, through a plugin-loading mechanism (where applicable).
117  *  The plugin namespace serves both segment and peer type namespace,
118  *  so if a segment type has the same name with a peer type,
119  *  they must be provided by the same plugin.
120  *
121  *  Note also that peers of different types may share the same segment.
122  *  Therefore each peer must know the type of each peer it needs to
123  *  communicate with, and have a driver for it.
124  *
125 */
126
127 struct xseg;
128 struct xseg_port;
129
130 #define XSEG_MAGIC      (0xcafe0000)
131 #define MAGIC_OBJH      (XSEG_MAGIC | 1)
132 #define MAGIC_REQ       (XSEG_MAGIC | 2)
133 #define MAGIC_PORT      (XSEG_MAGIC | 3)
134
135 struct xseg_operations {
136         void  (*mfree)(void *mem);
137         long  (*allocate)(const char *name, uint64_t size);
138         long  (*deallocate)(const char *name);
139         void *(*map)(const char *name, uint64_t size, struct xseg *seg);
140         void  (*unmap)(void *xseg, uint64_t size);
141 };
142
143 struct xseg_type {
144         struct xseg_operations ops;
145         char name[XSEG_TNAMESIZE];
146 };
147
148
149 struct xseg_peer_operations {
150         int   (*init_signal_desc)(struct xseg *xseg, void *sd);
151         void  (*quit_signal_desc)(struct xseg *xseg, void *sd);
152         void *(*alloc_data)(struct xseg *xseg);
153         void  (*free_data)(struct xseg *xseg, void *data);
154         void *(*alloc_signal_desc)(struct xseg *xseg, void *data);
155         void  (*free_signal_desc)(struct xseg *xseg, void *data, void *sd);
156         int   (*local_signal_init)(struct xseg *xseg, xport portno);
157         void  (*local_signal_quit)(struct xseg *xseg, xport portno);
158         int   (*remote_signal_init)(void);
159         void  (*remote_signal_quit)(void);
160         int   (*signal_join)(struct xseg *xseg);
161         int   (*signal_leave)(struct xseg *xseg);
162         int   (*prepare_wait)(struct xseg *xseg, uint32_t portno);
163         int   (*cancel_wait)(struct xseg *xseg, uint32_t portno);
164         int   (*wait_signal)(struct xseg *xseg, uint32_t usec_timeout);
165         int   (*signal)(struct xseg *xseg, uint32_t portno);
166         void *(*malloc)(uint64_t size);
167         void *(*realloc)(void *mem, uint64_t size);
168         void  (*mfree)(void *mem);
169 };
170
171 struct xseg_peer {
172         struct xseg_peer_operations peer_ops;
173         char name[XSEG_TNAMESIZE];
174 };
175
176 struct xseg_config {
177         uint64_t heap_size;     /* heap size in MB */
178         uint32_t nr_ports;
179         uint32_t page_shift;    /* the alignment unit */
180         char type[XSEG_TNAMESIZE]; /* zero-terminated identifier */
181         char name[XSEG_NAMESIZE];  /* zero-terminated identifier */
182 };
183
184 struct xseg_port {
185         struct xlock fq_lock;
186         struct xlock rq_lock;
187         struct xlock pq_lock;
188         xptr free_queue;
189         xptr request_queue;
190         xptr reply_queue;
191         uint64_t owner;
192         uint64_t peer_type;
193         uint32_t portno;
194         uint64_t max_alloc_reqs;
195         uint64_t alloc_reqs;
196         struct xlock port_lock;
197         xptr signal_desc;
198 };
199
200 struct xseg_request;
201
202 struct xseg_task {
203         uint64_t epoch;
204         struct xseg_request *req;
205         xqindex *deps;
206         xqindex nr_deps;
207         xqindex __alloced_deps;
208 };
209
210 /* OPS */
211 #define X_PING      0
212 #define X_READ      1
213 #define X_WRITE     2
214 #define X_SYNC      3
215 #define X_TRUNCATE  4
216 #define X_DELETE    5
217 #define X_ACQUIRE   6
218 #define X_RELEASE   7
219 #define X_COPY      8
220 #define X_CLONE     9
221 #define X_COMMIT   10
222 #define X_INFO     11
223 #define X_MAPR     12
224 #define X_MAPW     13
225 #define X_OPEN     14
226 #define X_CLOSE    15
227
228 /* FLAGS */
229 #define XF_NOSYNC (1 << 0)
230 #define XF_FLUSH  (1 << 1)
231 #define XF_FUA    (1 << 2)
232 #define XF_FORCE  (1 << 3)
233
234 /* STATES */
235 #define XS_SERVED       (1 << 0)
236 #define XS_FAILED       (1 << 1)
237
238 #define XS_ACCEPTED     (1 << 2)
239 #define XS_PENDING      (2 << 2)
240 #define XS_SERVING      (3 << 2)
241 #define XS_CONCLUDED    (3 << 2)
242
243 struct xseg_request {
244         xserial serial;
245         uint64_t offset;
246         uint64_t size; 
247         uint64_t serviced;
248         xptr data;
249         uint64_t datalen;
250         xptr target;
251         uint32_t targetlen;
252         uint32_t op;
253         uint32_t state;
254         uint32_t flags;
255         xport src_portno;
256         xport src_transit_portno;
257         xport dst_portno;
258         xport dst_transit_portno;
259         struct xq path;
260         xqindex path_bufs[MAX_PATH_LEN];
261         /* pad */
262         xptr buffer;
263         uint64_t bufferlen;
264         xqindex task;
265         uint64_t priv;
266         struct timeval timestamp;
267         uint64_t elapsed;
268 };
269
270 struct xseg_shared {
271         uint64_t flags;
272         char (*peer_types)[XSEG_TNAMESIZE]; /* alignment? */
273         xptr *peer_type_data;
274         uint32_t nr_peer_types;
275 };
276
277 struct xseg_private {
278         struct xseg_type segment_type;
279         struct xseg_peer peer_type;
280         struct xseg_peer **peer_types;
281         void **peer_type_data;
282         uint32_t max_peer_types;
283         void (*wakeup)(uint32_t portno);
284         xhash_t *req_data;
285         struct xlock reqdatalock;
286 };
287
288 struct xseg_counters {
289         uint64_t avg_req_lat;
290         uint64_t req_cnt;
291 };
292
293 struct xseg {
294         uint64_t version;
295         uint64_t segment_size;
296         struct xseg *segment;
297         struct xheap *heap;
298         struct xobject_h *object_handlers;
299
300         struct xobject_h *request_h;
301         struct xobject_h *port_h;
302         xptr *ports;
303         xport *src_gw, *dst_gw;
304
305         struct xseg_shared *shared;
306         struct xseg_private *priv;
307         uint32_t max_peer_types;
308         struct xseg_config config;
309         struct xseg_counters counters;
310 };
311
312 #define XSEG_F_LOCK 0x1
313
314 /* ================= XSEG REQUEST INTERFACE ================================= */
315 /*                     ___________________                         _________  */
316 /*                    /                   \                       /         \ */
317                 int    xseg_initialize      ( void                            );
318
319                 int    xseg_finalize        ( void                            );
320
321                 int    xseg_parse_spec      ( char                * spec,
322                                               struct xseg_config  * config    );
323
324    struct xseg_port *  xseg_bind_port       ( struct xseg         * xseg,
325                                               uint32_t              portno,
326                                               void                * sd        );
327
328     static uint32_t    xseg_portno          ( struct xseg         * xseg,
329                                               struct xseg_port    * port      );
330 /*                    \___________________/                       \_________/ */
331 /*                     ___________________                         _________  */
332 /*                    /                   \                       /         \ */
333                 int    xseg_register_type   ( struct xseg_type    * type      );
334                 int    xseg_unregister_type ( const char          * name      );
335
336                 int    xseg_register_peer   ( struct xseg_peer    * peer      );
337                 int    xseg_unregister_peer ( const char          * name      );
338
339                void    xseg_report_peer_types( void );
340
341             int64_t    xseg_enable_driver   ( struct xseg         * xseg,
342                                               const char          * name      );
343                 int    xseg_disable_driver  ( struct xseg         * xseg,
344                                               const char          * name      );
345 /*                    \___________________/                       \_________/ */
346 /*                     ___________________                         _________  */
347 /*                    /                   \                       /         \ */
348                 int    xseg_create          ( struct xseg_config  * cfg       );
349
350                void    xseg_destroy         ( struct xseg         * xseg      );
351 /*                    \___________________/                       \_________/ */
352 /*                     ___________________                         _________  */
353 /*                    /                   \                       /         \ */
354         struct xseg *  xseg_join            ( char                * segtype,
355                                               char                * segname,
356                                               char                * peertype,
357                                               void               (* wakeup    )
358                                              (uint32_t              portno   ));
359
360                void    xseg_leave           ( struct xseg         * xseg      );
361 /*                    \___________________/                       \_________/ */
362 /*                     ___________________                         _________  */
363 /*                    /                   \                       /         \ */
364                 int    xseg_alloc_requests  ( struct xseg         * xseg,
365                                               uint32_t              portno,
366                                               uint32_t              nr        );
367
368                 int    xseg_free_requests   ( struct xseg         * xseg,
369                                               uint32_t              portno,
370                                               int                   nr        );
371
372 struct xseg_request *  xseg_get_request     ( struct xseg         * xseg,
373                                               xport                 src_portno,
374                                               xport                 dst_portno,
375                                               uint32_t              flags     );
376
377                 int    xseg_put_request     ( struct xseg         * xseg,
378                                               struct xseg_request * xreq,
379                                               xport                 portno    );
380
381                 int    xseg_prep_request    ( struct xseg         * xseg,
382                                               struct xseg_request * xreq,
383                                               uint32_t              targetlen,
384                                               uint64_t              datalen  );
385 /*                    \___________________/                       \_________/ */
386 /*                     ___________________                         _________  */
387 /*                    /                   \                       /         \ */
388               xport    xseg_submit          ( struct xseg         * xseg,
389                                               struct xseg_request * xreq,      
390                                               xport                 portno,
391                                               uint32_t              flags     );
392
393 struct xseg_request *  xseg_receive         ( struct xseg         * xseg,
394                                               xport                 portno,    
395                                               uint32_t              flags     );
396 /*                    \___________________/                       \_________/ */
397 /*                     ___________________                         _________  */
398 /*                    /                   \                       /         \ */
399
400 struct xseg_request *  xseg_accept          ( struct xseg         * xseg,
401                                               xport                 portno,    
402                                               uint32_t              flags     );
403
404               xport    xseg_respond         ( struct xseg         * xseg,
405                                               struct xseg_request * xreq,
406                                               xport                 portno,
407                                               uint32_t              flags     );
408 /*                    \___________________/                       \_________/ */
409 /*                     ___________________                         _________  */
410 /*                    /                   \                       /         \ */
411                 int    xseg_prepare_wait    ( struct xseg         * xseg,
412                                               uint32_t              portno    );
413
414                 int    xseg_cancel_wait     ( struct xseg         * xseg,
415                                               uint32_t              portno    );
416
417                 int    xseg_wait_signal     ( struct xseg         * xseg,
418                                               uint32_t              utimeout  );
419
420                 int    xseg_signal          ( struct xseg         * xseg,
421                                               uint32_t              portno    );
422 /*                    \___________________/                       \_________/ */
423
424
425
426 /*                                                                            */
427 /* ================= XSEG REQUEST INTERFACE ================================= */
428
429 struct xseg_port* xseg_get_port(struct xseg *xseg, uint32_t portno);
430
431 static inline uint32_t xseg_portno(struct xseg *xseg, struct xseg_port *port)
432 {
433         return port->portno;
434 }
435
436 static inline char* xseg_get_target(struct xseg* xseg, struct xseg_request *req)
437 {
438         return (char *) XPTR_TAKE(req->target, xseg->segment);
439 }
440
441 static inline char* xseg_get_data(struct xseg* xseg, struct xseg_request *req)
442 {
443         return (char *) XPTR_TAKE(req->data, xseg->segment);
444 }
445
446 static inline void * xseg_get_signal_desc(struct xseg *xseg, struct xseg_port *port)
447 {
448         return (void *) XPTR_TAKE(port->signal_desc, xseg->segment);
449 }
450
451 struct xobject_h * xseg_get_objh(struct xseg *xseg, uint32_t magic, uint64_t size);
452 void xseg_put_objh(struct xseg *xseg, struct xobject_h *objh);
453
454 #define xseg_get_queue(__xseg, __port, __queue) \
455         ((struct xq *) XPTR_TAKE(__port->__queue, __xseg->segment))
456
457 #endif
458
459 xport xseg_set_srcgw            (struct xseg *xseg, xport portno, xport srcgw);
460 xport xseg_getandset_srcgw      (struct xseg *xseg, xport portno, xport srcgw);
461 xport xseg_set_dstgw            (struct xseg *xseg, xport portno, xport dstgw);
462 xport xseg_getandset_dstgw      (struct xseg *xseg, xport portno, xport dstgw);
463
464 int xseg_set_req_data (struct xseg *xseg, struct xseg_request *xreq, void *data);
465 int xseg_get_req_data (struct xseg *xseg, struct xseg_request *xreq, void **data);
466
467 int xseg_init_local_signal(struct xseg *xseg, xport portno);
468 void xseg_quit_local_signal(struct xseg *xseg, xport portno);
469
470 int xseg_resize_request (struct xseg *xseg, struct xseg_request *req,
471                         uint32_t new_targetlen, uint64_t new_datalen);
472
473 int xseg_set_max_requests(struct xseg *xseg, xport portno, uint64_t nr_reqs);
474 uint64_t xseg_get_max_requests(struct xseg *xseg, xport portno);
475 uint64_t xseg_get_allocated_requests(struct xseg *xseg, xport portno);
476 int xseg_set_freequeue_size(struct xseg *xseg, xport portno, xqindex size,
477                                 uint32_t flags);
478
479