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