Whamcloud - gitweb
Portals NAL for Myrinet GM2 for Lustre (lgmnal)
[fs/lustre-release.git] / lnet / klnds / lgmlnd / lgmnal_api.c
1
2 /*
3  * This program was prepared by the Regents of the University of
4  * California at Los Alamos National Laboratory (the University) under 
5  * contract number W-7405-ENG-36 with the U.S. Department of Energy
6  * (DoE). Neither the U.S. Government nor the
7  * University makes any warranty, express or implied, or assumes any
8  * liability or responsibility for the use of this software.
9  */
10
11
12
13 /*
14  *      Implements the API NAL functions
15  */
16
17 #include "lgmnal.h"
18
19 lgmnal_data_t   *global_nal_data = NULL;
20 /*
21  *      lgmnal_api_forward
22  *      This function takes a pack block of arguments from the NAL API
23  *      module and passes them to the NAL CB module. The CB module unpacks
24  *      the args and calls the appropriate function indicated by index.
25  *      Typically this function is used to pass args between kernel and use
26  *      space.
27  *      As lgmanl exists entirely in kernel, just pass the arg block directly to
28  *      the NAL CB, buy passing the args to lib_dispatch
29  *      Arguments are
30  *      nal_t   nal     Our nal
31  *      int     index   the api function that initiated this call 
32  *      void    *args   packed block of function args
33  *      size_t  arg_len length of args block
34  *      void    *ret    A return value for the API NAL
35  *      size_t  ret_len Size of the return value
36  *      
37  */
38
39 int
40 lgmnal_api_forward(nal_t *nal, int index, void *args, size_t arg_len,
41                 void *ret, size_t ret_len)
42 {
43
44         nal_cb_t        *nal_cb = NULL;
45         lgmnal_data_t   *nal_data = NULL;
46
47
48
49
50         LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_api_forward: nal [%p], index [%d], args [%p], arglen [%d], ret [%p], retlen [%d]\n", nal, index, args, arg_len, ret, ret_len));
51
52         if (!nal || !args || (index < 0) || (arg_len < 0)) {
53                         LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Bad args to lgmnal_api_forward\n"));
54 #ifdef LGMNAL_DEBUG
55                 if (!nal)
56                         LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("No nal specified\n"));
57                 if (!args)
58                         LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("No args specified\n"));
59                 if (index < 0)
60                         LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Index is negative[%d]\n", index));
61                 if (arg_len < 0)
62                         LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("arg_len is negative [%d]\n", arg_len));
63 #endif
64                 return (PTL_FAIL);
65         }
66
67         if (ret && (ret_len <= 0)) {
68                 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Bad args to lgmnal_api_forward\n"));
69 #ifdef LGMNAL_DEBUG
70                 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("ret_len is [%d]\n", ret_len));
71 #endif
72                 return (PTL_FAIL);
73         }
74
75
76         if (!nal->nal_data) {
77                 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("bad nal, no nal data\n"));     
78                 return (PTL_FAIL);
79         }
80         
81         nal_data = nal->nal_data;
82         LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("nal_data is [%p]\n", nal_data));        
83
84         if (!nal_data->nal_cb) {
85                 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("bad nal_data, no nal_cb\n"));  
86                 return (PTL_FAIL);
87         }
88         
89         nal_cb = nal_data->nal_cb;
90         LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("nal_cb is [%p]\n", nal_cb));    
91         
92         LGMNAL_PRINT(LGMNAL_DEBUG_V, ("lgmnal_api_forward calling lib_dispatch\n"));
93         lib_dispatch(nal_cb, NULL, index, args, ret);
94         LGMNAL_PRINT(LGMNAL_DEBUG_V, ("lgmnal_api_forward returns from lib_dispatch\n"));
95
96         return(PTL_OK);
97 }
98
99
100 /*
101  *      lgmnal_api_shutdown
102  *      Close down this interface and free any resources associated with it
103  *      nal_t   nal     our nal to shutdown
104  */
105 int
106 lgmnal_api_shutdown(nal_t *nal, int interface)
107 {
108
109         lgmnal_data_t   *nal_data = nal->nal_data;
110
111         LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_api_shutdown: nal_data [%p]\n", nal_data));
112
113         /*
114          *      TO DO   lgmnal_api_shutdown what is to be done?
115          */
116
117         return(PTL_OK);
118 }
119
120
121 /*
122  *      lgmnal_api_validate
123  *      validate a user address for use in communications
124  *      There's nothing to be done here
125  */
126 int
127 lgmnal_api_validate(nal_t *nal, void *base, size_t extent)
128 {
129
130         LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_api_validate : nal [%p], base [%p], extent [%d]\n", nal, base, extent));
131
132         return(PTL_OK);
133 }
134
135
136
137 /*
138  *      lgmnal_api_yield
139  *      Give up the processor
140  */
141 void
142 lgmnal_api_yield(nal_t *nal)
143 {
144         LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_api_yield : nal [%p]\n", nal));
145
146         set_current_state(TASK_INTERRUPTIBLE);
147         schedule();
148
149         return;
150 }
151
152
153
154 /*
155  *      lgmnal_api_lock
156  *      Take a threadsafe lock
157  */
158 void
159 lgmnal_api_lock(nal_t *nal, unsigned long *flags)
160 {
161
162         lgmnal_data_t   *nal_data;
163         nal_cb_t        *nal_cb;
164         LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_api_lock : nal [%p], flagsa [%p] flags[%ul]\n", nal, flags, *flags));
165
166         nal_data = nal->nal_data;
167         nal_cb = nal_data->nal_cb;
168
169         nal_cb->cb_cli(nal_cb, flags);
170 /*
171         LGMNAL_API_LOCK(nal_data);
172 */
173
174         return;
175 }
176
177 /*
178  *      lgmnal_api_unlock
179  *      Release a threadsafe lock
180  */
181 void
182 lgmnal_api_unlock(nal_t *nal, unsigned long *flags)
183 {
184         lgmnal_data_t   *nal_data;
185         nal_cb_t        *nal_cb;
186         LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_api_lock : nal [%p], flags [%p]\n", nal, flags));
187
188         nal_data = nal->nal_data;
189         if (!nal_data) {
190                 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("lgmnal_api_unlock bad nal, no nal_data\n"));
191         }
192         nal_cb = nal_data->nal_cb;
193         if (!nal_cb) {
194                 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("lgmnal_api_unlock bad nal_data, no nal_cb\n"));
195         }
196
197         nal_cb->cb_sti(nal_cb, flags);
198 /*
199         LGMNAL_API_UNLOCK(nal_data);
200 */
201
202         return;
203 }
204
205
206 nal_t *
207 lgmnal_init(int interface, ptl_pt_index_t ptl_size, ptl_ac_index_t ac_size, ptl_pid_t rpid)
208 {
209
210         nal_t           *nal = NULL;
211         nal_cb_t        *nal_cb = NULL;
212         lgmnal_data_t   *nal_data = NULL;
213         lgmnal_srxd_t   *srxd = NULL;
214         gm_status_t     gm_status;
215         unsigned int    local_nid = 0, global_nid = 0;
216         ptl_nid_t       portals_nid;
217         ptl_pid_t       portals_pid = 0;
218
219
220         LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_init : interface [%d], ptl_size [%d], ac_size[%d]\n",
221                         interface, ptl_size, ac_size));
222
223         if ((interface < 0) || (interface > LGMNAL_NUM_IF) || (ptl_size <= 0) || (ac_size <= 0) ) {
224                 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("bad args\n"));
225                 return(NULL);
226         } else {
227                 LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("parameters check out ok\n"));
228         }
229
230         LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Acquired global lock\n"));
231
232
233         PORTAL_ALLOC(nal_data, sizeof(lgmnal_data_t));
234         if (!nal_data) {
235                 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("can't get memory\n"));
236                 return(NULL);
237         }       
238         memset(nal_data, 0, sizeof(lgmnal_data_t));
239         /*
240          *      set the small message buffer size 
241          */
242         nal_data->refcnt = 1;
243
244         LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Allocd and reset nal_data[%p]\n", nal_data));
245         LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("small_msg_size is [%d]\n", nal_data->small_msg_size));
246
247         PORTAL_ALLOC(nal, sizeof(nal_t));
248         if (!nal) {
249                 PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));
250                 return(NULL);
251         }
252         memset(nal, 0, sizeof(nal_t));
253         LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Allocd and reset nal[%p]\n", nal));
254
255         PORTAL_ALLOC(nal_cb, sizeof(nal_cb_t));
256         if (!nal_cb) {
257                 PORTAL_FREE(nal, sizeof(nal_t));
258                 PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));
259                 return(NULL);
260         }
261         memset(nal_cb, 0, sizeof(nal_cb_t));
262         LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Allocd and reset nal_cb[%p]\n", nal_cb));
263
264         LGMNAL_INIT_NAL(nal);
265         LGMNAL_INIT_NAL_CB(nal_cb);
266         /*
267          *      String them all together
268          */
269         nal->nal_data = (void*)nal_data;
270         nal_cb->nal_data = (void*)nal_data;
271         nal_data->nal = nal;
272         nal_data->nal_cb = nal_cb;
273
274         LGMNAL_API_LOCK_INIT(nal_data);
275         LGMNAL_CB_LOCK_INIT(nal_data);
276         LGMNAL_GM_LOCK_INIT(nal_data);
277
278
279         /*
280          *      initialise the interface, 
281          */
282         LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Calling gm_init\n"));
283         if (gm_init() != GM_SUCCESS) {
284                 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("call to gm_init failed\n"));
285                 PORTAL_FREE(nal, sizeof(nal_t));        
286                 PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));   
287                 PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
288                 return(NULL);
289         }
290
291
292         LGMNAL_PRINT(LGMNAL_DEBUG_V, ("Calling gm_open with interface [%d], port [%d], name [%s], version [%d]\n", interface, LGMNAL_GM_PORT, "lgmnal", GM_API_VERSION));
293
294         LGMNAL_GM_LOCK(nal_data);
295         gm_status = gm_open(&nal_data->gm_port, 0, LGMNAL_GM_PORT, "lgmnal", GM_API_VERSION);
296         LGMNAL_GM_UNLOCK(nal_data);
297
298         LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("gm_open returned [%d]\n", gm_status));
299         if (gm_status == GM_SUCCESS) {
300                 LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("gm_open succeeded port[%p]\n", nal_data->gm_port));
301         } else {
302                 switch(gm_status) {
303                 case(GM_INVALID_PARAMETER):
304                         LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("gm_open Failure. Invalid Parameter\n"));
305                         break;
306                 case(GM_BUSY):
307                         LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("gm_open Failure. GM Busy\n"));
308                         break;
309                 case(GM_NO_SUCH_DEVICE):
310                         LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("gm_open Failure. No such device\n"));
311                         break;
312                 case(GM_INCOMPATIBLE_LIB_AND_DRIVER):
313                         LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("gm_open Failure. Incompatile lib and driver\n"));
314                         break;
315                 case(GM_OUT_OF_MEMORY):
316                         LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("gm_open Failure. Out of Memory\n"));
317                         break;
318                 default:
319                         LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("gm_open Failure. Unknow error code [%d]\n", gm_status));
320                         break;
321                 }       
322                 LGMNAL_GM_LOCK(nal_data);
323                 gm_finalize();
324                 LGMNAL_GM_UNLOCK(nal_data);
325                 PORTAL_FREE(nal, sizeof(nal_t));        
326                 PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));   
327                 PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
328                 return(NULL);
329         }
330
331         
332         nal_data->small_msg_size = lgmnal_small_msg_size;
333         nal_data->small_msg_gmsize = gm_min_size_for_length(lgmnal_small_msg_size);
334
335         if (lgmnal_alloc_srxd(nal_data) != LGMNAL_STATUS_OK) {
336                 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Failed to allocate small rx descriptors\n"));
337                 lgmnal_free_stxd(nal_data);
338                 LGMNAL_GM_LOCK(nal_data);
339                 gm_close(nal_data->gm_port);
340                 gm_finalize();
341                 LGMNAL_GM_UNLOCK(nal_data);
342                 PORTAL_FREE(nal, sizeof(nal_t));        
343                 PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));   
344                 PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
345                 return(NULL);
346         }
347
348
349         /*
350          *      Hang out a bunch of small receive buffers
351          *      In fact hang them all out
352          */
353         while((srxd = lgmnal_get_srxd(nal_data, 0))) {
354                 LGMNAL_PRINT(LGMNAL_DEBUG_V, ("giving [%p] to gm_provide_recvive_buffer\n", srxd->buffer));
355                 LGMNAL_GM_LOCK(nal_data);
356                 gm_provide_receive_buffer_with_tag(nal_data->gm_port, srxd->buffer, 
357                                                                         srxd->gmsize, GM_LOW_PRIORITY, 0);
358                 LGMNAL_GM_UNLOCK(nal_data);
359         }
360         
361         /*
362          *      Allocate pools of small tx buffers and descriptors
363          */
364         if (lgmnal_alloc_stxd(nal_data) != LGMNAL_STATUS_OK) {
365                 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Failed to allocate small tx descriptors\n"));
366                 LGMNAL_GM_LOCK(nal_data);
367                 gm_close(nal_data->gm_port);
368                 gm_finalize();
369                 LGMNAL_GM_UNLOCK(nal_data);
370                 PORTAL_FREE(nal, sizeof(nal_t));        
371                 PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));   
372                 PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
373                 return(NULL);
374         }
375
376         /*
377          *      Start the recieve thread
378          *      Initialise the gm_alarm we will use to wake the thread is 
379          *      it needs to be stopped
380          */
381         LGMNAL_PRINT(LGMNAL_DEBUG_V, ("Initializing receive thread alarm and flag\n"));
382         gm_initialize_alarm(&nal_data->rxthread_alarm);
383         nal_data->rxthread_flag = LGMNAL_THREAD_START;
384
385
386         LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Starting receive thread\n"));
387         nal_data->rxthread_pid = kernel_thread(lgmnal_receive_thread, (void*)nal_data, 0);
388         if (nal_data->rxthread_pid <= 0) {
389                 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Receive thread failed to start\n"));
390                 lgmnal_free_stxd(nal_data);
391                 lgmnal_free_srxd(nal_data);
392                 LGMNAL_GM_LOCK(nal_data);
393                 gm_close(nal_data->gm_port);
394                 gm_finalize();
395                 LGMNAL_GM_UNLOCK(nal_data);
396                 PORTAL_FREE(nal, sizeof(nal_t));        
397                 PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));   
398                 PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
399                 return(NULL);
400         }
401         while (nal_data->rxthread_flag != LGMNAL_THREAD_STARTED) {
402                 set_current_state(TASK_INTERRUPTIBLE);
403                 schedule_timeout(1024);
404                 LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Waiting for receive thread signs of life\n"));
405         }
406         LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("receive thread seems to have started\n"));
407         nal_data->rxthread_flag = LGMNAL_THREAD_CONTINUE;
408
409
410
411         /*
412          *      Initialise the portals library
413          */
414         LGMNAL_PRINT(LGMNAL_DEBUG_V, ("Getting node id\n"));
415         LGMNAL_GM_LOCK(nal_data);
416         gm_status = gm_get_node_id(nal_data->gm_port, &local_nid);
417         LGMNAL_GM_UNLOCK(nal_data);
418         if (gm_status != GM_SUCCESS) {
419                 lgmnal_stop_rxthread(nal_data);
420                 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("can't determine node id\n"));
421                 lgmnal_free_stxd(nal_data);
422                 lgmnal_free_srxd(nal_data);
423                 LGMNAL_GM_LOCK(nal_data);
424                 gm_close(nal_data->gm_port);
425                 gm_finalize();
426                 LGMNAL_GM_UNLOCK(nal_data);
427                 PORTAL_FREE(nal, sizeof(nal_t));        
428                 PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));   
429                 PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
430                 return(NULL);
431         }
432         nal_data->gm_local_nid = local_nid;
433         LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Local node id is [%u]\n", local_nid));
434         LGMNAL_GM_LOCK(nal_data);
435         gm_status = gm_node_id_to_global_id(nal_data->gm_port, local_nid, &global_nid);
436         LGMNAL_GM_UNLOCK(nal_data);
437         if (gm_status != GM_SUCCESS) {
438                 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("failed to obtain global id\n"));
439                 lgmnal_stop_rxthread(nal_data);
440                 lgmnal_free_stxd(nal_data);
441                 lgmnal_free_srxd(nal_data);
442                 LGMNAL_GM_LOCK(nal_data);
443                 gm_close(nal_data->gm_port);
444                 gm_finalize();
445                 LGMNAL_GM_UNLOCK(nal_data);
446                 PORTAL_FREE(nal, sizeof(nal_t));        
447                 PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));   
448                 PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
449                 return(NULL);
450         }
451         LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Global node id is [%u][%x]\n", global_nid));
452         nal_data->gm_global_nid = global_nid;
453
454 /*
455         pid = gm_getpid();
456 */
457         LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("portals_pid is [%u]\n", portals_pid));
458         portals_nid = (unsigned long)global_nid;
459         LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("portals_nid is [%lu]\n", portals_nid));
460         
461         LGMNAL_PRINT(LGMNAL_DEBUG_V, ("calling lib_init\n"));
462         if (lib_init(nal_cb, portals_nid, portals_pid, 1024, ptl_size, ac_size) != PTL_OK) {
463                 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("lib_init failed\n"));
464                 lgmnal_stop_rxthread(nal_data);
465                 lgmnal_free_stxd(nal_data);
466                 lgmnal_free_srxd(nal_data);
467                 LGMNAL_GM_LOCK(nal_data);
468                 gm_close(nal_data->gm_port);
469                 gm_finalize();
470                 LGMNAL_GM_UNLOCK(nal_data);
471                 PORTAL_FREE(nal, sizeof(nal_t));        
472                 PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));   
473                 PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
474                 return(NULL);
475                 
476         }
477         
478         LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("lgmnal_init finished\n"));
479         global_nal_data = nal->nal_data;
480         return(nal);
481 }
482
483
484
485 /*
486  *      Called when module removed
487  */
488 void lgmnal_fini()
489 {
490         lgmnal_data_t   *nal_data = global_nal_data;
491         nal_t           *nal = nal_data->nal;
492         nal_cb_t        *nal_cb = nal_data->nal_cb;
493
494         LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_fini\n"));
495
496         PtlNIFini(lgmnal_ni);
497         lib_fini(nal_cb);
498
499         lgmnal_stop_rxthread(nal_data);
500         lgmnal_free_stxd(nal_data);
501         lgmnal_free_srxd(nal_data);
502         LGMNAL_GM_LOCK(nal_data);
503         gm_close(nal_data->gm_port);
504         gm_finalize();
505         LGMNAL_GM_UNLOCK(nal_data);
506         PORTAL_FREE(nal, sizeof(nal_t));        
507         PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));   
508         PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
509 }
510
511 EXPORT_SYMBOL(lgmnal_init);
512 EXPORT_SYMBOL(lgmnal_fini);
513 EXPORT_SYMBOL(lgmnal_api_forward);
514 EXPORT_SYMBOL(lgmnal_api_validate);
515 EXPORT_SYMBOL(lgmnal_api_yield);
516 EXPORT_SYMBOL(lgmnal_api_lock);
517 EXPORT_SYMBOL(lgmnal_api_unlock);
518 EXPORT_SYMBOL(lgmnal_api_shutdown);