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.
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
15 #ifndef __INCLUDE_LGMNAL_H__
16 #define __INCLUDE_LGMNAL_H__
18 #include "linux/config.h"
19 #include "linux/module.h"
20 #include "linux/tty.h"
21 #include "linux/kernel.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"
32 #include <linux/modversions.h>
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"
42 #include "portals/lib-nal.h"
43 #include "portals/lib-p30.h"
45 #define GM_STRONG_TYPES 1
47 #include "gm_internal.h"
51 * Defines for the API NAL
57 * Small message size is configurable
58 * insmod can set small_msg_size
59 * which is used to populate nal_data.small_msg_size
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
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
71 typedef struct _lgmnal_hash {
74 struct _lgmnal_hash *next;
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.
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 */
93 struct iovec iov[PTL_MD_MAX_IOV];
94 struct _lgmnal_stxd_t *next;
98 * as for lgmnal_stxd_t
100 typedef struct _lgmnal_srxd_t {
105 struct _lgmnal_srxd_t *next;
109 * Header which lmgnal puts at the start of each message
111 typedef struct _lgmnal_msghdr {
114 unsigned int sender_node_id;
117 #define LGMNAL_MSGHDR_SIZE sizeof(lgmnal_msghdr_t)
120 * There's one of these for each interface that is initialised
121 * There's a maximum of LGMNAL_NUM_IF lgmnal_data_t
124 typedef struct _lgmnal_data_t {
126 #ifdef LGMNAL_API_LOCK_SPIN
127 spinlock_t api_lock; /* lock provided for api->lock function */
129 struct semaphore api_lock;
131 spinlock_t cb_lock; /* lock provided for cb_cli function */
133 char _cb_function[128];
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 */
141 lgmnal_hash_t *stxd_hash; /* hash to translate txbuffer to stxd. Created in stxd_alloc */
143 spinlock_t srxd_lock;
144 struct semaphore srxd_token;
146 #ifdef LGMNAL_USE_GM_HASH
147 struct gm_hash *srxd_hash;
149 lgmnal_hash_t *srxd_hash;
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 */
161 int small_msg_gmsize;
168 * For nal_data->rxthread_flag
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
176 #define LGMNAL_NUM_IF 1
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
185 typedef struct _lgmnal_global_t {
187 struct semaphore init_lock;
188 lgmnal_data_t *ifs[LGMNAL_NUM_IF];
191 extern lgmnal_data_t global_nal_data;
192 #define LGMNAL_DEBUG_LEVEL lgmnal_global.debug_level
194 extern lgmnal_data_t *global_nal_data;
195 extern int lgmnal_debug_level;
196 #define LGMNAL_DEBUG_LEVEL lgmnal_debug_level
200 * The gm_port to use for lgmnal
202 #define LGMNAL_GM_PORT 4
207 #define LGMNAL_IOC_GET_GNID 1
210 * LGMNAL_DEBUG_LEVEL set by module load 0<debug_level<4
211 * Increase it to get more debug info
214 #define LGMNAL_DEBUG 1
216 #define LGMNAL_PRINT(level, args) if (LGMNAL_DEBUG_LEVEL >= level) lgmnal_print args
218 #define LGMNAL_PRINT(level, args)
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 */
229 #define LGMNAL_STATUS_OK 0
230 #define LGMNAL_STATUS_FAIL 1
231 #define LGMNAL_STATUS_NOMEM 2
235 * FUNCTION PROTOTYPES
243 * To access the global structure
244 * to add or remove interface (lgmnal_init) or shutdown only
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")); \
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")); \
259 * For the API lock function
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)
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)
272 * For the Small tx and rx descriptor lists
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);
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);
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)); \
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__; \
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__)); \
310 #define LGMNAL_CB_LOCK_INIT(a) spin_lock_init(&a->cb_lock);
316 int lgmnal_api_forward(nal_t *, int, void *, size_t, void *, size_t);
318 int lgmnal_api_shutdown(nal_t *, int);
320 int lgmnal_api_validate(nal_t *, void *, size_t);
322 void lgmnal_api_yield(nal_t *);
324 void lgmnal_api_lock(nal_t *, unsigned long *);
326 void lgmnal_api_unlock(nal_t *, unsigned long *);
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; \
338 a->nal_data = NULL; \
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);
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);
352 int lgmnal_cb_recv(nal_cb_t *, void *, lib_msg_t *,
353 unsigned int, struct iovec *, size_t, size_t);
355 int lgmnal_cb_recv_pages(nal_cb_t *, void *, lib_msg_t *,
356 unsigned int, ptl_kiov_t *, size_t, size_t);
358 int lgmnal_cb_read(nal_cb_t *, void *private, void *, user_ptr, size_t);
360 int lgmnal_cb_write(nal_cb_t *, void *private, user_ptr, void *, size_t);
362 int lgmnal_cb_callback(nal_cb_t *, void *, lib_eq_t *, ptl_event_t *);
364 void *lgmnal_cb_malloc(nal_cb_t *, size_t);
366 void lgmnal_cb_free(nal_cb_t *, void *, size_t);
368 void lgmnal_cb_unmap(nal_cb_t *, unsigned int, struct iovec*, void **);
370 int lgmnal_cb_map(nal_cb_t *, unsigned int, struct iovec*, void **);
372 void lgmnal_cb_printf(nal_cb_t *, const char *fmt, ...);
374 void lgmnal_cb_cli(nal_cb_t *, unsigned long *);
376 void lgmnal_cb_sti(nal_cb_t *, unsigned long *);
378 int lgmnal_cb_dist(nal_cb_t *, ptl_nid_t, unsigned long *);
380 nal_t *lgmnal_init(int, ptl_pt_index_t, ptl_ac_index_t, ptl_pid_t rpid);
382 void lgmnal_fini(void);
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; \
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; \
409 void lgmnal_print(const char *, ...);
412 * Small Transmit and Receive Descriptor Functions
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 *);
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 *);
425 * general utility functions
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);
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**);
440 * Communication functions
442 int lgmnal_receive_thread(void *);
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);
447 lgmnal_small_receive2(nal_cb_t *, void *, lib_msg_t *, unsigned int, struct iovec *, size_t, size_t);
449 void lgmnal_yield(int);
451 #endif /*__INCLUDE_LGMNAL_H__*/