Make xseg request state volatile
[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 #define X_SNAPSHOT 16
228
229 /* FLAGS */
230 #define XF_NOSYNC (1 << 0)
231 #define XF_FLUSH  (1 << 1)
232 #define XF_FUA    (1 << 2)
233 #define XF_FORCE  (1 << 3)
234
235 /* STATES */
236 #define XS_SERVED       (1 << 0)
237 #define XS_FAILED       (1 << 1)
238
239 #define XS_ACCEPTED     (1 << 2)
240 #define XS_PENDING      (2 << 2)
241 #define XS_SERVING      (3 << 2)
242 #define XS_CONCLUDED    (3 << 2)
243
244 struct xseg_request {
245         xserial serial;
246         uint64_t offset;
247         uint64_t size; 
248         uint64_t serviced;
249         xptr data;
250         uint64_t datalen;
251         xptr target;
252         uint32_t targetlen;
253         uint32_t op;
254         volatile uint32_t state;
255         uint32_t flags;
256         xport src_portno;
257         xport src_transit_portno;
258         xport dst_portno;
259         xport dst_transit_portno;
260         struct xq path;
261         xqindex path_bufs[MAX_PATH_LEN];
262         /* pad */
263         xptr buffer;
264         uint64_t bufferlen;
265         xqindex task;
266         uint64_t priv;
267         struct timeval timestamp;
268         uint64_t elapsed;
269 };
270
271 struct xseg_shared {
272         uint64_t flags;
273         char (*peer_types)[XSEG_TNAMESIZE]; /* alignment? */
274         xptr *peer_type_data;
275         uint32_t nr_peer_types;
276 };
277
278 struct xseg_private {
279         struct xseg_type segment_type;
280         struct xseg_peer peer_type;
281         struct xseg_peer **peer_types;
282         void **peer_type_data;
283         uint32_t max_peer_types;
284         void (*wakeup)(uint32_t portno);
285         xhash_t *req_data;
286         struct xlock reqdatalock;
287 };
288
289 struct xseg_counters {
290         uint64_t avg_req_lat;
291         uint64_t req_cnt;
292 };
293
294 struct xseg {
295         uint64_t version;
296         uint64_t segment_size;
297         struct xseg *segment;
298         struct xheap *heap;
299         struct xobject_h *object_handlers;
300
301         struct xobject_h *request_h;
302         struct xobject_h *port_h;
303         xptr *ports;
304         xport *src_gw, *dst_gw;
305
306         struct xseg_shared *shared;
307         struct xseg_private *priv;
308         uint32_t max_peer_types;
309         struct xseg_config config;
310         struct xseg_counters counters;
311 };
312
313 #define XSEG_F_LOCK 0x1
314
315 /* ================= XSEG REQUEST INTERFACE ================================= */
316 /*                     ___________________                         _________  */
317 /*                    /                   \                       /         \ */
318                 int    xseg_initialize      ( void                            );
319
320                 int    xseg_finalize        ( void                            );
321
322                 int    xseg_parse_spec      ( char                * spec,
323                                               struct xseg_config  * config    );
324
325    struct xseg_port *  xseg_bind_port       ( struct xseg         * xseg,
326                                               uint32_t              portno,
327                                               void                * sd        );
328
329     static uint32_t    xseg_portno          ( struct xseg         * xseg,
330                                               struct xseg_port    * port      );
331 /*                    \___________________/                       \_________/ */
332 /*                     ___________________                         _________  */
333 /*                    /                   \                       /         \ */
334                 int    xseg_register_type   ( struct xseg_type    * type      );
335                 int    xseg_unregister_type ( const char          * name      );
336
337                 int    xseg_register_peer   ( struct xseg_peer    * peer      );
338                 int    xseg_unregister_peer ( const char          * name      );
339
340                void    xseg_report_peer_types( void );
341
342             int64_t    xseg_enable_driver   ( struct xseg         * xseg,
343                                               const char          * name      );
344                 int    xseg_disable_driver  ( struct xseg         * xseg,
345                                               const char          * name      );
346 /*                    \___________________/                       \_________/ */
347 /*                     ___________________                         _________  */
348 /*                    /                   \                       /         \ */
349                 int    xseg_create          ( struct xseg_config  * cfg       );
350
351                void    xseg_destroy         ( struct xseg         * xseg      );
352 /*                    \___________________/                       \_________/ */
353 /*                     ___________________                         _________  */
354 /*                    /                   \                       /         \ */
355         struct xseg *  xseg_join            ( char                * segtype,
356                                               char                * segname,
357                                               char                * peertype,
358                                               void               (* wakeup    )
359                                              (uint32_t              portno   ));
360
361                void    xseg_leave           ( struct xseg         * xseg      );
362 /*                    \___________________/                       \_________/ */
363 /*                     ___________________                         _________  */
364 /*                    /                   \                       /         \ */
365                 int    xseg_alloc_requests  ( struct xseg         * xseg,
366                                               uint32_t              portno,
367                                               uint32_t              nr        );
368
369                 int    xseg_free_requests   ( struct xseg         * xseg,
370                                               uint32_t              portno,
371                                               int                   nr        );
372
373 struct xseg_request *  xseg_get_request     ( struct xseg         * xseg,
374                                               xport                 src_portno,
375                                               xport                 dst_portno,
376                                               uint32_t              flags     );
377
378                 int    xseg_put_request     ( struct xseg         * xseg,
379                                               struct xseg_request * xreq,
380                                               xport                 portno    );
381
382                 int    xseg_prep_request    ( struct xseg         * xseg,
383                                               struct xseg_request * xreq,
384                                               uint32_t              targetlen,
385                                               uint64_t              datalen  );
386 /*                    \___________________/                       \_________/ */
387 /*                     ___________________                         _________  */
388 /*                    /                   \                       /         \ */
389               xport    xseg_submit          ( struct xseg         * xseg,
390                                               struct xseg_request * xreq,      
391                                               xport                 portno,
392                                               uint32_t              flags     );
393
394 struct xseg_request *  xseg_receive         ( struct xseg         * xseg,
395                                               xport                 portno,    
396                                               uint32_t              flags     );
397 /*                    \___________________/                       \_________/ */
398 /*                     ___________________                         _________  */
399 /*                    /                   \                       /         \ */
400
401 struct xseg_request *  xseg_accept          ( struct xseg         * xseg,
402                                               xport                 portno,    
403                                               uint32_t              flags     );
404
405               xport    xseg_respond         ( struct xseg         * xseg,
406                                               struct xseg_request * xreq,
407                                               xport                 portno,
408                                               uint32_t              flags     );
409 /*                    \___________________/                       \_________/ */
410 /*                     ___________________                         _________  */
411 /*                    /                   \                       /         \ */
412                 int    xseg_prepare_wait    ( struct xseg         * xseg,
413                                               uint32_t              portno    );
414
415                 int    xseg_cancel_wait     ( struct xseg         * xseg,
416                                               uint32_t              portno    );
417
418                 int    xseg_wait_signal     ( struct xseg         * xseg,
419                                               uint32_t              utimeout  );
420
421                 int    xseg_signal          ( struct xseg         * xseg,
422                                               uint32_t              portno    );
423 /*                    \___________________/                       \_________/ */
424
425
426
427 /*                                                                            */
428 /* ================= XSEG REQUEST INTERFACE ================================= */
429
430 struct xseg_port* xseg_get_port(struct xseg *xseg, uint32_t portno);
431
432
433 extern char* xseg_get_data_nonstatic(struct xseg* xseg, struct xseg_request *req);
434 extern char* xseg_get_target_nonstatic(struct xseg* xseg, struct xseg_request *req);
435
436 static inline uint32_t xseg_portno(struct xseg *xseg, struct xseg_port *port)
437 {
438         return port->portno;
439 }
440 static inline char* xseg_get_target(struct xseg* xseg, struct xseg_request *req)
441 {
442         return (char *) XPTR_TAKE(req->target, xseg->segment);
443 }
444
445 static inline char* xseg_get_data(struct xseg* xseg, struct xseg_request *req)
446 {
447         return (char *) XPTR_TAKE(req->data, xseg->segment);
448 }
449
450 static inline void * xseg_get_signal_desc(struct xseg *xseg, struct xseg_port *port)
451 {
452         return (void *) XPTR_TAKE(port->signal_desc, xseg->segment);
453 }
454
455 struct xobject_h * xseg_get_objh(struct xseg *xseg, uint32_t magic, uint64_t size);
456 void xseg_put_objh(struct xseg *xseg, struct xobject_h *objh);
457
458 #define xseg_get_queue(__xseg, __port, __queue) \
459         ((struct xq *) XPTR_TAKE(__port->__queue, __xseg->segment))
460
461 #endif
462
463 xport xseg_set_srcgw            (struct xseg *xseg, xport portno, xport srcgw);
464 xport xseg_getandset_srcgw      (struct xseg *xseg, xport portno, xport srcgw);
465 xport xseg_set_dstgw            (struct xseg *xseg, xport portno, xport dstgw);
466 xport xseg_getandset_dstgw      (struct xseg *xseg, xport portno, xport dstgw);
467
468 int xseg_set_req_data (struct xseg *xseg, struct xseg_request *xreq, void *data);
469 int xseg_get_req_data (struct xseg *xseg, struct xseg_request *xreq, void **data);
470
471 int xseg_init_local_signal(struct xseg *xseg, xport portno);
472 void xseg_quit_local_signal(struct xseg *xseg, xport portno);
473
474 int xseg_resize_request (struct xseg *xseg, struct xseg_request *req,
475                         uint32_t new_targetlen, uint64_t new_datalen);
476
477 int xseg_set_max_requests(struct xseg *xseg, xport portno, uint64_t nr_reqs);
478 uint64_t xseg_get_max_requests(struct xseg *xseg, xport portno);
479 uint64_t xseg_get_allocated_requests(struct xseg *xseg, xport portno);
480 int xseg_set_freequeue_size(struct xseg *xseg, xport portno, xqindex size,
481                                 uint32_t flags);
482
483