Whamcloud - gitweb
Portals NAL for Myrinet GM2 for Lustre (lgmnal)
[fs/lustre-release.git] / lnet / klnds / lgmlnd / lgmnal.h
1 /*
2  * This program was prepared by the Regents of the University of
3  * California at Los Alamos National Laboratory (the University) under 
4  * contract number W-7405-ENG-36 with the U.S. Department of Energy
5  * (DoE). Neither the U.S. Government nor the
6  * University makes any warranty, express or implied, or assumes any
7  * liability or responsibility for the use of this software.
8  */
9
10 /*
11  *      Portals GM kernel NAL header file
12  *      This file makes all declaration and prototypes 
13  *      for the API side and CB side of the NAL
14  */
15 #ifndef __INCLUDE_LGMNAL_H__
16 #define __INCLUDE_LGMNAL_H__
17
18 #include "linux/config.h"
19 #include "linux/module.h"
20 #include "linux/tty.h"
21 #include "linux/kernel.h"
22 #include "linux/mm.h"
23 #include "linux/string.h"
24 #include "linux/stat.h"
25 #include "linux/errno.h"
26 #include "linux/locks.h"
27 #include "linux/unistd.h"
28 #include "linux/init.h"
29 #include "linux/sem.h"
30 #include "linux/vmalloc.h"
31 #ifdef MODVERSIONS
32 #include <linux/modversions.h>
33 #endif
34
35
36 #include "portals/nal.h"
37 #include "portals/api.h"
38 #include "portals/errno.h"
39 #include "linux/kp30.h"
40 #include "portals/p30.h"
41
42 #include "portals/lib-nal.h"
43 #include "portals/lib-p30.h"
44
45 #define GM_STRONG_TYPES 1
46 #include "gm.h"
47 #include "gm_internal.h"
48
49
50 /*
51  *      Defines for the API NAL
52  */
53
54
55
56 /*
57  *      Small message size is configurable
58  *      insmod can set small_msg_size
59  *      which is used to populate nal_data.small_msg_size
60  */
61 #define LGMNAL_SMALL_MESSAGE            1078
62 #define LGMNAL_LARGE_MESSAGE_INIT       1079
63 #define LGMNAL_LARGE_MESSAGE_ACK        1080
64 #define LGMNAL_LARGE_MESSAGE_FINI       1081
65
66 extern  int lgmnal_small_msg_size;
67 #define LGMNAL_SMALL_MSG_SIZE(a)        a->small_msg_size
68 #define LGMNAL_IS_SMALL_MESSAGE(n,a,b,c)        lgmnal_is_small_message(n, a, b, c)
69 #define LGMNAL_MAGIC    0x1234abcd
70
71 typedef struct _lgmnal_hash {
72                 void *key;
73                 void *data;
74                 struct _lgmnal_hash     *next;
75         } lgmnal_hash_t;
76
77 /*
78  *      Small Transmit Descriptor
79  *      A structre to keep track of a small transmit operation
80  *      This structure has a one-to-one relationship with a small
81  *      transmit buffer (both create by lgmnal_stxd_alloc). 
82  *      stxd has pointer to txbuffer and the hash table in nal_data
83  *      allows us to go the other way.
84  */
85 typedef struct _lgmnal_stxd_t {
86         void    *buffer;                /* Address of small wired buffer this decriptor uses */
87         int     size;                   /* size (in bytes) of the tx buffer this descripto uses */
88         gm_size_t       gmsize;         /* gmsize of the tx buffer this descripto uses */
89         int     type;                   /* large or small message */
90         struct _lgmnal_data_t *nal_data;
91         lib_msg_t       *cookie;        /* the cookie the portals library gave us */
92         int     niov;
93         struct iovec    iov[PTL_MD_MAX_IOV];
94         struct _lgmnal_stxd_t   *next;
95 } lgmnal_stxd_t;
96
97 /*
98  *      as for lgmnal_stxd_t 
99  */
100 typedef struct _lgmnal_srxd_t {
101         void    *buffer;
102         int     size;
103         gm_size_t       gmsize;
104         int     type;
105         struct _lgmnal_srxd_t   *next;
106 } lgmnal_srxd_t;
107
108 /*
109  *      Header which lmgnal puts at the start of each message
110  */
111 typedef struct  _lgmnal_msghdr {
112         int     magic;
113         int     type;
114         unsigned int    sender_node_id;
115         lgmnal_stxd_t   *stxd;
116         } lgmnal_msghdr_t;
117 #define LGMNAL_MSGHDR_SIZE      sizeof(lgmnal_msghdr_t)
118
119 /* 
120  *      There's one of these for each interface that is initialised
121  *      There's a maximum of LGMNAL_NUM_IF lgmnal_data_t
122  */
123
124 typedef struct _lgmnal_data_t {
125         int     refcnt;
126 #ifdef LGMNAL_API_LOCK_SPIN
127         spinlock_t      api_lock;       /* lock provided for api->lock function */
128 #else
129         struct semaphore api_lock;
130 #endif
131         spinlock_t      cb_lock;        /* lock provided for cb_cli function */
132         char            _cb_file[128];
133         char            _cb_function[128];
134         int             _cb_line;
135         spinlock_t      stxd_lock;      /* lock to add or remove stxd to/from free list */
136         struct semaphore stxd_token;    /* Don't try to access the list until get a token */
137         lgmnal_stxd_t   *stxd;          /* list of free stxd's */
138 #ifdef LGMNAL_USE_GM_HASH
139         struct gm_hash  *stxd_hash;     /* hash to translate txbuffer to stxd. Created in stxd_alloc */
140 #else
141         lgmnal_hash_t   *stxd_hash;     /* hash to translate txbuffer to stxd. Created in stxd_alloc */
142 #endif
143         spinlock_t      srxd_lock;
144         struct semaphore srxd_token;
145         lgmnal_srxd_t   *srxd;
146 #ifdef LGMNAL_USE_GM_HASH
147         struct gm_hash  *srxd_hash;
148 #else
149         lgmnal_hash_t   *srxd_hash;
150 #endif
151         nal_t           *nal;           /* our API NAL */
152         nal_cb_t        *nal_cb;        /* our CB nal */
153         struct gm_port  *gm_port;       /* the gm port structure we open in lgmnal_init */
154         unsigned int    gm_local_nid;   /* our gm local node id */
155         unsigned int    gm_global_nid;  /* our gm global node id */
156         spinlock_t      gm_lock;        /* GM is not threadsage */
157         long            rxthread_pid;   /* thread id of our receiver thread */
158         int             rxthread_flag;  /* stop the thread flag */
159         gm_alarm_t      rxthread_alarm; /* used to wake sleeping rx thread */
160         int             small_msg_size;
161         int             small_msg_gmsize;
162         char            _file[128];
163         char            _function[128];
164         int             _line;
165 } lgmnal_data_t;
166
167 /*
168  *      For nal_data->rxthread_flag
169  */
170 #define LGMNAL_THREAD_START     444     
171 #define LGMNAL_THREAD_STARTED   333
172 #define LGMNAL_THREAD_CONTINUE  777
173 #define LGMNAL_THREAD_STOP      666
174 #define LGMNAL_THREAD_STOPPED   555
175
176 #define LGMNAL_NUM_IF   1
177
178 #if 0
179 /*
180  *      A global structre to maintain 1 nal_data structure for each 
181  *      myrinet card that the user initialises (only tested for 1)
182  *      To add or remove any nal_data structures from the ifs arrary the 
183  *      init_lock must be acquired. This is the only time this lock is acquired
184  */
185 typedef struct _lgmnal_global_t {
186         int     debug_level;
187         struct  semaphore       init_lock;
188         lgmnal_data_t           *ifs[LGMNAL_NUM_IF];
189 } lgmnal_global_t;
190
191 extern lgmnal_data_t    global_nal_data;
192 #define LGMNAL_DEBUG_LEVEL      lgmnal_global.debug_level
193 #else
194 extern lgmnal_data_t    *global_nal_data;
195 extern int      lgmnal_debug_level;
196 #define LGMNAL_DEBUG_LEVEL      lgmnal_debug_level
197 #endif
198
199 /*
200  *      The gm_port to use for lgmnal
201  */
202 #define LGMNAL_GM_PORT  4
203
204 /*
205  * for ioctl get pid
206  */
207 #define LGMNAL_IOC_GET_GNID 1   
208
209 /*
210  *      LGMNAL_DEBUG_LEVEL set by module load 0<debug_level<4
211  *      Increase it to get more debug info
212  */     
213
214 #define LGMNAL_DEBUG 1
215 #ifdef LGMNAL_DEBUG
216 #define LGMNAL_PRINT(level, args)       if (LGMNAL_DEBUG_LEVEL >= level) lgmnal_print args
217 #else
218 #define LGMNAL_PRINT(level, args)
219 #endif
220
221 #define LGMNAL_DEBUG_ERR 1      /* only report errors */
222 #define LGMNAL_DEBUG_TRACE 2    /* on entering function */
223 #define LGMNAL_DEBUG_V 3        /* debug */
224 #define LGMNAL_DEBUG_VV 4       /* more debug */
225
226 /*
227  *      Return codes
228  */
229 #define LGMNAL_STATUS_OK        0
230 #define LGMNAL_STATUS_FAIL      1
231 #define LGMNAL_STATUS_NOMEM     2
232
233
234 /*
235  *      FUNCTION PROTOTYPES
236  */
237
238 /*
239  *      Locking macros
240  */
241
242 /*
243  *      To access the global structure
244  *      to add or remove interface (lgmnal_init) or shutdown only
245  */
246 #define LGMNAL_GLOBAL_LOCK_INIT sema_init(&(lgmnal_global.init_lock), 1)
247 #define LGMNAL_GLOBAL_LOCK      do {    \
248                                 LGMNAL_PRINT(1, ("Acquiring global mutex\n")); \
249                                 down(&(lgmnal_global.init_lock)); \
250                                 LGMNAL_PRINT(1, ("Got global lock\n")); \
251                                 } while (0)
252 #define LGMNAL_GLOBAL_UNLOCK    do {            \
253                                 LGMNAL_PRINT(1, ("Releasing global mutex\n")); \
254                                 up(&(lgmnal_global.init_lock)); \
255                                 LGMNAL_PRINT(1, ("Release global mutex\n")); \
256                                 } while (0)
257
258 /*
259  *      For the API lock function
260  */
261 #ifdef LGMNAL_API_LOCK_SPIN
262 #define LGMNAL_API_LOCK_INIT(a)         spin_lock_init(&a->api_lock)
263 #define LGMNAL_API_LOCK(a)              spin_lock(&a->api_lock)
264 #define LGMNAL_API_UNLOCK(a)            spin_unlock(&a->api_lock)
265 #else
266 #define LGMNAL_API_LOCK_INIT(a)         sema_init(&a->api_lock, 1)
267 #define LGMNAL_API_LOCK(a)              down(&a->api_lock)
268 #define LGMNAL_API_UNLOCK(a)            up(&a->api_lock)
269 #endif
270
271 /*
272  *      For the Small tx and rx descriptor lists
273  */
274 #define LGMNAL_TXD_LOCK_INIT(a)                 spin_lock_init(&a->stxd_lock);
275 #define LGMNAL_TXD_LOCK(a)                      spin_lock(&a->stxd_lock);
276 #define LGMNAL_TXD_UNLOCK(a)                    spin_unlock(&a->stxd_lock);
277 #define LGMNAL_TXD_TOKEN_INIT(a, n)             sema_init(&a->stxd_token, n);
278 #define LGMNAL_TXD_GETTOKEN(a)                  down(&a->stxd_token);
279 #define LGMNAL_TXD_TRYGETTOKEN(a)               down_trylock(&a->stxd_token)
280 #define LGMNAL_TXD_RETURNTOKEN(a)               up(&a->stxd_token);
281
282
283 #define LGMNAL_RXD_LOCK_INIT(a)                 spin_lock_init(&a->srxd_lock);
284 #define LGMNAL_RXD_LOCK(a)                      spin_lock(&a->srxd_lock);
285 #define LGMNAL_RXD_UNLOCK(a)                    spin_unlock(&a->srxd_lock);
286 #define LGMNAL_RXD_TOKEN_INIT(a, n)             sema_init(&a->srxd_token, n);
287 #define LGMNAL_RXD_GETTOKEN(a)                  down(&a->srxd_token);
288 #define LGMNAL_RXD_TRYGETTOKEN(a)               down_trylock(&a->srxd_token)
289 #define LGMNAL_RXD_RETURNTOKEN(a)               up(&a->srxd_token);
290
291 #define LGMNAL_GM_LOCK_INIT(a)                  spin_lock_init(&a->gm_lock);
292 #define LGMNAL_GM_LOCK(a)                       do { \
293                                                         while (!spin_trylock(&a->gm_lock)) { \
294                                                                 LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("waiting %s:%s:%d holder %s:%s:%d\n", __FUNCTION__, __FILE__, __LINE__, nal_data->_function, nal_data->_file, nal_data->_line)); \
295                                                                 lgmnal_yield(128); \
296                                                         } \
297                                                                 LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("GM Locked %s:%s:%d\n", __FUNCTION__, __FILE__, __LINE__)); \
298                                                                 sprintf(nal_data->_function, "%s", __FUNCTION__); \
299                                                                 sprintf(nal_data->_file, "%s", __FILE__); \
300                                                                 nal_data->_line = __LINE__; \
301                                                 } while (0)
302 #define LGMNAL_GM_UNLOCK(a)                     do { \
303                                                         spin_unlock(&a->gm_lock); \
304                                                         memset(nal_data->_function, 0, 128); \
305                                                         memset(nal_data->_file, 0, 128); \
306                                                         nal_data->_line = 0; \
307                                                         LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("GM Unlocked %s:%s:%d\n", __FUNCTION__, __FILE__, __LINE__)); \
308                                                 } while(0);
309
310 #define LGMNAL_CB_LOCK_INIT(a)                  spin_lock_init(&a->cb_lock);
311
312
313 /*
314  *      API NAL
315  */
316 int lgmnal_api_forward(nal_t *, int, void *, size_t, void *, size_t);
317
318 int lgmnal_api_shutdown(nal_t *, int);
319
320 int lgmnal_api_validate(nal_t *, void *, size_t);
321
322 void lgmnal_api_yield(nal_t *);
323
324 void lgmnal_api_lock(nal_t *, unsigned long *);
325
326 void lgmnal_api_unlock(nal_t *, unsigned long *);
327
328
329 #define LGMNAL_INIT_NAL(a)      do {    \
330                                 a->forward = lgmnal_api_forward; \
331                                 a->shutdown = lgmnal_api_shutdown; \
332                                 a->validate = NULL; \
333                                 a->yield = lgmnal_api_yield; \
334                                 a->lock = lgmnal_api_lock; \
335                                 a->unlock = lgmnal_api_unlock; \
336                                 a->timeout = NULL; \
337                                 a->refct = 1; \
338                                 a->nal_data = NULL; \
339                                 } while (0)
340
341
342 /*
343  *      CB NAL
344  */
345
346 int lgmnal_cb_send(nal_cb_t *, void *, lib_msg_t *, ptl_hdr_t *,
347         int, ptl_nid_t, ptl_pid_t, unsigned int, struct iovec *, size_t);
348
349 int lgmnal_cb_send_pages(nal_cb_t *, void *, lib_msg_t *, ptl_hdr_t *,
350         int, ptl_nid_t, ptl_pid_t, unsigned int, ptl_kiov_t *, size_t);
351
352 int lgmnal_cb_recv(nal_cb_t *, void *, lib_msg_t *, 
353         unsigned int, struct iovec *, size_t, size_t);
354
355 int lgmnal_cb_recv_pages(nal_cb_t *, void *, lib_msg_t *, 
356         unsigned int, ptl_kiov_t *, size_t, size_t);
357
358 int lgmnal_cb_read(nal_cb_t *, void *private, void *, user_ptr, size_t);
359
360 int lgmnal_cb_write(nal_cb_t *, void *private, user_ptr, void *, size_t);
361
362 int lgmnal_cb_callback(nal_cb_t *, void *, lib_eq_t *, ptl_event_t *);
363
364 void *lgmnal_cb_malloc(nal_cb_t *, size_t);
365
366 void lgmnal_cb_free(nal_cb_t *, void *, size_t);
367
368 void lgmnal_cb_unmap(nal_cb_t *, unsigned int, struct iovec*, void **);
369
370 int  lgmnal_cb_map(nal_cb_t *, unsigned int, struct iovec*, void **); 
371
372 void lgmnal_cb_printf(nal_cb_t *, const char *fmt, ...);
373
374 void lgmnal_cb_cli(nal_cb_t *, unsigned long *);
375
376 void lgmnal_cb_sti(nal_cb_t *, unsigned long *);
377
378 int lgmnal_cb_dist(nal_cb_t *, ptl_nid_t, unsigned long *);
379
380 nal_t *lgmnal_init(int, ptl_pt_index_t, ptl_ac_index_t, ptl_pid_t rpid);
381
382 void  lgmnal_fini(void);
383
384
385
386 #define LGMNAL_INIT_NAL_CB(a)   do {    \
387                                 a->cb_send = lgmnal_cb_send; \
388                                 a->cb_send_pages = lgmnal_cb_send_pages; \
389                                 a->cb_recv = lgmnal_cb_recv; \
390                                 a->cb_recv_pages = lgmnal_cb_recv_pages; \
391                                 a->cb_read = lgmnal_cb_read; \
392                                 a->cb_write = lgmnal_cb_write; \
393                                 a->cb_callback = lgmnal_cb_callback; \
394                                 a->cb_malloc = lgmnal_cb_malloc; \
395                                 a->cb_free = lgmnal_cb_free; \
396                                 a->cb_map = NULL; \
397                                 a->cb_unmap = NULL; \
398                                 a->cb_printf = lgmnal_cb_printf; \
399                                 a->cb_cli = lgmnal_cb_cli; \
400                                 a->cb_sti = lgmnal_cb_sti; \
401                                 a->cb_dist = lgmnal_cb_dist; \
402                                 a->nal_data = NULL; \
403                                 } while (0)
404
405 /*
406  *      lgmnal utilities
407  */
408
409 void lgmnal_print(const char *, ...);
410
411 /*
412  *      Small Transmit and Receive Descriptor Functions
413  */
414 int  lgmnal_alloc_stxd(lgmnal_data_t *);
415 void lgmnal_free_stxd(lgmnal_data_t *);
416 lgmnal_stxd_t* lgmnal_get_stxd(lgmnal_data_t *, int);
417 void lgmnal_return_stxd(lgmnal_data_t *, lgmnal_stxd_t *);
418
419 int  lgmnal_alloc_srxd(lgmnal_data_t *);
420 void lgmnal_free_srxd(lgmnal_data_t *);
421 lgmnal_srxd_t* lgmnal_get_srxd(lgmnal_data_t *, int);
422 void lgmnal_return_srxd(lgmnal_data_t *, lgmnal_srxd_t *);
423
424 /*
425  *      general utility functions
426  */
427 lgmnal_srxd_t   *lgmnal_rxbuffer_to_srxd(lgmnal_data_t *, void*);
428 lgmnal_stxd_t   *lgmnal_txbuffer_to_stxd(lgmnal_data_t *, void*);
429 void    lgmnal_stop_rxthread(lgmnal_data_t *);
430 void    lgmnal_small_tx_done(gm_port_t *, void *, gm_status_t);
431 char    *lgmnal_gm_error(gm_status_t);
432 char    *lgmnal_rxevent(gm_recv_event_t*);
433 int     lgmnal_is_small_message(lgmnal_data_t*, int, struct iovec*, int);
434
435 void *lgmnal_hash_find(lgmnal_hash_t *, void*);
436 int lgmnal_hash_add(lgmnal_hash_t**, void*, void*);
437 void lgmnal_hash_free(lgmnal_hash_t**);
438
439 /*
440  *      Communication functions
441  */
442 int lgmnal_receive_thread(void *);
443 int
444 lgmnal_small_transmit(nal_cb_t *, void *, lib_msg_t *, ptl_hdr_t *, int, ptl_nid_t, ptl_pid_t, unsigned int, struct iovec*, int);
445
446 int
447 lgmnal_small_receive2(nal_cb_t *, void *, lib_msg_t *, unsigned int, struct iovec *, size_t, size_t);
448
449 void lgmnal_yield(int);
450
451 #endif /*__INCLUDE_LGMNAL_H__*/