Whamcloud - gitweb
* Landed portals:b_port_step as follows...
[fs/lustre-release.git] / lnet / include / lnet / lib-types.h
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * p30/lib-types.h
5  *
6  * Types used by the library side routines that do not need to be
7  * exposed to the user application
8  */
9
10 #ifndef __PORTALS_LIB_TYPES_H__
11 #define __PORTALS_LIB_TYPES_H__
12
13 #include "build_check.h"
14
15 #if defined(__linux__)
16 #include <portals/linux/lib-types.h>
17 #elif defined(__APPLE__)
18 #include <portals/darwin/lib-types.h>
19 #else
20 #error Unsupported Operating System
21 #endif
22
23 #include <libcfs/libcfs.h>
24 #include <libcfs/list.h>
25 #include <portals/types.h>
26 #include <portals/nal.h>
27
28 typedef char *user_ptr;
29 typedef struct lib_msg_t lib_msg_t;
30 typedef struct lib_ptl_t lib_ptl_t;
31 typedef struct lib_ac_t lib_ac_t;
32 typedef struct lib_me_t lib_me_t;
33 typedef struct lib_md_t lib_md_t;
34 typedef struct lib_eq_t lib_eq_t;
35
36 #define WIRE_ATTR       __attribute__((packed))
37
38 /* The wire handle's interface cookie only matches one network interface in
39  * one epoch (i.e. new cookie when the interface restarts or the node
40  * reboots).  The object cookie only matches one object on that interface
41  * during that object's lifetime (i.e. no cookie re-use). */
42 typedef struct {
43         __u64 wh_interface_cookie;
44         __u64 wh_object_cookie;
45 } WIRE_ATTR ptl_handle_wire_t;
46
47 /* byte-flip insensitive! */
48 #define PTL_WIRE_HANDLE_NONE \
49 ((const ptl_handle_wire_t) {.wh_interface_cookie = -1, .wh_object_cookie = -1})
50
51 typedef enum {
52         PTL_MSG_ACK = 0,
53         PTL_MSG_PUT,
54         PTL_MSG_GET,
55         PTL_MSG_REPLY,
56         PTL_MSG_HELLO,
57 } ptl_msg_type_t;
58
59 /* The variant fields of the portals message header are aligned on an 8
60  * byte boundary in the message header.  Note that all types used in these
61  * wire structs MUST be fixed size and the smaller types are placed at the
62  * end. */
63 typedef struct ptl_ack {
64         ptl_handle_wire_t  dst_wmd;
65         ptl_match_bits_t   match_bits;
66         ptl_size_t         mlength;
67 } WIRE_ATTR ptl_ack_t;
68
69 typedef struct ptl_put {
70         ptl_handle_wire_t  ack_wmd;
71         ptl_match_bits_t   match_bits;
72         ptl_hdr_data_t     hdr_data;
73         ptl_pt_index_t     ptl_index;
74         ptl_size_t         offset;
75 } WIRE_ATTR ptl_put_t;
76
77 typedef struct ptl_get {
78         ptl_handle_wire_t  return_wmd;
79         ptl_match_bits_t   match_bits;
80         ptl_pt_index_t     ptl_index;
81         ptl_size_t         src_offset;
82         ptl_size_t         sink_length;
83 } WIRE_ATTR ptl_get_t;
84
85 typedef struct ptl_reply {
86         ptl_handle_wire_t  dst_wmd;
87 } WIRE_ATTR ptl_reply_t;
88
89 typedef struct ptl_hello {
90         __u64              incarnation;
91         __u32              type;
92 } WIRE_ATTR ptl_hello_t;
93
94 typedef struct {
95         ptl_nid_t           dest_nid;
96         ptl_nid_t           src_nid;
97         ptl_pid_t           dest_pid;
98         ptl_pid_t           src_pid;
99         __u32               type;               /* ptl_msg_type_t */
100         __u32               payload_length;     /* payload data to follow */
101         /*<------__u64 aligned------->*/
102         union {
103                 ptl_ack_t   ack;
104                 ptl_put_t   put;
105                 ptl_get_t   get;
106                 ptl_reply_t reply;
107                 ptl_hello_t hello;
108         } msg;
109 } WIRE_ATTR ptl_hdr_t;
110
111 /* A HELLO message contains the portals magic number and protocol version
112  * code in the header's dest_nid, the peer's NID in the src_nid, and
113  * PTL_MSG_HELLO in the type field.  All other common fields are zero
114  * (including payload_size; i.e. no payload).  
115  * This is for use by byte-stream NALs (e.g. TCP/IP) to check the peer is
116  * running the same protocol and to find out its NID, so that hosts with
117  * multiple IP interfaces can have a single NID. These NALs should exchange
118  * HELLO messages when a connection is first established. 
119  * Individual NALs can put whatever else they fancy in ptl_hdr_t::msg. 
120  */
121 typedef struct {
122         __u32   magic;                          /* PORTALS_PROTO_MAGIC */
123         __u16   version_major;                  /* increment on incompatible change */
124         __u16   version_minor;                  /* increment on compatible change */
125 } WIRE_ATTR ptl_magicversion_t;
126
127 #define PORTALS_PROTO_MAGIC                0xeebc0ded
128
129 #define PORTALS_PROTO_VERSION_MAJOR        1
130 #define PORTALS_PROTO_VERSION_MINOR        0
131
132 typedef struct {
133         long recv_count, recv_length, send_count, send_length, drop_count,
134             drop_length, msgs_alloc, msgs_max;
135 } lib_counters_t;
136
137 /* temporary expedient: limit number of entries in discontiguous MDs */
138 #define PTL_MTU        (1<<20)
139 #define PTL_MD_MAX_IOV 256
140
141 struct lib_msg_t {
142         struct list_head  msg_list;
143         lib_md_t         *md;
144         ptl_handle_wire_t ack_wmd;
145         ptl_event_t       ev;
146 };
147
148 struct lib_ptl_t {
149         ptl_pt_index_t size;
150         struct list_head *tbl;
151 };
152
153 struct lib_ac_t {
154         int next_free;
155 };
156
157 typedef struct {
158         struct list_head  lh_hash_chain;
159         __u64             lh_cookie;
160 } lib_handle_t;
161
162 #define lh_entry(ptr, type, member) \
163         ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
164
165 struct lib_eq_t {
166         struct list_head  eq_list;
167         lib_handle_t      eq_lh;
168         ptl_seq_t         eq_enq_seq;
169         ptl_seq_t         eq_deq_seq;
170         ptl_size_t        eq_size;
171         ptl_event_t      *eq_events;
172         int               eq_refcount;
173         ptl_eq_handler_t  eq_callback;
174         void             *eq_addrkey;
175 };
176
177 struct lib_me_t {
178         struct list_head  me_list;
179         lib_handle_t      me_lh;
180         ptl_process_id_t  match_id;
181         ptl_match_bits_t  match_bits, ignore_bits;
182         ptl_unlink_t      unlink;
183         lib_md_t         *md;
184 };
185
186 struct lib_md_t {
187         struct list_head  md_list;
188         lib_handle_t      md_lh;
189         lib_me_t         *me;
190         user_ptr          start;
191         ptl_size_t        offset;
192         ptl_size_t        length;
193         ptl_size_t        max_size;
194         int               threshold;
195         int               pending;
196         unsigned int      options;
197         unsigned int      md_flags;
198         void             *user_ptr;
199         lib_eq_t         *eq;
200         void             *md_addrkey;
201         unsigned int      md_niov;                /* # frags */
202         union {
203                 struct iovec  iov[PTL_MD_MAX_IOV];
204                 ptl_kiov_t    kiov[PTL_MD_MAX_IOV];
205         } md_iov;
206 };
207
208 #define PTL_MD_FLAG_ZOMBIE            (1 << 0)
209 #define PTL_MD_FLAG_AUTO_UNLINK       (1 << 1)
210
211 static inline int lib_md_exhausted (lib_md_t *md) 
212 {
213         return (md->threshold == 0 ||
214                 ((md->options & PTL_MD_MAX_SIZE) != 0 &&
215                  md->offset + md->max_size > md->length));
216 }
217
218 #ifdef PTL_USE_LIB_FREELIST
219 typedef struct
220 {
221         void              *fl_objs;             /* single contiguous array of objects */
222         int                fl_nobjs;            /* the number of them */
223         int                fl_objsize;          /* the size (including overhead) of each of them */
224         struct list_head   fl_list;             /* where they are enqueued */
225 } lib_freelist_t;
226
227 typedef struct
228 {
229         struct list_head   fo_list;             /* enqueue on fl_list */
230         void              *fo_contents;         /* aligned contents */
231 } lib_freeobj_t;
232 #endif
233
234 typedef struct {
235         /* info about peers we are trying to fail */
236         struct list_head  tp_list;             /* stash in ni.ni_test_peers */
237         ptl_nid_t         tp_nid;              /* matching nid */
238         unsigned int      tp_threshold;        /* # failures to simulate */
239 } lib_test_peer_t;
240
241 #define PTL_COOKIE_TYPE_MD    1
242 #define PTL_COOKIE_TYPE_ME    2
243 #define PTL_COOKIE_TYPE_EQ    3
244 #define PTL_COOKIE_TYPES      4
245 /* PTL_COOKIE_TYPES must be a power of 2, so the cookie type can be
246  * extracted by masking with (PTL_COOKIE_TYPES - 1) */
247
248 typedef struct lib_ni 
249 {
250         nal_t            *ni_api;
251         ptl_process_id_t  ni_pid;
252         lib_ptl_t         ni_portals;
253         lib_counters_t    ni_counters;
254         ptl_ni_limits_t   ni_actual_limits;
255
256         int               ni_lh_hash_size;      /* size of lib handle hash table */
257         struct list_head *ni_lh_hash_table;     /* all extant lib handles, this interface */
258         __u64             ni_next_object_cookie; /* cookie generator */
259         __u64             ni_interface_cookie;  /* uniquely identifies this ni in this epoch */
260         
261         struct list_head  ni_test_peers;
262         
263 #ifdef PTL_USE_LIB_FREELIST
264         lib_freelist_t    ni_free_mes;
265         lib_freelist_t    ni_free_msgs;
266         lib_freelist_t    ni_free_mds;
267         lib_freelist_t    ni_free_eqs;
268 #endif
269
270         struct list_head  ni_active_msgs;
271         struct list_head  ni_active_mds;
272         struct list_head  ni_active_eqs;
273
274 #ifdef __KERNEL__
275         spinlock_t        ni_lock;
276         cfs_waitq_t       ni_waitq;
277 #else
278         pthread_mutex_t   ni_mutex;
279         pthread_cond_t    ni_cond;
280 #endif
281 } lib_ni_t;
282
283
284 typedef struct lib_nal
285 {
286         /* lib-level interface state */
287         lib_ni_t libnal_ni;
288
289         /* NAL-private data */
290         void *libnal_data;
291
292         /*
293          * send: Sends a preformatted header and payload data to a
294          * specified remote process. The payload is scattered over 'niov'
295          * fragments described by iov, starting at 'offset' for 'mlen'
296          * bytes.  
297          * NB the NAL may NOT overwrite iov.  
298          * PTL_OK on success => NAL has committed to send and will call
299          * lib_finalize on completion
300          */
301         ptl_err_t (*libnal_send) 
302                 (struct lib_nal *nal, void *private, lib_msg_t *cookie, 
303                  ptl_hdr_t *hdr, int type, ptl_nid_t nid, ptl_pid_t pid, 
304                  unsigned int niov, struct iovec *iov, 
305                  size_t offset, size_t mlen);
306         
307         /* as send, but with a set of page fragments (NULL if not supported) */
308         ptl_err_t (*libnal_send_pages)
309                 (struct lib_nal *nal, void *private, lib_msg_t * cookie, 
310                  ptl_hdr_t * hdr, int type, ptl_nid_t nid, ptl_pid_t pid, 
311                  unsigned int niov, ptl_kiov_t *iov, 
312                  size_t offset, size_t mlen);
313         /*
314          * recv: Receives an incoming message from a remote process.  The
315          * payload is to be received into the scattered buffer of 'niov'
316          * fragments described by iov, starting at 'offset' for 'mlen'
317          * bytes.  Payload bytes after 'mlen' up to 'rlen' are to be
318          * discarded.  
319          * NB the NAL may NOT overwrite iov.
320          * PTL_OK on success => NAL has committed to receive and will call
321          * lib_finalize on completion
322          */
323         ptl_err_t (*libnal_recv) 
324                 (struct lib_nal *nal, void *private, lib_msg_t * cookie,
325                  unsigned int niov, struct iovec *iov, 
326                  size_t offset, size_t mlen, size_t rlen);
327
328         /* as recv, but with a set of page fragments (NULL if not supported) */
329         ptl_err_t (*libnal_recv_pages) 
330                 (struct lib_nal *nal, void *private, lib_msg_t * cookie,
331                  unsigned int niov, ptl_kiov_t *iov, 
332                  size_t offset, size_t mlen, size_t rlen);
333
334         /*
335          * (un)map: Tell the NAL about some memory it will access.
336          * *addrkey passed to libnal_unmap() is what libnal_map() set it to.
337          * type of *iov depends on options.
338          * Set to NULL if not required.
339          */
340         ptl_err_t (*libnal_map)
341                 (struct lib_nal *nal, unsigned int niov, struct iovec *iov, 
342                  void **addrkey);
343         void (*libnal_unmap)
344                 (struct lib_nal *nal, unsigned int niov, struct iovec *iov, 
345                  void **addrkey);
346
347         /* as (un)map, but with a set of page fragments */
348         ptl_err_t (*libnal_map_pages)
349                 (struct lib_nal *nal, unsigned int niov, ptl_kiov_t *iov, 
350                  void **addrkey);
351         void (*libnal_unmap_pages)
352                 (struct lib_nal *nal, unsigned int niov, ptl_kiov_t *iov, 
353                  void **addrkey);
354
355         void (*libnal_printf)(struct lib_nal *nal, const char *fmt, ...);
356
357         /* Calculate a network "distance" to given node */
358         int (*libnal_dist) (struct lib_nal *nal, ptl_nid_t nid, unsigned long *dist);
359 } lib_nal_t;
360
361 #endif