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_threads(gmnalni);
135 gm_close(gmnalni->gmni_port);
140 gmnal_free_txs(gmnalni);
141 gmnal_free_rxs(gmnalni);
143 PORTAL_FREE(gmnalni, sizeof(*gmnalni));
144 PORTAL_FREE(libnal, sizeof(*libnal));
148 gmnal_api_startup(nal_t *nal, ptl_pid_t requested_pid,
149 ptl_ni_limits_t *requested_limits,
150 ptl_ni_limits_t *actual_limits)
153 lib_nal_t *libnal = NULL;
154 gmnal_ni_t *gmnalni = NULL;
155 gmnal_rx_t *rx = NULL;
156 gm_status_t gm_status;
157 ptl_process_id_t process_id;
160 if (nal->nal_refct != 0) {
161 if (actual_limits != NULL) {
162 libnal = (lib_nal_t *)nal->nal_data;
163 *actual_limits = libnal->libnal_ni.ni_actual_limits;
169 /* Called on first PtlNIInit() */
170 CDEBUG(D_TRACE, "startup\n");
172 PORTAL_ALLOC(gmnalni, sizeof(*gmnalni));
173 if (gmnalni == NULL) {
174 CERROR("can't allocate gmnalni\n");
178 PORTAL_ALLOC(libnal, sizeof(*libnal));
179 if (libnal == NULL) {
180 CERROR("can't allocate lib_nal\n");
184 memset(gmnalni, 0, sizeof(*gmnalni));
185 gmnalni->gmni_libnal = libnal;
186 spin_lock_init(&gmnalni->gmni_gm_lock);
188 *libnal = (lib_nal_t) {
189 .libnal_send = gmnal_cb_send,
190 .libnal_send_pages = gmnal_cb_send_pages,
191 .libnal_recv = gmnal_cb_recv,
192 .libnal_recv_pages = gmnal_cb_recv_pages,
193 .libnal_dist = gmnal_cb_dist,
194 .libnal_data = gmnalni,
198 * initialise the interface,
200 CDEBUG(D_NET, "Calling gm_init\n");
201 if (gm_init() != GM_SUCCESS) {
202 CERROR("call to gm_init failed\n");
206 CDEBUG(D_NET, "Calling gm_open with port [%d], "
207 "name [%s], version [%d]\n", gm_port_id,
208 "gmnal", GM_API_VERSION);
210 gm_status = gm_open(&gmnalni->gmni_port, 0, gm_port_id, "gmnal",
213 if (gm_status != GM_SUCCESS) {
214 CERROR("Can't open GM port %d: %d (%s)\n",
215 gm_port_id, gm_status, gmnal_gmstatus2str(gm_status));
219 CDEBUG(D_NET,"gm_open succeeded port[%p]\n",gmnalni->gmni_port);
221 gmnalni->gmni_msg_size = offsetof(gmnal_msg_t,
222 gmm_u.immediate.gmim_payload[PTL_MTU]);
223 CWARN("Msg size %08x\n", gmnalni->gmni_msg_size);
225 if (gmnal_alloc_rxs(gmnalni) != 0) {
226 CERROR("Failed to allocate rx descriptors\n");
230 if (gmnal_alloc_txs(gmnalni) != 0) {
231 CERROR("Failed to allocate tx descriptors\n");
235 process_id.pid = requested_pid;
236 process_id.nid = gmnal_get_local_nid(gmnalni);
237 if (process_id.nid == PTL_NID_ANY)
240 CDEBUG(D_NET, "portals_pid is [%u]\n", process_id.pid);
241 CDEBUG(D_NET, "portals_nid is ["LPU64"]\n", process_id.nid);
243 /* Hang out a bunch of small receive buffers
244 * In fact hang them all out */
245 for (rx = gmnalni->gmni_rx; rx != NULL; rx = rx->rx_next)
246 gmnal_post_rx(gmnalni, rx);
248 if (lib_init(libnal, nal, process_id,
249 requested_limits, actual_limits) != PTL_OK) {
250 CERROR("lib_init failed\n");
254 /* Now that we have initialised the portals library, start receive
255 * threads, we do this to avoid processing messages before we can parse
257 rc = gmnal_start_threads(gmnalni);
259 CERROR("Can't start threads: %d\n", rc);
263 rc = libcfs_nal_cmd_register(GMNAL, &gmnal_cmd, libnal->libnal_data);
265 CDEBUG(D_NET, "libcfs_nal_cmd_register failed: %d\n", rc);
269 CDEBUG(D_NET, "gmnal_init finished\n");
273 gmnal_stop_threads(gmnalni);
276 gm_close(gmnalni->gmni_port);
281 /* safe to free buffers after network has been shut down */
282 gmnal_free_txs(gmnalni);
283 gmnal_free_rxs(gmnalni);
286 PORTAL_FREE(libnal, sizeof(*libnal));
289 PORTAL_FREE(gmnalni, sizeof(*gmnalni));
294 ptl_handle_ni_t kgmnal_ni;
298 * Called when module loaded
304 CDEBUG(D_NET, "reset nal[%p]\n", &the_gm_nal);
306 the_gm_nal = (nal_t) {
307 .nal_ni_init = gmnal_api_startup,
308 .nal_ni_fini = gmnal_api_shutdown,
312 rc = ptl_register_nal(GMNAL, &the_gm_nal);
314 CERROR("Can't register GMNAL: %d\n", rc);
315 rc = PtlNIInit(GMNAL, LUSTRE_SRV_PTL_PID, NULL, NULL, &kgmnal_ni);
316 if (rc != PTL_OK && rc != PTL_IFACE_DUP) {
317 ptl_unregister_nal(GMNAL);
326 * Called when module removed
330 CDEBUG(D_TRACE, "gmnal_fini\n");
332 PtlNIFini(kgmnal_ni);
334 ptl_unregister_nal(GMNAL);