2 * Copyright 2012 GRNET S.A. All rights reserved.
4 * Redistribution and use in source and binary forms, with or
5 * without modification, are permitted provided that the following
8 * 1. Redistributions of source code must retain the above
9 * copyright notice, this list of conditions and the following
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.
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.
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.
39 #define XSEG_VERSION 2012022601
42 #ifndef XSEG_PAGE_SHIFT
43 #define XSEG_PAGE_SHIFT 12
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)
55 #include <xtypes/xq.h>
56 #include <xtypes/xobj.h>
57 #include <xtypes/xhash.h>
58 #include <xtypes/xpool.h>
60 typedef uint64_t xserial;
61 typedef uint32_t xport;
63 #define NoSerial ((xserial)-1)
64 #define NoPort ((xport) -1)
67 #define XSEG_DEF_REQS 256
70 #ifndef XSEG_DEF_MAX_ALLOCATED_REQS
71 #define XSEG_DEF_MAX_ALLOCATED_REQS 1024
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
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"
85 #if XSEG_DEF_REQS > XSEG_MAX_ALLOCATED_REQS
86 #error "XSEG_DEF_REQS should me less than XSEG_MAX_ALLOCATED_REQS"
90 #define MAX_PATH_LEN 32
93 #define XSEG_NAMESIZE 256
94 #define XSEG_TNAMESIZE 32
98 * Segments are memory segments shared among peers.
99 * Peers are local execution contexes that share a segment.
101 * xseg_type and xseg_peer
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.
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.
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.
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.
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)
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);
144 struct xseg_operations ops;
145 char name[XSEG_TNAMESIZE];
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);
172 struct xseg_peer_operations peer_ops;
173 char name[XSEG_TNAMESIZE];
177 uint64_t heap_size; /* heap size in MB */
179 uint32_t page_shift; /* the alignment unit */
180 char type[XSEG_TNAMESIZE]; /* zero-terminated identifier */
181 char name[XSEG_NAMESIZE]; /* zero-terminated identifier */
185 struct xlock fq_lock;
186 struct xlock rq_lock;
187 struct xlock pq_lock;
194 uint64_t max_alloc_reqs;
196 struct xlock port_lock;
205 struct xseg_request *req;
208 xqindex __alloced_deps;
228 #define X_SNAPSHOT 16
232 #define XF_NOSYNC (1 << 0)
233 #define XF_FLUSH (1 << 1)
234 #define XF_FUA (1 << 2)
235 #define XF_FORCE (1 << 3)
236 #define XF_CONTADDR (1 << 4)
240 #define CAN_ACCEPT (1 << 0)
241 #define CAN_RECEIVE (1 << 1)
244 #define XS_SERVED (1 << 0)
245 #define XS_FAILED (1 << 1)
247 #define XS_ACCEPTED (1 << 2)
248 #define XS_PENDING (2 << 2)
249 #define XS_SERVING (3 << 2)
250 #define XS_CONCLUDED (3 << 2)
252 struct xseg_request {
262 volatile uint32_t state;
265 xport transit_portno;
267 xport effective_dst_portno;
269 xqindex path_bufs[MAX_PATH_LEN];
275 struct timeval timestamp;
281 char (*peer_types)[XSEG_TNAMESIZE]; /* alignment? */
282 xptr *peer_type_data;
283 uint32_t nr_peer_types;
286 struct xseg_private {
287 struct xseg_type segment_type;
288 struct xseg_peer peer_type;
289 struct xseg_peer **peer_types;
290 void **peer_type_data;
291 uint32_t max_peer_types;
292 void (*wakeup)(uint32_t portno);
294 struct xlock reqdatalock;
297 struct xseg_counters {
298 uint64_t avg_req_lat;
304 uint64_t segment_size;
305 struct xseg *segment;
307 struct xobject_h *object_handlers;
309 struct xobject_h *request_h;
310 struct xobject_h *port_h;
312 xport *path_next, *dst_gw;
314 struct xseg_shared *shared;
315 struct xseg_private *priv;
316 uint32_t max_peer_types;
317 struct xseg_config config;
318 struct xseg_counters counters;
321 #define XSEG_F_LOCK 0x1
323 /* ================= XSEG REQUEST INTERFACE ================================= */
324 /* ___________________ _________ */
326 int xseg_initialize ( void );
328 int xseg_finalize ( void );
330 int xseg_parse_spec ( char * spec,
331 struct xseg_config * config );
333 struct xseg_port * xseg_bind_port ( struct xseg * xseg,
337 static uint32_t xseg_portno ( struct xseg * xseg,
338 struct xseg_port * port );
339 /* \___________________/ \_________/ */
340 /* ___________________ _________ */
342 int xseg_register_type ( struct xseg_type * type );
343 int xseg_unregister_type ( const char * name );
345 int xseg_register_peer ( struct xseg_peer * peer );
346 int xseg_unregister_peer ( const char * name );
348 void xseg_report_peer_types( void );
350 int64_t xseg_enable_driver ( struct xseg * xseg,
352 int xseg_disable_driver ( struct xseg * xseg,
354 /* \___________________/ \_________/ */
355 /* ___________________ _________ */
357 int xseg_create ( struct xseg_config * cfg );
359 void xseg_destroy ( struct xseg * xseg );
360 /* \___________________/ \_________/ */
361 /* ___________________ _________ */
363 struct xseg * xseg_join ( char * segtype,
369 void xseg_leave ( struct xseg * xseg );
370 /* \___________________/ \_________/ */
371 /* ___________________ _________ */
373 int xseg_alloc_requests ( struct xseg * xseg,
377 int xseg_free_requests ( struct xseg * xseg,
381 struct xseg_request * xseg_get_request ( struct xseg * xseg,
386 int xseg_put_request ( struct xseg * xseg,
387 struct xseg_request * xreq,
390 int xseg_prep_request ( struct xseg * xseg,
391 struct xseg_request * xreq,
394 /* \___________________/ \_________/ */
395 /* ___________________ _________ */
397 xport xseg_submit ( struct xseg * xseg,
398 struct xseg_request * xreq,
402 struct xseg_request * xseg_receive ( struct xseg * xseg,
405 /* \___________________/ \_________/ */
406 /* ___________________ _________ */
409 struct xseg_request * xseg_accept ( struct xseg * xseg,
413 xport xseg_respond ( struct xseg * xseg,
414 struct xseg_request * xreq,
417 /* \___________________/ \_________/ */
418 /* ___________________ _________ */
420 int xseg_prepare_wait ( struct xseg * xseg,
423 int xseg_cancel_wait ( struct xseg * xseg,
426 int xseg_wait_signal ( struct xseg * xseg,
429 int xseg_signal ( struct xseg * xseg,
431 /* \___________________/ \_________/ */
436 /* ================= XSEG REQUEST INTERFACE ================================= */
438 struct xseg_port* xseg_get_port(struct xseg *xseg, uint32_t portno);
441 extern char* xseg_get_data_nonstatic(struct xseg* xseg, struct xseg_request *req);
442 extern char* xseg_get_target_nonstatic(struct xseg* xseg, struct xseg_request *req);
444 static inline uint32_t xseg_portno(struct xseg *xseg, struct xseg_port *port)
448 static inline char* xseg_get_target(struct xseg* xseg, struct xseg_request *req)
450 return (char *) XPTR_TAKE(req->target, xseg->segment);
453 static inline char* xseg_get_data(struct xseg* xseg, struct xseg_request *req)
455 return (char *) XPTR_TAKE(req->data, xseg->segment);
458 static inline void * xseg_get_signal_desc(struct xseg *xseg, struct xseg_port *port)
460 return (void *) XPTR_TAKE(port->signal_desc, xseg->segment);
463 struct xobject_h * xseg_get_objh(struct xseg *xseg, uint32_t magic, uint64_t size);
464 void xseg_put_objh(struct xseg *xseg, struct xobject_h *objh);
466 #define xseg_get_queue(__xseg, __port, __queue) \
467 ((struct xq *) XPTR_TAKE(__port->__queue, __xseg->segment))
470 int xseg_set_path_next(struct xseg *xseg, xport portno, xport next);
472 int xseg_set_req_data(struct xseg *xseg, struct xseg_request *xreq, void *data);
473 int xseg_get_req_data(struct xseg *xseg, struct xseg_request *xreq, void **data);
475 int xseg_init_local_signal(struct xseg *xseg, xport portno);
476 void xseg_quit_local_signal(struct xseg *xseg, xport portno);
478 int xseg_resize_request (struct xseg *xseg, struct xseg_request *req,
479 uint32_t new_targetlen, uint64_t new_datalen);
481 int xseg_set_max_requests(struct xseg *xseg, xport portno, uint64_t nr_reqs);
482 uint64_t xseg_get_max_requests(struct xseg *xseg, xport portno);
483 uint64_t xseg_get_allocated_requests(struct xseg *xseg, xport portno);
484 int xseg_set_freequeue_size(struct xseg *xseg, xport portno, xqindex size,
487 xport xseg_forward(struct xseg *xseg, struct xseg_request *req, xport new_dst,
488 xport portno, uint32_t flags);