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 * 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.
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.
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.
23 * Implements the API NAL functions
28 gmnal_data_t *global_nal_data = NULL;
31 * This function takes a pack block of arguments from the NAL API
32 * module and passes them to the NAL CB module. The CB module unpacks
33 * the args and calls the appropriate function indicated by index.
34 * Typically this function is used to pass args between kernel and use
36 * As lgmanl exists entirely in kernel, just pass the arg block directly
37 * to the NAL CB, buy passing the args to lib_dispatch
40 * int index the api function that initiated this call
41 * void *args packed block of function args
42 * size_t arg_len length of args block
43 * void *ret A return value for the API NAL
44 * size_t ret_len Size of the return value
49 gmnal_api_forward(nal_t *nal, int index, void *args, size_t arg_len,
50 void *ret, size_t ret_len)
53 nal_cb_t *nal_cb = NULL;
54 gmnal_data_t *nal_data = NULL;
60 if (!nal || !args || (index < 0) || (arg_len < 0)) {
61 CDEBUG(D_ERROR, "Bad args to gmnal_api_forward\n");
65 if (ret && (ret_len <= 0)) {
66 CDEBUG(D_ERROR, "Bad args to gmnal_api_forward\n");
72 CDEBUG(D_ERROR, "bad nal, no nal data\n");
76 nal_data = nal->nal_data;
77 CDEBUG(D_INFO, "nal_data is [%p]\n", nal_data);
79 if (!nal_data->nal_cb) {
80 CDEBUG(D_ERROR, "bad nal_data, no nal_cb\n");
84 nal_cb = nal_data->nal_cb;
85 CDEBUG(D_INFO, "nal_cb is [%p]\n", nal_cb);
87 CDEBUG(D_PORTALS, "gmnal_api_forward calling lib_dispatch\n");
88 lib_dispatch(nal_cb, NULL, index, args, ret);
89 CDEBUG(D_PORTALS, "gmnal_api_forward returns from lib_dispatch\n");
97 * Close down this interface and free any resources associated with it
98 * nal_t nal our nal to shutdown
101 gmnal_api_shutdown(nal_t *nal, int interface)
104 gmnal_data_t *nal_data = nal->nal_data;
106 CDEBUG(D_TRACE, "gmnal_api_shutdown: nal_data [%p]\n", nal_data);
114 * validate a user address for use in communications
115 * There's nothing to be done here
118 gmnal_api_validate(nal_t *nal, void *base, size_t extent)
128 * Give up the processor
131 gmnal_api_yield(nal_t *nal)
133 CDEBUG(D_TRACE, "gmnal_api_yield : nal [%p]\n", nal);
135 set_current_state(TASK_INTERRUPTIBLE);
145 * Take a threadsafe lock
148 gmnal_api_lock(nal_t *nal, unsigned long *flags)
151 gmnal_data_t *nal_data;
154 nal_data = nal->nal_data;
155 nal_cb = nal_data->nal_cb;
157 nal_cb->cb_cli(nal_cb, flags);
164 * Release a threadsafe lock
167 gmnal_api_unlock(nal_t *nal, unsigned long *flags)
169 gmnal_data_t *nal_data;
172 nal_data = nal->nal_data;
173 nal_cb = nal_data->nal_cb;
175 nal_cb->cb_sti(nal_cb, flags);
182 gmnal_init(int interface, ptl_pt_index_t ptl_size, ptl_ac_index_t ac_size,
187 nal_cb_t *nal_cb = NULL;
188 gmnal_data_t *nal_data = NULL;
189 gmnal_srxd_t *srxd = NULL;
190 gm_status_t gm_status;
191 unsigned int local_nid = 0, global_nid = 0;
192 ptl_nid_t portals_nid;
193 ptl_pid_t portals_pid = 0;
196 CDEBUG(D_TRACE, "gmnal_init : interface [%d], ptl_size [%d],
197 ac_size[%d]\n", interface, ptl_size, ac_size);
200 PORTAL_ALLOC(nal_data, sizeof(gmnal_data_t));
202 CDEBUG(D_ERROR, "can't get memory\n");
205 memset(nal_data, 0, sizeof(gmnal_data_t));
207 * set the small message buffer size
209 nal_data->refcnt = 1;
211 CDEBUG(D_INFO, "Allocd and reset nal_data[%p]\n", nal_data);
212 CDEBUG(D_INFO, "small_msg_size is [%d]\n", nal_data->small_msg_size);
214 PORTAL_ALLOC(nal, sizeof(nal_t));
216 PORTAL_FREE(nal_data, sizeof(gmnal_data_t));
219 memset(nal, 0, sizeof(nal_t));
220 CDEBUG(D_INFO, "Allocd and reset nal[%p]\n", nal);
222 PORTAL_ALLOC(nal_cb, sizeof(nal_cb_t));
224 PORTAL_FREE(nal, sizeof(nal_t));
225 PORTAL_FREE(nal_data, sizeof(gmnal_data_t));
228 memset(nal_cb, 0, sizeof(nal_cb_t));
229 CDEBUG(D_INFO, "Allocd and reset nal_cb[%p]\n", nal_cb);
232 GMNAL_INIT_NAL_CB(nal_cb);
234 * String them all together
236 nal->nal_data = (void*)nal_data;
237 nal_cb->nal_data = (void*)nal_data;
239 nal_data->nal_cb = nal_cb;
241 GMNAL_CB_LOCK_INIT(nal_data);
242 GMNAL_GM_LOCK_INIT(nal_data);
246 * initialise the interface,
248 CDEBUG(D_INFO, "Calling gm_init\n");
249 if (gm_init() != GM_SUCCESS) {
250 CDEBUG(D_ERROR, "call to gm_init failed\n");
251 PORTAL_FREE(nal, sizeof(nal_t));
252 PORTAL_FREE(nal_data, sizeof(gmnal_data_t));
253 PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
258 CDEBUG(D_NET, "Calling gm_open with interface [%d], port [%d],
259 name [%s], version [%d]\n", interface, GMNAL_GM_PORT,
260 "gmnal", GM_API_VERSION);
262 GMNAL_GM_LOCK(nal_data);
263 gm_status = gm_open(&nal_data->gm_port, 0, GMNAL_GM_PORT, "gmnal",
265 GMNAL_GM_UNLOCK(nal_data);
267 CDEBUG(D_INFO, "gm_open returned [%d]\n", gm_status);
268 if (gm_status == GM_SUCCESS) {
269 CDEBUG(D_INFO, "gm_open succeeded port[%p]\n",
273 case(GM_INVALID_PARAMETER):
274 CDEBUG(D_ERROR, "gm_open Failure. Invalid Parameter\n");
277 CDEBUG(D_ERROR, "gm_open Failure. GM Busy\n");
279 case(GM_NO_SUCH_DEVICE):
280 CDEBUG(D_ERROR, "gm_open Failure. No such device\n");
282 case(GM_INCOMPATIBLE_LIB_AND_DRIVER):
283 CDEBUG(D_ERROR, "gm_open Failure. Incompatile lib
286 case(GM_OUT_OF_MEMORY):
287 CDEBUG(D_ERROR, "gm_open Failure. Out of Memory\n");
290 CDEBUG(D_ERROR, "gm_open Failure. Unknow error
291 code [%d]\n", gm_status);
294 GMNAL_GM_LOCK(nal_data);
296 GMNAL_GM_UNLOCK(nal_data);
297 PORTAL_FREE(nal, sizeof(nal_t));
298 PORTAL_FREE(nal_data, sizeof(gmnal_data_t));
299 PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
304 nal_data->small_msg_size = gmnal_small_msg_size;
305 nal_data->small_msg_gmsize =
306 gm_min_size_for_length(gmnal_small_msg_size);
308 if (gmnal_alloc_srxd(nal_data) != GMNAL_STATUS_OK) {
309 CDEBUG(D_ERROR, "Failed to allocate small rx descriptors\n");
310 gmnal_free_txd(nal_data);
311 GMNAL_GM_LOCK(nal_data);
312 gm_close(nal_data->gm_port);
314 GMNAL_GM_UNLOCK(nal_data);
315 PORTAL_FREE(nal, sizeof(nal_t));
316 PORTAL_FREE(nal_data, sizeof(gmnal_data_t));
317 PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
323 * Hang out a bunch of small receive buffers
324 * In fact hang them all out
326 while((srxd = gmnal_get_srxd(nal_data, 0))) {
327 CDEBUG(D_NET, "giving [%p] to gm_provide_recvive_buffer\n",
329 GMNAL_GM_LOCK(nal_data);
330 gm_provide_receive_buffer_with_tag(nal_data->gm_port,
331 srxd->buffer, srxd->gmsize,
333 GMNAL_GM_UNLOCK(nal_data);
337 * Allocate pools of small tx buffers and descriptors
339 if (gmnal_alloc_txd(nal_data) != GMNAL_STATUS_OK) {
340 CDEBUG(D_ERROR, "Failed to allocate small tx descriptors\n");
341 GMNAL_GM_LOCK(nal_data);
342 gm_close(nal_data->gm_port);
344 GMNAL_GM_UNLOCK(nal_data);
345 PORTAL_FREE(nal, sizeof(nal_t));
346 PORTAL_FREE(nal_data, sizeof(gmnal_data_t));
347 PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
351 gmnal_start_kernel_threads(nal_data);
353 while (nal_data->rxthread_flag != GMNAL_RXTHREADS_STARTED) {
355 CDEBUG(D_INFO, "Waiting for receive thread signs of life\n");
358 CDEBUG(D_INFO, "receive thread seems to have started\n");
362 * Initialise the portals library
364 CDEBUG(D_NET, "Getting node id\n");
365 GMNAL_GM_LOCK(nal_data);
366 gm_status = gm_get_node_id(nal_data->gm_port, &local_nid);
367 GMNAL_GM_UNLOCK(nal_data);
368 if (gm_status != GM_SUCCESS) {
369 gmnal_stop_rxthread(nal_data);
370 gmnal_stop_ctthread(nal_data);
371 CDEBUG(D_ERROR, "can't determine node id\n");
372 gmnal_free_txd(nal_data);
373 gmnal_free_srxd(nal_data);
374 GMNAL_GM_LOCK(nal_data);
375 gm_close(nal_data->gm_port);
377 GMNAL_GM_UNLOCK(nal_data);
378 PORTAL_FREE(nal, sizeof(nal_t));
379 PORTAL_FREE(nal_data, sizeof(gmnal_data_t));
380 PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
383 nal_data->gm_local_nid = local_nid;
384 CDEBUG(D_INFO, "Local node id is [%u]\n", local_nid);
385 GMNAL_GM_LOCK(nal_data);
386 gm_status = gm_node_id_to_global_id(nal_data->gm_port, local_nid,
388 GMNAL_GM_UNLOCK(nal_data);
389 if (gm_status != GM_SUCCESS) {
390 CDEBUG(D_ERROR, "failed to obtain global id\n");
391 gmnal_stop_rxthread(nal_data);
392 gmnal_stop_ctthread(nal_data);
393 gmnal_free_txd(nal_data);
394 gmnal_free_srxd(nal_data);
395 GMNAL_GM_LOCK(nal_data);
396 gm_close(nal_data->gm_port);
398 GMNAL_GM_UNLOCK(nal_data);
399 PORTAL_FREE(nal, sizeof(nal_t));
400 PORTAL_FREE(nal_data, sizeof(gmnal_data_t));
401 PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
404 CDEBUG(D_INFO, "Global node id is [%u]\n", global_nid);
405 nal_data->gm_global_nid = global_nid;
410 CDEBUG(D_INFO, "portals_pid is [%u]\n", portals_pid);
411 portals_nid = (unsigned long)global_nid;
412 CDEBUG(D_INFO, "portals_nid is ["LPU64"]\n", portals_nid);
414 CDEBUG(D_PORTALS, "calling lib_init\n");
415 if (lib_init(nal_cb, portals_nid, portals_pid, 1024, ptl_size,
416 ac_size) != PTL_OK) {
417 CDEBUG(D_ERROR, "lib_init failed\n");
418 gmnal_stop_rxthread(nal_data);
419 gmnal_stop_ctthread(nal_data);
420 gmnal_free_txd(nal_data);
421 gmnal_free_srxd(nal_data);
422 GMNAL_GM_LOCK(nal_data);
423 gm_close(nal_data->gm_port);
425 GMNAL_GM_UNLOCK(nal_data);
426 PORTAL_FREE(nal, sizeof(nal_t));
427 PORTAL_FREE(nal_data, sizeof(gmnal_data_t));
428 PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
433 CDEBUG(D_INFO, "gmnal_init finished\n");
434 global_nal_data = nal->nal_data;
441 * Called when module removed
445 gmnal_data_t *nal_data = global_nal_data;
446 nal_t *nal = nal_data->nal;
447 nal_cb_t *nal_cb = nal_data->nal_cb;
449 CDEBUG(D_TRACE, "gmnal_fini\n");
451 PtlNIFini(kgmnal_ni);
454 gmnal_stop_rxthread(nal_data);
455 gmnal_stop_ctthread(nal_data);
456 gmnal_free_txd(nal_data);
457 gmnal_free_srxd(nal_data);
458 GMNAL_GM_LOCK(nal_data);
459 gm_close(nal_data->gm_port);
461 GMNAL_GM_UNLOCK(nal_data);
462 PORTAL_FREE(nal, sizeof(nal_t));
463 PORTAL_FREE(nal_data, sizeof(gmnal_data_t));
464 PORTAL_FREE(nal_cb, sizeof(nal_cb_t));