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