1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (c) 2003 Los Alamos National Laboratory (LANL)
6 * This file is part of Lustre, http://www.lustre.org/
8 * This file is free software; you can redistribute it and/or
9 * modify it under the terms of version 2.1 of the GNU Lesser General
10 * Public License as published by the Free Software Foundation.
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 Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with Portals; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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
27 #ifndef __INCLUDE_LGMNAL_H__
28 #define __INCLUDE_LGMNAL_H__
30 #include "linux/config.h"
31 #include "linux/module.h"
32 #include "linux/tty.h"
33 #include "linux/kernel.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"
44 #include <linux/modversions.h>
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"
54 #include "portals/lib-nal.h"
55 #include "portals/lib-p30.h"
57 #define GM_STRONG_TYPES 1
59 #include "gm_internal.h"
63 * Defines for the API NAL
69 * Small message size is configurable
70 * insmod can set small_msg_size
71 * which is used to populate nal_data.small_msg_size
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
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
83 typedef struct _lgmnal_hash {
86 struct _lgmnal_hash *next;
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.
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 */
105 struct iovec iov[PTL_MD_MAX_IOV];
106 struct _lgmnal_stxd_t *next;
110 * as for lgmnal_stxd_t
112 typedef struct _lgmnal_srxd_t {
117 struct _lgmnal_srxd_t *next;
121 * Header which lmgnal puts at the start of each message
123 typedef struct _lgmnal_msghdr {
126 unsigned int sender_node_id;
129 #define LGMNAL_MSGHDR_SIZE sizeof(lgmnal_msghdr_t)
132 * There's one of these for each interface that is initialised
133 * There's a maximum of LGMNAL_NUM_IF lgmnal_data_t
136 typedef struct _lgmnal_data_t {
138 #ifdef LGMNAL_API_LOCK_SPIN
139 spinlock_t api_lock; /* lock provided for api->lock function */
141 struct semaphore api_lock;
143 spinlock_t cb_lock; /* lock provided for cb_cli function */
145 char _cb_function[128];
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 */
153 lgmnal_hash_t *stxd_hash; /* hash to translate txbuffer to stxd. Created in stxd_alloc */
155 spinlock_t srxd_lock;
156 struct semaphore srxd_token;
158 #ifdef LGMNAL_USE_GM_HASH
159 struct gm_hash *srxd_hash;
161 lgmnal_hash_t *srxd_hash;
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 */
173 int small_msg_gmsize;
180 * For nal_data->rxthread_flag
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
188 #define LGMNAL_NUM_IF 1
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
197 typedef struct _lgmnal_global_t {
199 struct semaphore init_lock;
200 lgmnal_data_t *ifs[LGMNAL_NUM_IF];
203 extern lgmnal_data_t global_nal_data;
204 #define LGMNAL_DEBUG_LEVEL lgmnal_global.debug_level
206 extern lgmnal_data_t *global_nal_data;
207 extern int lgmnal_debug_level;
208 #define LGMNAL_DEBUG_LEVEL lgmnal_debug_level
212 * The gm_port to use for lgmnal
214 #define LGMNAL_GM_PORT 4
219 #define LGMNAL_IOC_GET_GNID 1
222 * LGMNAL_DEBUG_LEVEL set by module load 0<debug_level<4
223 * Increase it to get more debug info
226 #define LGMNAL_DEBUG 1
228 #define LGMNAL_PRINT(level, args) if (LGMNAL_DEBUG_LEVEL >= level) lgmnal_print args
230 #define LGMNAL_PRINT(level, args)
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 */
241 #define LGMNAL_STATUS_OK 0
242 #define LGMNAL_STATUS_FAIL 1
243 #define LGMNAL_STATUS_NOMEM 2
247 * FUNCTION PROTOTYPES
255 * To access the global structure
256 * to add or remove interface (lgmnal_init) or shutdown only
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")); \
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")); \
271 * For the API lock function
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)
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)
284 * For the Small tx and rx descriptor lists
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);
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);
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)); \
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__; \
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__)); \
322 #define LGMNAL_CB_LOCK_INIT(a) spin_lock_init(&a->cb_lock);
328 int lgmnal_api_forward(nal_t *, int, void *, size_t, void *, size_t);
330 int lgmnal_api_shutdown(nal_t *, int);
332 int lgmnal_api_validate(nal_t *, void *, size_t);
334 void lgmnal_api_yield(nal_t *);
336 void lgmnal_api_lock(nal_t *, unsigned long *);
338 void lgmnal_api_unlock(nal_t *, unsigned long *);
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; \
350 a->nal_data = NULL; \
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);
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);
364 int lgmnal_cb_recv(nal_cb_t *, void *, lib_msg_t *,
365 unsigned int, struct iovec *, size_t, size_t);
367 int lgmnal_cb_recv_pages(nal_cb_t *, void *, lib_msg_t *,
368 unsigned int, ptl_kiov_t *, size_t, size_t);
370 int lgmnal_cb_read(nal_cb_t *, void *private, void *, user_ptr, size_t);
372 int lgmnal_cb_write(nal_cb_t *, void *private, user_ptr, void *, size_t);
374 int lgmnal_cb_callback(nal_cb_t *, void *, lib_eq_t *, ptl_event_t *);
376 void *lgmnal_cb_malloc(nal_cb_t *, size_t);
378 void lgmnal_cb_free(nal_cb_t *, void *, size_t);
380 void lgmnal_cb_unmap(nal_cb_t *, unsigned int, struct iovec*, void **);
382 int lgmnal_cb_map(nal_cb_t *, unsigned int, struct iovec*, void **);
384 void lgmnal_cb_printf(nal_cb_t *, const char *fmt, ...);
386 void lgmnal_cb_cli(nal_cb_t *, unsigned long *);
388 void lgmnal_cb_sti(nal_cb_t *, unsigned long *);
390 int lgmnal_cb_dist(nal_cb_t *, ptl_nid_t, unsigned long *);
392 nal_t *lgmnal_init(int, ptl_pt_index_t, ptl_ac_index_t, ptl_pid_t rpid);
394 void lgmnal_fini(void);
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; \
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; \
421 void lgmnal_print(const char *, ...);
424 * Small Transmit and Receive Descriptor Functions
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 *);
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 *);
437 * general utility functions
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);
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**);
452 * Communication functions
454 int lgmnal_receive_thread(void *);
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);
459 lgmnal_small_receive2(nal_cb_t *, void *, lib_msg_t *, unsigned int, struct iovec *, size_t, size_t);
461 void lgmnal_yield(int);
463 #endif /*__INCLUDE_LGMNAL_H__*/