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
29 gmnal_cmd(struct portals_cfg *pcfg, void *private)
31 gmnal_ni_t *gmnalni = private;
35 gm_status_t gm_status;
37 CDEBUG(D_TRACE, "gmnal_cmd [%d] private [%p]\n",
38 pcfg->pcfg_command, private);
39 gmnalni = (gmnal_ni_t*)private;
41 switch(pcfg->pcfg_command) {
42 case GMNAL_IOC_GET_GNID:
44 PORTAL_ALLOC(name, pcfg->pcfg_plen1);
45 copy_from_user(name, PCFG_PBUF(pcfg, 1), pcfg->pcfg_plen1);
47 gm_status = gm_host_name_to_node_id_ex(gmnalni->gmni_port, 0,
49 if (gm_status != GM_SUCCESS) {
50 CDEBUG(D_NET, "gm_host_name_to_node_id_ex(...host %s) "
51 "failed[%d]\n", name, gm_status);
55 CDEBUG(D_NET, "Local node %s id is [%d]\n", name, nid);
56 gm_status = gm_node_id_to_global_id(gmnalni->gmni_port,
58 if (gm_status != GM_SUCCESS) {
59 CDEBUG(D_NET, "gm_node_id_to_global_id failed[%d]\n",
64 CDEBUG(D_NET, "Global node is is [%u][%x]\n", gmid, gmid);
65 copy_to_user(PCFG_PBUF(pcfg, 2), &gmid, pcfg->pcfg_plen2);
68 case NAL_CMD_REGISTER_MYNID:
70 if (pcfg->pcfg_nid == gmnalni->gmni_libnal->libnal_ni.ni_pid.nid)
73 CERROR("Can't change NID from "LPD64" to "LPD64"\n",
74 gmnalni->gmni_libnal->libnal_ni.ni_pid.nid,
79 CERROR ("gmnal_cmd UNKNOWN[%d]\n", pcfg->pcfg_command);
86 gmnal_get_local_nid (gmnal_ni_t *gmnalni)
88 unsigned int local_gmid;
89 unsigned int global_gmid;
91 gm_status_t gm_status;
93 /* Called before anything initialised: no need to lock */
94 gm_status = gm_get_node_id(gmnalni->gmni_port, &local_gmid);
95 if (gm_status != GM_SUCCESS)
98 CDEBUG(D_NET, "Local node id is [%u]\n", local_gmid);
100 gm_status = gm_node_id_to_global_id(gmnalni->gmni_port,
103 if (gm_status != GM_SUCCESS)
106 CDEBUG(D_NET, "Global node id is [%u]\n", global_gmid);
108 nid = (__u64)global_gmid;
109 LASSERT (nid != PTL_NID_ANY);
116 gmnal_api_shutdown(nal_t *nal)
118 lib_nal_t *libnal = nal->nal_data;
119 gmnal_ni_t *gmnalni = libnal->libnal_data;
121 if (nal->nal_refct != 0) {
122 /* This module got the first ref */
127 CDEBUG(D_TRACE, "gmnal_api_shutdown: gmnalni [%p]\n", gmnalni);
129 /* Stop portals calling our ioctl handler */
130 libcfs_nal_cmd_unregister(GMNAL);
132 /* stop processing messages */
133 gmnal_stop_ctthread(gmnalni);
134 gmnal_stop_rxthread(gmnalni);
136 gm_close(gmnalni->gmni_port);
141 gmnal_free_txs(gmnalni);
142 gmnal_free_rxs(gmnalni);
144 PORTAL_FREE(gmnalni, sizeof(*gmnalni));
145 PORTAL_FREE(libnal, sizeof(*libnal));
149 gmnal_api_startup(nal_t *nal, ptl_pid_t requested_pid,
150 ptl_ni_limits_t *requested_limits,
151 ptl_ni_limits_t *actual_limits)
154 lib_nal_t *libnal = NULL;
155 gmnal_ni_t *gmnalni = NULL;
156 gmnal_rx_t *rx = NULL;
157 gm_status_t gm_status;
158 ptl_process_id_t process_id;
161 if (nal->nal_refct != 0) {
162 if (actual_limits != NULL) {
163 libnal = (lib_nal_t *)nal->nal_data;
164 *actual_limits = libnal->libnal_ni.ni_actual_limits;
170 /* Called on first PtlNIInit() */
171 CDEBUG(D_TRACE, "startup\n");
173 PORTAL_ALLOC(gmnalni, sizeof(*gmnalni));
174 if (gmnalni == NULL) {
175 CERROR("can't allocate gmnalni\n");
179 PORTAL_ALLOC(libnal, sizeof(*libnal));
180 if (libnal == NULL) {
181 CERROR("can't allocate lib_nal\n");
185 memset(gmnalni, 0, sizeof(*gmnalni));
186 gmnalni->gmni_libnal = libnal;
187 spin_lock_init(&gmnalni->gmni_gm_lock);
189 *libnal = (lib_nal_t) {
190 .libnal_send = gmnal_cb_send,
191 .libnal_send_pages = gmnal_cb_send_pages,
192 .libnal_recv = gmnal_cb_recv,
193 .libnal_recv_pages = gmnal_cb_recv_pages,
194 .libnal_dist = gmnal_cb_dist,
195 .libnal_data = gmnalni,
199 * initialise the interface,
201 CDEBUG(D_NET, "Calling gm_init\n");
202 if (gm_init() != GM_SUCCESS) {
203 CERROR("call to gm_init failed\n");
207 CDEBUG(D_NET, "Calling gm_open with port [%d], "
208 "name [%s], version [%d]\n", gm_port_id,
209 "gmnal", GM_API_VERSION);
211 gm_status = gm_open(&gmnalni->gmni_port, 0, gm_port_id, "gmnal",
214 if (gm_status != GM_SUCCESS) {
215 CERROR("Can't open GM port %d: %d (%s)\n",
216 gm_port_id, gm_status, gmnal_gmstatus2str(gm_status));
220 CDEBUG(D_NET,"gm_open succeeded port[%p]\n",gmnalni->gmni_port);
222 gmnalni->gmni_msg_size = offsetof(gmnal_msg_t,
223 gmm_u.immediate.gmim_payload[PTL_MTU]);
224 CWARN("Msg size %08x\n", gmnalni->gmni_msg_size);
226 if (gmnal_alloc_rxs(gmnalni) != 0) {
227 CERROR("Failed to allocate rx descriptors\n");
231 if (gmnal_alloc_txs(gmnalni) != 0) {
232 CERROR("Failed to allocate tx descriptors\n");
236 process_id.pid = requested_pid;
237 process_id.nid = gmnal_get_local_nid(gmnalni);
238 if (process_id.nid == PTL_NID_ANY)
241 CDEBUG(D_NET, "portals_pid is [%u]\n", process_id.pid);
242 CDEBUG(D_NET, "portals_nid is ["LPU64"]\n", process_id.nid);
244 /* Hang out a bunch of small receive buffers
245 * In fact hang them all out */
246 for (rx = gmnalni->gmni_rx; rx != NULL; rx = rx->rx_next)
247 gmnal_post_rx(gmnalni, rx);
249 if (lib_init(libnal, nal, process_id,
250 requested_limits, actual_limits) != PTL_OK) {
251 CERROR("lib_init failed\n");
255 /* Now that we have initialised the portals library, start receive
256 * threads, we do this to avoid processing messages before we can parse
258 rc = gmnal_start_kernel_threads(gmnalni);
260 CERROR("Can't start threads: %d\n", rc);
264 rc = libcfs_nal_cmd_register(GMNAL, &gmnal_cmd, libnal->libnal_data);
266 CDEBUG(D_NET, "libcfs_nal_cmd_register failed: %d\n", rc);
270 CDEBUG(D_NET, "gmnal_init finished\n");
274 gmnal_stop_rxthread(gmnalni);
275 gmnal_stop_ctthread(gmnalni);
278 gm_close(gmnalni->gmni_port);
283 /* safe to free buffers after network has been shut down */
284 gmnal_free_txs(gmnalni);
285 gmnal_free_rxs(gmnalni);
288 PORTAL_FREE(libnal, sizeof(*libnal));
291 PORTAL_FREE(gmnalni, sizeof(*gmnalni));
296 ptl_handle_ni_t kgmnal_ni;
300 * Called when module loaded
306 CDEBUG(D_NET, "reset nal[%p]\n", &the_gm_nal);
308 the_gm_nal = (nal_t) {
309 .nal_ni_init = gmnal_api_startup,
310 .nal_ni_fini = gmnal_api_shutdown,
314 rc = ptl_register_nal(GMNAL, &the_gm_nal);
316 CERROR("Can't register GMNAL: %d\n", rc);
317 rc = PtlNIInit(GMNAL, LUSTRE_SRV_PTL_PID, NULL, NULL, &kgmnal_ni);
318 if (rc != PTL_OK && rc != PTL_IFACE_DUP) {
319 ptl_unregister_nal(GMNAL);
328 * Called when module removed
332 CDEBUG(D_TRACE, "gmnal_fini\n");
334 PtlNIFini(kgmnal_ni);
336 ptl_unregister_nal(GMNAL);