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;
204 struct xseg_request *req;
207 xqindex __alloced_deps;
227 #define X_SNAPSHOT 16
230 #define XF_NOSYNC (1 << 0)
231 #define XF_FLUSH (1 << 1)
232 #define XF_FUA (1 << 2)
233 #define XF_FORCE (1 << 3)
236 #define XS_SERVED (1 << 0)
237 #define XS_FAILED (1 << 1)
239 #define XS_ACCEPTED (1 << 2)
240 #define XS_PENDING (2 << 2)
241 #define XS_SERVING (3 << 2)
242 #define XS_CONCLUDED (3 << 2)
244 struct xseg_request {
254 volatile uint32_t state;
257 xport src_transit_portno;
259 xport dst_transit_portno;
261 xqindex path_bufs[MAX_PATH_LEN];
267 struct timeval timestamp;
273 char (*peer_types)[XSEG_TNAMESIZE]; /* alignment? */
274 xptr *peer_type_data;
275 uint32_t nr_peer_types;
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);
286 struct xlock reqdatalock;
289 struct xseg_counters {
290 uint64_t avg_req_lat;
296 uint64_t segment_size;
297 struct xseg *segment;
299 struct xobject_h *object_handlers;
301 struct xobject_h *request_h;
302 struct xobject_h *port_h;
304 xport *src_gw, *dst_gw;
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;
313 #define XSEG_F_LOCK 0x1
315 /* ================= XSEG REQUEST INTERFACE ================================= */
316 /* ___________________ _________ */
318 int xseg_initialize ( void );
320 int xseg_finalize ( void );
322 int xseg_parse_spec ( char * spec,
323 struct xseg_config * config );
325 struct xseg_port * xseg_bind_port ( struct xseg * xseg,
329 static uint32_t xseg_portno ( struct xseg * xseg,
330 struct xseg_port * port );
331 /* \___________________/ \_________/ */
332 /* ___________________ _________ */
334 int xseg_register_type ( struct xseg_type * type );
335 int xseg_unregister_type ( const char * name );
337 int xseg_register_peer ( struct xseg_peer * peer );
338 int xseg_unregister_peer ( const char * name );
340 void xseg_report_peer_types( void );
342 int64_t xseg_enable_driver ( struct xseg * xseg,
344 int xseg_disable_driver ( struct xseg * xseg,
346 /* \___________________/ \_________/ */
347 /* ___________________ _________ */
349 int xseg_create ( struct xseg_config * cfg );
351 void xseg_destroy ( struct xseg * xseg );
352 /* \___________________/ \_________/ */
353 /* ___________________ _________ */
355 struct xseg * xseg_join ( char * segtype,
361 void xseg_leave ( struct xseg * xseg );
362 /* \___________________/ \_________/ */
363 /* ___________________ _________ */
365 int xseg_alloc_requests ( struct xseg * xseg,
369 int xseg_free_requests ( struct xseg * xseg,
373 struct xseg_request * xseg_get_request ( struct xseg * xseg,
378 int xseg_put_request ( struct xseg * xseg,
379 struct xseg_request * xreq,
382 int xseg_prep_request ( struct xseg * xseg,
383 struct xseg_request * xreq,
386 /* \___________________/ \_________/ */
387 /* ___________________ _________ */
389 xport xseg_submit ( struct xseg * xseg,
390 struct xseg_request * xreq,
394 struct xseg_request * xseg_receive ( struct xseg * xseg,
397 /* \___________________/ \_________/ */
398 /* ___________________ _________ */
401 struct xseg_request * xseg_accept ( struct xseg * xseg,
405 xport xseg_respond ( struct xseg * xseg,
406 struct xseg_request * xreq,
409 /* \___________________/ \_________/ */
410 /* ___________________ _________ */
412 int xseg_prepare_wait ( struct xseg * xseg,
415 int xseg_cancel_wait ( struct xseg * xseg,
418 int xseg_wait_signal ( struct xseg * xseg,
421 int xseg_signal ( struct xseg * xseg,
423 /* \___________________/ \_________/ */
428 /* ================= XSEG REQUEST INTERFACE ================================= */
430 struct xseg_port* xseg_get_port(struct xseg *xseg, uint32_t portno);
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);
436 static inline uint32_t xseg_portno(struct xseg *xseg, struct xseg_port *port)
440 static inline char* xseg_get_target(struct xseg* xseg, struct xseg_request *req)
442 return (char *) XPTR_TAKE(req->target, xseg->segment);
445 static inline char* xseg_get_data(struct xseg* xseg, struct xseg_request *req)
447 return (char *) XPTR_TAKE(req->data, xseg->segment);
450 static inline void * xseg_get_signal_desc(struct xseg *xseg, struct xseg_port *port)
452 return (void *) XPTR_TAKE(port->signal_desc, xseg->segment);
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);
458 #define xseg_get_queue(__xseg, __port, __queue) \
459 ((struct xq *) XPTR_TAKE(__port->__queue, __xseg->segment))
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);
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);
471 int xseg_init_local_signal(struct xseg *xseg, xport portno);
472 void xseg_quit_local_signal(struct xseg *xseg, xport portno);
474 int xseg_resize_request (struct xseg *xseg, struct xseg_request *req,
475 uint32_t new_targetlen, uint64_t new_datalen);
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,