Whamcloud - gitweb
land v0.9.1 on HEAD, in preparation for a 1.0.x branch
[fs/lustre-release.git] / lnet / klnds / gmlnd / gmlnd.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 /*
24  *      Portals GM kernel NAL header file
25  *      This file makes all declaration and prototypes 
26  *      for the API side and CB side of the NAL
27  */
28 #ifndef __INCLUDE_GMNAL_H__
29 #define __INCLUDE_GMNAL_H__
30
31 #ifndef EXPORT_SYMTAB
32 # define EXPORT_SYMTAB
33 #endif
34
35 #include "linux/config.h"
36 #include "linux/module.h"
37 #include "linux/tty.h"
38 #include "linux/kernel.h"
39 #include "linux/mm.h"
40 #include "linux/string.h"
41 #include "linux/stat.h"
42 #include "linux/errno.h"
43 #include "linux/locks.h"
44 #include "linux/unistd.h"
45 #include "linux/init.h"
46 #include "linux/sem.h"
47 #include "linux/vmalloc.h"
48
49 #define DEBUG_SUBSYSTEM S_GMNAL
50
51 #include "portals/nal.h"
52 #include "portals/api.h"
53 #include "portals/errno.h"
54 #include "linux/kp30.h"
55 #include "portals/p30.h"
56
57 #include "portals/lib-nal.h"
58 #include "portals/lib-p30.h"
59
60 #define GM_STRONG_TYPES 1
61 #include "gm.h"
62 #include "gm_internal.h"
63
64
65
66 /*
67  *      Defines for the API NAL
68  */
69
70 /*
71  *      Small message size is configurable
72  *      insmod can set small_msg_size
73  *      which is used to populate nal_data.small_msg_size
74  */
75 #define GMNAL_SMALL_MESSAGE             1078
76 #define GMNAL_LARGE_MESSAGE_INIT        1079
77 #define GMNAL_LARGE_MESSAGE_ACK 1080
78 #define GMNAL_LARGE_MESSAGE_FINI        1081
79
80 extern  int gmnal_small_msg_size;
81 extern  int num_rx_threads;
82 extern  int num_stxds;
83 #define GMNAL_SMALL_MSG_SIZE(a)         a->small_msg_size
84 #define GMNAL_IS_SMALL_MESSAGE(n,a,b,c) gmnal_is_small_msg(n, a, b, c)
85 #define GMNAL_MAGIC                             0x1234abcd
86
87
88 /*
89  *      Small Transmit Descriptor
90  *      A structre to keep track of a small transmit operation
91  *      This structure has a one-to-one relationship with a small
92  *      transmit buffer (both create by gmnal_stxd_alloc). 
93  *      There are two free list of stxd. One for use by clients of the NAL
94  *      and the other by the NAL rxthreads when doing sends. 
95  *      This helps prevent deadlock caused by stxd starvation.
96  */
97 typedef struct _gmnal_stxd_t {
98         void                    *buffer;
99         int                     buffer_size;
100         gm_size_t               gm_size;
101         int                     msg_size;
102         int                     gm_target_node;
103         int                     gm_priority;
104         int                     type;
105         struct _gmnal_data_t    *nal_data;
106         lib_msg_t               *cookie;
107         int                     niov;
108         struct iovec            iov[PTL_MD_MAX_IOV];
109         struct _gmnal_stxd_t    *next;
110         int                     rxt; 
111         int                     kniov;
112         struct iovec            *iovec_dup;
113 } gmnal_stxd_t;
114
115 /*
116  *      keeps a transmit token for large transmit (gm_get)
117  *      and a pointer to rxd that is used as context for large receive
118  */
119 typedef struct _gmnal_ltxd_t {
120         struct _gmnal_ltxd_t    *next;
121         struct  _gmnal_srxd_t  *srxd;
122 } gmnal_ltxd_t;
123
124
125 /*
126  *      as for gmnal_stxd_t 
127  *      a hash table in nal_data find srxds from
128  *      the rx buffer address. hash table populated at init time
129  */
130 typedef struct _gmnal_srxd_t {
131         void                    *buffer;
132         int                     size;
133         gm_size_t               gmsize;
134         unsigned int            gm_source_node;
135         gmnal_stxd_t            *source_stxd;
136         int                     type;
137         int                     nsiov;
138         int                     nriov;
139         struct iovec            *riov;
140         int                     ncallbacks;
141         spinlock_t              callback_lock;
142         int                     callback_status;
143         lib_msg_t               *cookie;
144         struct _gmnal_srxd_t    *next;
145         struct _gmnal_data_t    *nal_data;
146 } gmnal_srxd_t;
147
148 /*
149  *      Header which lmgnal puts at the start of each message
150  */
151 typedef struct  _gmnal_msghdr {
152         int             magic;
153         int             type;
154         unsigned int    sender_node_id;
155         gmnal_stxd_t    *stxd;
156         int             niov;
157         } gmnal_msghdr_t;
158 #define GMNAL_MSGHDR_SIZE       sizeof(gmnal_msghdr_t)
159
160 /*
161  *      the caretaker thread (ct_thread) gets receive events
162  *      (and other events) from the myrinet device via the GM2 API.
163  *      caretaker thread populates one work entry for each receive event,
164  *      puts it on a Q in nal_data and wakes a receive thread to  
165  *      process the receive.  
166  *      Processing a portals receive can involve a transmit operation. 
167  *      Because of this the caretaker thread cannot process receives 
168  *      as it may get deadlocked when supply of transmit descriptors 
169  *      is exhausted (as caretaker thread is responsible for replacing 
170  *      transmit descriptors on the free list)
171  */
172 typedef struct _gmnal_rxtwe {
173         void                    *buffer;
174         unsigned                snode;
175         unsigned                sport;
176         unsigned                type;
177         unsigned                length;
178         struct _gmnal_rxtwe     *next;
179 } gmnal_rxtwe_t;
180
181 /*
182  *      1 receive thread started on each CPU
183  */
184 #define NRXTHREADS 10 /* max number of receiver threads */
185
186 typedef struct _gmnal_data_t {
187         int             refcnt;
188         spinlock_t      cb_lock;
189         spinlock_t      stxd_lock;
190         struct semaphore stxd_token;
191         gmnal_stxd_t    *stxd;
192         spinlock_t      rxt_stxd_lock;
193         struct semaphore rxt_stxd_token;
194         gmnal_stxd_t    *rxt_stxd;
195         spinlock_t      ltxd_lock;
196         struct semaphore ltxd_token;
197         gmnal_ltxd_t    *ltxd;
198         spinlock_t      srxd_lock;
199         struct semaphore srxd_token;
200         gmnal_srxd_t    *srxd;
201         struct gm_hash  *srxd_hash;
202         nal_t           *nal;   
203         nal_cb_t        *nal_cb;
204         struct gm_port  *gm_port;
205         unsigned int    gm_local_nid;
206         unsigned int    gm_global_nid;
207         spinlock_t      gm_lock;
208         long            rxthread_pid[NRXTHREADS];
209         int             rxthread_stop_flag;
210         spinlock_t      rxthread_flag_lock;
211         long            rxthread_flag;
212         long            ctthread_pid;
213         int             ctthread_flag;
214         gm_alarm_t      ctthread_alarm;
215         int             small_msg_size;
216         int             small_msg_gmsize;
217         gmnal_rxtwe_t   *rxtwe_head;
218         gmnal_rxtwe_t   *rxtwe_tail;
219         spinlock_t      rxtwe_lock;
220         struct  semaphore rxtwe_wait;
221 } gmnal_data_t;
222
223 /*
224  *      Flags to start/stop and check status of threads
225  *      each rxthread sets 1 bit (any bit) of the flag on startup
226  *      and clears 1 bit when exiting
227  */
228 #define GMNAL_THREAD_RESET      0
229 #define GMNAL_THREAD_STOP       666
230 #define GMNAL_CTTHREAD_STARTED  333
231 #define GMNAL_RXTHREADS_STARTED ( (1<<num_rx_threads)-1)
232
233
234 extern gmnal_data_t     *global_nal_data;
235
236 /*
237  *      The gm_port to use for gmnal
238  */
239 #define GMNAL_GM_PORT   4
240
241 /*
242  * for ioctl get pid
243  */
244 #define GMNAL_IOC_GET_GNID 1    
245
246 /*
247  *      Return codes
248  */
249 #define GMNAL_STATUS_OK 0
250 #define GMNAL_STATUS_FAIL       1
251 #define GMNAL_STATUS_NOMEM      2
252
253
254 /*
255  *      FUNCTION PROTOTYPES
256  */
257
258 /*
259  *      Locking macros
260  */
261
262 /*
263  *      For the Small tx and rx descriptor lists
264  */
265 #define GMNAL_TXD_LOCK_INIT(a)          spin_lock_init(&a->stxd_lock);
266 #define GMNAL_TXD_LOCK(a)               spin_lock(&a->stxd_lock);
267 #define GMNAL_TXD_UNLOCK(a)             spin_unlock(&a->stxd_lock);
268 #define GMNAL_TXD_TOKEN_INIT(a, n)      sema_init(&a->stxd_token, n);
269 #define GMNAL_TXD_GETTOKEN(a)           down(&a->stxd_token);
270 #define GMNAL_TXD_TRYGETTOKEN(a)        down_trylock(&a->stxd_token)
271 #define GMNAL_TXD_RETURNTOKEN(a)        up(&a->stxd_token);
272
273 #define GMNAL_RXT_TXD_LOCK_INIT(a)      spin_lock_init(&a->rxt_stxd_lock);
274 #define GMNAL_RXT_TXD_LOCK(a)           spin_lock(&a->rxt_stxd_lock);
275 #define GMNAL_RXT_TXD_UNLOCK(a)         spin_unlock(&a->rxt_stxd_lock);
276 #define GMNAL_RXT_TXD_TOKEN_INIT(a, n)  sema_init(&a->rxt_stxd_token, n);
277 #define GMNAL_RXT_TXD_GETTOKEN(a)       down(&a->rxt_stxd_token);
278 #define GMNAL_RXT_TXD_TRYGETTOKEN(a)    down_trylock(&a->rxt_stxd_token)
279 #define GMNAL_RXT_TXD_RETURNTOKEN(a)    up(&a->rxt_stxd_token);
280
281 #define GMNAL_LTXD_LOCK_INIT(a)         spin_lock_init(&a->ltxd_lock);
282 #define GMNAL_LTXD_LOCK(a)              spin_lock(&a->ltxd_lock);
283 #define GMNAL_LTXD_UNLOCK(a)            spin_unlock(&a->ltxd_lock);
284 #define GMNAL_LTXD_TOKEN_INIT(a, n)     sema_init(&a->ltxd_token, n);
285 #define GMNAL_LTXD_GETTOKEN(a)          down(&a->ltxd_token);
286 #define GMNAL_LTXD_TRYGETTOKEN(a)       down_trylock(&a->ltxd_token)
287 #define GMNAL_LTXD_RETURNTOKEN(a)       up(&a->ltxd_token);
288
289 #define GMNAL_RXD_LOCK_INIT(a)          spin_lock_init(&a->srxd_lock);
290 #define GMNAL_RXD_LOCK(a)               spin_lock(&a->srxd_lock);
291 #define GMNAL_RXD_UNLOCK(a)             spin_unlock(&a->srxd_lock);
292 #define GMNAL_RXD_TOKEN_INIT(a, n)      sema_init(&a->srxd_token, n);
293 #define GMNAL_RXD_GETTOKEN(a)           down(&a->srxd_token);
294 #define GMNAL_RXD_TRYGETTOKEN(a)        down_trylock(&a->srxd_token)
295 #define GMNAL_RXD_RETURNTOKEN(a)        up(&a->srxd_token);
296
297 #define GMNAL_GM_LOCK_INIT(a)           spin_lock_init(&a->gm_lock);
298 #define GMNAL_GM_LOCK(a)                spin_lock(&a->gm_lock);
299 #define GMNAL_GM_UNLOCK(a)              spin_unlock(&a->gm_lock);
300 #define GMNAL_CB_LOCK_INIT(a)           spin_lock_init(&a->cb_lock);
301
302
303 /*
304  *      Memory Allocator
305  */
306
307 /*
308  *      API NAL
309  */
310 int gmnal_api_forward(nal_t *, int, void *, size_t, void *, size_t);
311
312 int gmnal_api_shutdown(nal_t *, int);
313
314 int gmnal_api_validate(nal_t *, void *, size_t);
315
316 void gmnal_api_yield(nal_t *);
317
318 void gmnal_api_lock(nal_t *, unsigned long *);
319
320 void gmnal_api_unlock(nal_t *, unsigned long *);
321
322
323 #define GMNAL_INIT_NAL(a)       do {    \
324                                 a->forward = gmnal_api_forward; \
325                                 a->shutdown = gmnal_api_shutdown; \
326                                 a->validate = NULL; \
327                                 a->yield = gmnal_api_yield; \
328                                 a->lock = gmnal_api_lock; \
329                                 a->unlock = gmnal_api_unlock; \
330                                 a->timeout = NULL; \
331                                 a->refct = 1; \
332                                 a->nal_data = NULL; \
333                                 } while (0)
334
335
336 /*
337  *      CB NAL
338  */
339
340 int gmnal_cb_send(nal_cb_t *, void *, lib_msg_t *, ptl_hdr_t *,
341         int, ptl_nid_t, ptl_pid_t, unsigned int, struct iovec *, size_t);
342
343 int gmnal_cb_send_pages(nal_cb_t *, void *, lib_msg_t *, ptl_hdr_t *,
344         int, ptl_nid_t, ptl_pid_t, unsigned int, ptl_kiov_t *, size_t);
345
346 int gmnal_cb_recv(nal_cb_t *, void *, lib_msg_t *, 
347         unsigned int, struct iovec *, size_t, size_t);
348
349 int gmnal_cb_recv_pages(nal_cb_t *, void *, lib_msg_t *, 
350         unsigned int, ptl_kiov_t *, size_t, size_t);
351
352 int gmnal_cb_read(nal_cb_t *, void *private, void *, user_ptr, size_t);
353
354 int gmnal_cb_write(nal_cb_t *, void *private, user_ptr, void *, size_t);
355
356 int gmnal_cb_callback(nal_cb_t *, void *, lib_eq_t *, ptl_event_t *);
357
358 void *gmnal_cb_malloc(nal_cb_t *, size_t);
359
360 void gmnal_cb_free(nal_cb_t *, void *, size_t);
361
362 void gmnal_cb_unmap(nal_cb_t *, unsigned int, struct iovec*, void **);
363
364 int  gmnal_cb_map(nal_cb_t *, unsigned int, struct iovec*, void **); 
365
366 void gmnal_cb_printf(nal_cb_t *, const char *fmt, ...);
367
368 void gmnal_cb_cli(nal_cb_t *, unsigned long *);
369
370 void gmnal_cb_sti(nal_cb_t *, unsigned long *);
371
372 int gmnal_cb_dist(nal_cb_t *, ptl_nid_t, unsigned long *);
373
374 nal_t *gmnal_init(int, ptl_pt_index_t, ptl_ac_index_t, ptl_pid_t rpid);
375
376 void  gmnal_fini(void);
377
378
379
380 #define GMNAL_INIT_NAL_CB(a)    do {    \
381                                 a->cb_send = gmnal_cb_send; \
382                                 a->cb_send_pages = gmnal_cb_send_pages; \
383                                 a->cb_recv = gmnal_cb_recv; \
384                                 a->cb_recv_pages = gmnal_cb_recv_pages; \
385                                 a->cb_read = gmnal_cb_read; \
386                                 a->cb_write = gmnal_cb_write; \
387                                 a->cb_callback = gmnal_cb_callback; \
388                                 a->cb_malloc = gmnal_cb_malloc; \
389                                 a->cb_free = gmnal_cb_free; \
390                                 a->cb_map = NULL; \
391                                 a->cb_unmap = NULL; \
392                                 a->cb_printf = gmnal_cb_printf; \
393                                 a->cb_cli = gmnal_cb_cli; \
394                                 a->cb_sti = gmnal_cb_sti; \
395                                 a->cb_dist = gmnal_cb_dist; \
396                                 a->nal_data = NULL; \
397                                 } while (0)
398
399
400 /*
401  *      Small and Large Transmit and Receive Descriptor Functions
402  */
403 int             gmnal_alloc_txd(gmnal_data_t *);
404 void            gmnal_free_txd(gmnal_data_t *);
405 gmnal_stxd_t*   gmnal_get_stxd(gmnal_data_t *, int);
406 void            gmnal_return_stxd(gmnal_data_t *, gmnal_stxd_t *);
407 gmnal_ltxd_t*   gmnal_get_ltxd(gmnal_data_t *);
408 void            gmnal_return_ltxd(gmnal_data_t *, gmnal_ltxd_t *);
409
410 int             gmnal_alloc_srxd(gmnal_data_t *);
411 void            gmnal_free_srxd(gmnal_data_t *);
412 gmnal_srxd_t*   gmnal_get_srxd(gmnal_data_t *, int);
413 void            gmnal_return_srxd(gmnal_data_t *, gmnal_srxd_t *);
414
415 /*
416  *      general utility functions
417  */
418 gmnal_srxd_t    *gmnal_rxbuffer_to_srxd(gmnal_data_t *, void*);
419 void            gmnal_stop_rxthread(gmnal_data_t *);
420 void            gmnal_stop_ctthread(gmnal_data_t *);
421 void            gmnal_small_tx_callback(gm_port_t *, void *, gm_status_t);
422 void            gmnal_drop_sends_callback(gm_port_t *, void *, gm_status_t);
423 char            *gmnal_gm_error(gm_status_t);
424 char            *gmnal_rxevent(gm_recv_event_t*);
425 int             gmnal_is_small_msg(gmnal_data_t*, int, struct iovec*, int);
426 void            gmnal_yield(int);
427 int             gmnal_start_kernel_threads(gmnal_data_t *);
428
429
430 /*
431  *      Communication functions
432  */
433
434 /*
435  *      Receive threads
436  */
437 int             gmnal_ct_thread(void *); /* caretaker thread */
438 int             gmnal_rx_thread(void *); /* receive thread */
439 int             gmnal_pre_receive(gmnal_data_t*, gmnal_rxtwe_t*, int);
440 int             gmnal_rx_bad(gmnal_data_t *, gmnal_rxtwe_t *, gmnal_srxd_t*);
441 int             gmnal_rx_requeue_buffer(gmnal_data_t *, gmnal_srxd_t *);
442 int             gmnal_add_rxtwe(gmnal_data_t *, gm_recv_t *);
443 gmnal_rxtwe_t * gmnal_get_rxtwe(gmnal_data_t *);
444 void            gmnal_remove_rxtwe(gmnal_data_t *);
445
446
447 /*
448  *      Small messages
449  */
450 int             gmnal_small_rx(nal_cb_t *, void *, lib_msg_t *, unsigned int, 
451                                 struct iovec *, size_t, size_t);
452 int             gmnal_small_tx(nal_cb_t *, void *, lib_msg_t *, ptl_hdr_t *, 
453                                 int, ptl_nid_t, ptl_pid_t, 
454                                 unsigned int, struct iovec*, int);
455 void            gmnal_small_tx_callback(gm_port_t *, void *, gm_status_t);
456
457
458
459 /*
460  *      Large messages
461  */
462 int             gmnal_large_rx(nal_cb_t *, void *, lib_msg_t *, unsigned int, 
463                                 struct iovec *, size_t, size_t);
464
465 int             gmnal_large_tx(nal_cb_t *, void *, lib_msg_t *, ptl_hdr_t *, 
466                                 int, ptl_nid_t, ptl_pid_t, unsigned int, 
467                                 struct iovec*, int);
468
469 void            gmnal_large_tx_callback(gm_port_t *, void *, gm_status_t);
470
471 int             gmnal_remote_get(gmnal_srxd_t *, int, struct iovec*, int, 
472                                   struct iovec*);
473
474 void            gmnal_remote_get_callback(gm_port_t *, void *, gm_status_t);
475
476 int             gmnal_copyiov(int, gmnal_srxd_t *, int, struct iovec*, int, 
477                                struct iovec*);
478
479 void            gmnal_large_tx_ack(gmnal_data_t *, gmnal_srxd_t *);
480 void            gmnal_large_tx_ack_callback(gm_port_t *, void *, gm_status_t);
481 void            gmnal_large_tx_ack_received(gmnal_data_t *, gmnal_srxd_t *);
482
483 #endif /*__INCLUDE_GMNAL_H__*/