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