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