Whamcloud - gitweb
* Landed b_cray_portals_merge (3148, 3158)
[fs/lustre-release.git] / lnet / lnet / api-ni.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * api/api-ni.c
5  * Network Interface code
6  *
7  *  Copyright (c) 2001-2003 Cluster File Systems, Inc.
8  *  Copyright (c) 2001-2002 Sandia National Laboratories
9  *
10  *   This file is part of Lustre, http://www.sf.net/projects/lustre/
11  *
12  *   Lustre is free software; you can redistribute it and/or
13  *   modify it under the terms of version 2 of the GNU General Public
14  *   License as published by the Free Software Foundation.
15  *
16  *   Lustre is distributed in the hope that it will be useful,
17  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *   GNU General Public License for more details.
20  *
21  *   You should have received a copy of the GNU General Public License
22  *   along with Lustre; if not, write to the Free Software
23  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24  */
25
26 #define DEBUG_SUBSYSTEM S_PORTALS
27 #include <portals/api-support.h>
28
29 int ptl_init;
30
31 /* Put some magic in the NI handle so uninitialised/zeroed handles are easy
32  * to spot */
33 #define NI_HANDLE_MAGIC  0xebc0de00
34 #define NI_HANDLE_MASK   0x000000ff
35
36 static struct nal_t *ptl_nal_table[NAL_MAX_NR];
37
38 #ifdef __KERNEL__
39 DECLARE_MUTEX(ptl_mutex);
40
41 static void ptl_mutex_enter (void) 
42 {
43         down (&ptl_mutex);
44 }
45
46 static void ptl_mutex_exit (void)
47 {
48         up (&ptl_mutex);
49 }
50 #else
51 static void ptl_mutex_enter (void)
52 {
53 }
54
55 static void ptl_mutex_exit (void) 
56 {
57 }
58 #endif
59
60 nal_t *ptl_hndl2nal(ptl_handle_any_t *handle)
61 {
62         unsigned int idx = handle->nal_idx;
63
64         /* XXX we really rely on the caller NOT racing with interface
65          * setup/teardown.  That ensures her NI handle can't get
66          * invalidated out from under her (or worse, swapped for a
67          * completely different interface!) */
68
69         if (((idx ^ NI_HANDLE_MAGIC) & ~NI_HANDLE_MASK) != 0)
70                 return NULL;
71
72         idx &= NI_HANDLE_MASK;
73         
74         if (idx >= NAL_MAX_NR ||
75             ptl_nal_table[idx] == NULL ||
76             ptl_nal_table[idx]->nal_refct == 0)
77                 return NULL;
78
79         return ptl_nal_table[idx];
80 }
81
82 int ptl_register_nal (ptl_interface_t interface, nal_t *nal)
83 {
84         int    rc;
85         
86         ptl_mutex_enter();
87         
88         if (interface < 0 || interface >= NAL_MAX_NR)
89                 rc = PTL_IFACE_INVALID;
90         else if (ptl_nal_table[interface] != NULL)
91                 rc = PTL_IFACE_DUP;
92         else {
93                 rc = PTL_OK;
94                 ptl_nal_table[interface] = nal;
95                 LASSERT(nal->nal_refct == 0);
96         }
97
98         ptl_mutex_exit();
99         return (rc);
100 }
101
102 void ptl_unregister_nal (ptl_interface_t interface)
103 {
104         LASSERT(interface >= 0 && interface < NAL_MAX_NR);
105         LASSERT(ptl_nal_table[interface] != NULL);
106         LASSERT(ptl_nal_table[interface]->nal_refct == 0);
107         
108         ptl_mutex_enter();
109         
110         ptl_nal_table[interface] = NULL;
111
112         ptl_mutex_exit();
113 }
114
115 int ptl_ni_init(void)
116 {
117         /* If this assertion fails, we need more bits in NI_HANDLE_MASK and
118          * to shift NI_HANDLE_MAGIC left appropriately */
119         LASSERT (NAL_MAX_NR <= (NI_HANDLE_MASK + 1));
120         
121         ptl_mutex_enter();
122
123         if (!ptl_init) {
124                 /* NULL pointers, clear flags */
125                 memset(ptl_nal_table, 0, sizeof(ptl_nal_table));
126 #ifndef __KERNEL__
127                 /* Kernel NALs register themselves when their module loads,
128                  * and unregister themselves when their module is unloaded.
129                  * Userspace NALs, are plugged in explicitly here... */
130                 {
131                         extern nal_t procapi_nal;
132
133                         /* XXX pretend it's socknal to keep liblustre happy... */
134                         ptl_nal_table[SOCKNAL] = &procapi_nal;
135                         LASSERT (procapi_nal.nal_refct == 0);
136                 }
137 #endif
138                 ptl_init = 1;
139         }
140
141         ptl_mutex_exit();
142         
143         return PTL_OK;
144 }
145
146 void ptl_ni_fini(void)
147 {
148         nal_t  *nal;
149         int     i;
150
151         ptl_mutex_enter();
152
153         if (ptl_init) {
154                 for (i = 0; i < NAL_MAX_NR; i++) {
155
156                         nal = ptl_nal_table[i];
157                         if (nal == NULL)
158                                 continue;
159                         
160                         if (nal->nal_refct != 0) {
161                                 CWARN("NAL %d has outstanding refcount %d\n",
162                                       i, nal->nal_refct);
163                                 nal->shutdown(nal);
164                         }
165                         
166                         ptl_nal_table[i] = NULL;
167                 }
168
169                 ptl_init = 0;
170         }
171         
172         ptl_mutex_exit();
173 }
174
175 int PtlNIInit(ptl_interface_t interface, ptl_pid_t requested_pid,
176               ptl_ni_limits_t *desired_limits, ptl_ni_limits_t *actual_limits,
177               ptl_handle_ni_t *handle)
178 {
179         nal_t *nal;
180         int    i;
181         int    rc;
182
183         if (!ptl_init)
184                 return PTL_NO_INIT;
185
186         ptl_mutex_enter ();
187
188         if (interface == PTL_IFACE_DEFAULT) {
189                 for (i = 0; i < NAL_MAX_NR; i++)
190                         if (ptl_nal_table[i] != NULL) {
191                                 interface = i;
192                                 break;
193                         }
194                 /* NB if no interfaces are registered, 'interface' will
195                  * fail the valid test below */
196         }
197         
198         if (interface < 0 || 
199             interface >= NAL_MAX_NR ||
200             ptl_nal_table[interface] == NULL) {
201                 GOTO(out, rc = PTL_IFACE_INVALID);
202         }
203
204         nal = ptl_nal_table[interface];
205
206         CDEBUG(D_OTHER, "Starting up NAL (%d) refs %d\n", interface, nal->nal_refct);
207         rc = nal->startup(nal, requested_pid, desired_limits, actual_limits);
208
209         if (rc != PTL_OK) {
210                 CERROR("Error %d starting up NAL %d, refs %d\n", rc,
211                        interface, nal->nal_refct);
212                 GOTO(out, rc);
213         }
214         
215         if (nal->nal_refct != 0) {
216                 /* Caller gets to know if this was the first ref or not */
217                 rc = PTL_IFACE_DUP;
218         }
219         
220         nal->nal_refct++;
221         handle->nal_idx = (NI_HANDLE_MAGIC & ~NI_HANDLE_MASK) | interface;
222
223  out:
224         ptl_mutex_exit ();
225         return rc;
226 }
227
228 int PtlNIFini(ptl_handle_ni_t ni)
229 {
230         nal_t *nal;
231         int    idx;
232
233         if (!ptl_init)
234                 return PTL_NO_INIT;
235
236         ptl_mutex_enter ();
237
238         nal = ptl_hndl2nal (&ni);
239         if (nal == NULL) {
240                 ptl_mutex_exit ();
241                 return PTL_HANDLE_INVALID;
242         }
243
244         idx = ni.nal_idx & NI_HANDLE_MASK;
245
246         LASSERT(nal->nal_refct > 0);
247
248         nal->nal_refct--;
249
250         /* nal_refct == 0 tells nal->shutdown to really shut down */
251         nal->shutdown(nal);
252
253         ptl_mutex_exit ();
254         return PTL_OK;
255 }
256
257 int PtlNIHandle(ptl_handle_any_t handle_in, ptl_handle_ni_t * ni_out)
258 {
259         *ni_out = handle_in;
260
261         return PTL_OK;
262 }