1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2002, Lawrence Livermore National Labs (LLNL)
5 * Author: Brian Behlendorf <behlendorf1@llnl.gov>
6 * Amey Inamdar <amey@calsoftinc.com>
7 * Kedar Sovani <kedar@calsoftinc.com>
10 * This file is part of Portals, http://www.sf.net/projects/lustre/
12 * Portals 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.
16 * Portals 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.
21 * You should have received a copy of the GNU General Public License
22 * along with Portals; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #define DEBUG_SUBSYSTEM S_PINGER
28 #include <libcfs/kp30.h>
29 #include <portals/p30.h>
32 #define STDSIZE (sizeof(int) + sizeof(int) + sizeof(struct timeval))
33 #define MAXSIZE (16*1024)
35 static unsigned ping_head_magic;
36 static unsigned ping_bulk_magic;
37 static int nal = SOCKNAL; // Your NAL,
38 static unsigned long packets_valid = 0; // Valid packets
39 static int running = 1;
42 static struct pingsrv_data *server=NULL; // Our ping server
44 static void *pingsrv_shutdown(int err)
48 /* Yes, we are intentionally allowing us to fall through each
49 * case in to the next. This allows us to pass an error
50 * code to just clean up the right stuff.
54 /* Unlink any memory descriptors we may have used */
55 if ((rc = PtlMDUnlink (server->mdin_h)))
56 PDEBUG ("PtlMDUnlink (out head buffer)", rc);
58 /* Free the event queue */
59 if ((rc = PtlEQFree (server->eq)))
60 PDEBUG ("PtlEQFree", rc);
62 /* Unlink the client portal from the ME list */
63 if ((rc = PtlMEUnlink (server->me)))
64 PDEBUG ("PtlMEUnlink", rc);
67 PtlNIFini (server->ni);
72 if (server->in_buf != NULL)
73 PORTAL_FREE (server->in_buf, MAXSIZE);
77 sizeof (struct pingsrv_data));
81 CDEBUG (D_OTHER, "ping sever resources released\n");
83 } /* pingsrv_shutdown() */
86 int pingsrv_thread(void *arg)
90 unsigned long ping_bulk_magic = __cpu_to_le32(0xcafebabe);
92 kportal_daemonize ("pingsrv");
93 server->tsk = cfs_current();
96 set_current_state (TASK_INTERRUPTIBLE);
97 if (atomic_read (&pkt) == 0) {
98 schedule_timeout (MAX_SCHEDULE_TIMEOUT);
102 magic = __le32_to_cpu(*((int *)(server->evnt.md.start
103 + server->evnt.offset)));
106 if(magic != 0xdeadbeef) {
107 CERROR("Unexpected Packet to the server, magic: %lx %d\n", magic, server->evnt.offset);
110 memcpy (server->in_buf, &ping_bulk_magic, sizeof(ping_bulk_magic));
112 server->mdout.length = server->evnt.rlength;
113 server->mdout.start = server->in_buf;
114 server->mdout.threshold = 1;
115 server->mdout.options = PTL_MD_EVENT_START_DISABLE | PTL_MD_OP_PUT;
116 server->mdout.user_ptr = NULL;
117 server->mdout.eq_handle = PTL_EQ_NONE;
119 /* Bind the outgoing buffer */
120 if ((rc = PtlMDBind (server->ni, server->mdout,
121 PTL_UNLINK, &server->mdout_h))) {
122 PDEBUG ("PtlMDBind", rc);
123 pingsrv_shutdown (1);
128 server->mdin.start = server->in_buf;
129 server->mdin.length = MAXSIZE;
130 server->mdin.threshold = 1;
131 server->mdin.options = PTL_MD_EVENT_START_DISABLE | PTL_MD_OP_PUT;
132 server->mdin.user_ptr = NULL;
133 server->mdin.eq_handle = server->eq;
135 if ((rc = PtlMDAttach (server->me, server->mdin,
136 PTL_UNLINK, &server->mdin_h))) {
137 PDEBUG ("PtlMDAttach (bulk)", rc);
138 CDEBUG (D_OTHER, "ping server resources allocated\n");
141 if ((rc = PtlPut (server->mdout_h, PTL_NOACK_REQ,
142 server->evnt.initiator, PTL_PING_CLIENT, 0, 0, 0, 0)))
143 PDEBUG ("PtlPut", rc);
148 pingsrv_shutdown (1);
153 static void pingsrv_packet(ptl_event_t *ev)
156 wake_up_process (server->tsk);
157 } /* pingsrv_head() */
159 static void pingsrv_callback(ptl_event_t *ev)
163 CERROR ("null in callback, ev=%p\n", ev);
168 CWARN ("received ping from nid "LPX64" "
169 "(off=%u rlen=%u mlen=%u head=%x seq=%d size=%d)\n",
170 ev->initiator.nid, ev->offset, ev->rlength, ev->mlength,
171 __le32_to_cpu(*((int *)(ev->md.start + ev->offset))),
172 __le32_to_cpu(*((int *)(ev->md.start + ev->offset + sizeof(unsigned)))),
173 __le32_to_cpu(*((int *)(ev->md.start + ev->offset + 2 *
174 sizeof(unsigned)))));
180 } /* pingsrv_callback() */
183 static struct pingsrv_data *pingsrv_setup(void)
187 server->ni = PTL_INVALID_HANDLE;
189 /* Aquire and initialize the proper nal for portals. */
190 rc = PtlNIInit(nal, 0, NULL, NULL, &server->ni);
191 if (!(rc == PTL_OK || rc == PTL_IFACE_DUP)) {
192 CDEBUG (D_OTHER, "NAL %x not loaded\n", nal);
193 return pingsrv_shutdown (4);
197 /* Based on the initialization aquire our unique portal ID. */
198 if ((rc = PtlGetId (server->ni, &server->my_id))) {
199 PDEBUG ("PtlGetId", rc);
200 return pingsrv_shutdown (2);
203 server->id_local.nid = PTL_NID_ANY;
204 server->id_local.pid = PTL_PID_ANY;
206 /* Attach a match entries for header packets */
207 if ((rc = PtlMEAttach (server->ni, PTL_PING_SERVER,
208 server->id_local,0, ~0,
209 PTL_RETAIN, PTL_INS_AFTER, &server->me))) {
210 PDEBUG ("PtlMEAttach", rc);
211 return pingsrv_shutdown (2);
215 if ((rc = PtlEQAlloc (server->ni, 1024, &pingsrv_callback,
217 PDEBUG ("PtlEQAlloc (callback)", rc);
218 return pingsrv_shutdown (2);
221 PORTAL_ALLOC (server->in_buf, MAXSIZE);
223 CDEBUG (D_OTHER,"Allocation error\n");
224 return pingsrv_shutdown(2);
227 /* Setup the incoming buffer */
228 server->mdin.start = server->in_buf;
229 server->mdin.length = MAXSIZE;
230 server->mdin.threshold = 1;
231 server->mdin.options = PTL_MD_EVENT_START_DISABLE | PTL_MD_OP_PUT;
232 server->mdin.user_ptr = NULL;
233 server->mdin.eq_handle = server->eq;
234 memset (server->in_buf, 0, STDSIZE);
236 if ((rc = PtlMDAttach (server->me, server->mdin,
237 PTL_UNLINK, &server->mdin_h))) {
238 PDEBUG ("PtlMDAttach (bulk)", rc);
239 CDEBUG (D_OTHER, "ping server resources allocated\n");
244 } /* pingsrv_setup() */
246 static int pingsrv_start(void)
248 /* Setup our server */
249 if (!pingsrv_setup()) {
250 CDEBUG (D_OTHER, "pingsrv_setup() failed, server stopped\n");
253 cfs_kernel_thread (pingsrv_thread,NULL,0);
255 } /* pingsrv_start() */
257 static int __init pingsrv_init(void)
259 ping_head_magic = __cpu_to_le32(PING_HEADER_MAGIC);
260 ping_bulk_magic = __cpu_to_le32(PING_BULK_MAGIC);
261 PORTAL_ALLOC (server, sizeof(struct pingsrv_data));
263 return pingsrv_start ();
264 } /* pingsrv_init() */
266 static void /*__exit*/ pingsrv_cleanup(void)
268 cfs_remove_proc_entry ("net/pingsrv", NULL);
271 wake_up_process (server->tsk);
272 while (running != 1) {
273 set_current_state (TASK_UNINTERRUPTIBLE);
274 schedule_timeout (cfs_time_seconds(1));
277 } /* pingsrv_cleanup() */
280 MODULE_PARM(nal, "i");
281 MODULE_PARM_DESC(nal, "Use the specified NAL "
282 "(2-ksocknal, 1-kqswnal)");
284 MODULE_AUTHOR("Brian Behlendorf (LLNL)");
285 MODULE_DESCRIPTION("A kernel space ping server for portals testing");
286 MODULE_LICENSE("GPL");
288 cfs_module(ping_srv, "1.0.0", pingsrv_init, pingsrv_cleanup);