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 <linux/kp30.h>
29 #include <portals/p30.h>
32 #include <linux/module.h>
33 #include <linux/proc_fs.h>
34 #include <linux/init.h>
35 #include <linux/kernel.h>
36 #include <linux/sched.h>
37 #include <linux/version.h>
38 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
39 #include <linux/workqueue.h>
41 #include <linux/tqueue.h>
43 #include <linux/wait.h>
44 #include <linux/smp_lock.h>
46 #include <asm/unistd.h>
47 #include <asm/semaphore.h>
49 #define STDSIZE (sizeof(int) + sizeof(int) + sizeof(struct timeval))
50 #define MAXSIZE (16*1024*1024)
52 static unsigned ping_head_magic;
53 static unsigned ping_bulk_magic;
54 static int nal = 0; // Your NAL,
55 static unsigned long packets_valid = 0; // Valid packets
56 static int running = 1;
59 static struct pingsrv_data *server=NULL; // Our ping server
61 static void *pingsrv_shutdown(int err)
65 /* Yes, we are intentionally allowing us to fall through each
66 * case in to the next. This allows us to pass an error
67 * code to just clean up the right stuff.
71 /* Unlink any memory descriptors we may have used */
72 if ((rc = PtlMDUnlink (server->mdin_h)))
73 PDEBUG ("PtlMDUnlink (out head buffer)", rc);
75 /* Free the event queue */
76 if ((rc = PtlEQFree (server->eq)))
77 PDEBUG ("PtlEQFree", rc);
79 /* Unlink the client portal from the ME list */
80 if ((rc = PtlMEUnlink (server->me)))
81 PDEBUG ("PtlMEUnlink", rc);
89 if (server->in_buf != NULL)
90 PORTAL_FREE (server->in_buf, MAXSIZE);
94 sizeof (struct pingsrv_data));
98 CDEBUG (D_OTHER, "ping sever resources released\n");
100 } /* pingsrv_shutdown() */
103 int pingsrv_thread(void *arg)
107 unsigned long ping_bulk_magic = 0xcafebabe;
109 kportal_daemonize ("pingsrv");
110 server->tsk = current;
113 set_current_state (TASK_INTERRUPTIBLE);
114 if (atomic_read (&pkt) == 0) {
115 schedule_timeout (MAX_SCHEDULE_TIMEOUT);
119 magic = *((int *)(server->evnt.mem_desc.start
120 + server->evnt.offset));
123 if(magic != 0xdeadbeef) {
124 printk("Unexpected Packet to the server\n");
127 memcpy (server->in_buf, &ping_bulk_magic, sizeof(ping_bulk_magic));
129 server->mdout.length = server->evnt.rlength;
130 server->mdout.start = server->in_buf;
131 server->mdout.threshold = 1;
132 server->mdout.options = PTL_MD_OP_PUT;
133 server->mdout.user_ptr = NULL;
134 server->mdout.eventq = PTL_EQ_NONE;
136 /* Bind the outgoing buffer */
137 if ((rc = PtlMDBind (server->ni, server->mdout,
138 &server->mdout_h))) {
139 PDEBUG ("PtlMDBind", rc);
140 pingsrv_shutdown (1);
145 server->mdin.start = server->in_buf;
146 server->mdin.length = MAXSIZE;
147 server->mdin.threshold = 1;
148 server->mdin.options = PTL_MD_OP_PUT;
149 server->mdin.user_ptr = NULL;
150 server->mdin.eventq = server->eq;
152 if ((rc = PtlMDAttach (server->me, server->mdin,
153 PTL_UNLINK, &server->mdin_h))) {
154 PDEBUG ("PtlMDAttach (bulk)", rc);
155 CDEBUG (D_OTHER, "ping server resources allocated\n");
158 if ((rc = PtlPut (server->mdout_h, PTL_NOACK_REQ,
159 server->evnt.initiator, PTL_PING_CLIENT, 0, 0, 0, 0)))
160 PDEBUG ("PtlPut", rc);
165 pingsrv_shutdown (1);
170 static int pingsrv_packet(ptl_event_t *ev)
173 wake_up_process (server->tsk);
175 } /* pingsrv_head() */
177 static int pingsrv_callback(ptl_event_t *ev)
181 CERROR ("null in callback, ev=%p\n", ev);
186 printk ("received ping from nid "LPX64" "
187 "(off=%u rlen=%u mlen=%u head=%x seq=%d size=%d)\n",
188 ev->initiator.nid, ev->offset, ev->rlength, ev->mlength,
189 *((int *)(ev->mem_desc.start + ev->offset)),
190 *((int *)(ev->mem_desc.start + ev->offset + sizeof(unsigned))),
191 *((int *)(ev->mem_desc.start + ev->offset + 2 *
196 return pingsrv_packet(ev);
198 } /* pingsrv_callback() */
201 static struct pingsrv_data *pingsrv_setup(void)
203 ptl_handle_ni_t *nip;
206 /* Aquire and initialize the proper nal for portals. */
207 if ((nip = kportal_get_ni (nal)) == NULL) {
208 CDEBUG (D_OTHER, "NAL %d not loaded\n", nal);
209 return pingsrv_shutdown (4);
214 /* Based on the initialization aquire our unique portal ID. */
215 if ((rc = PtlGetId (server->ni, &server->my_id))) {
216 PDEBUG ("PtlGetId", rc);
217 return pingsrv_shutdown (2);
220 server->id_local.nid = PTL_NID_ANY;
221 server->id_local.pid = PTL_PID_ANY;
223 /* Attach a match entries for header packets */
224 if ((rc = PtlMEAttach (server->ni, PTL_PING_SERVER,
225 server->id_local,0, ~0,
226 PTL_RETAIN, PTL_INS_AFTER, &server->me))) {
227 PDEBUG ("PtlMEAttach", rc);
228 return pingsrv_shutdown (2);
232 if ((rc = PtlEQAlloc (server->ni, 1024, pingsrv_callback,
234 PDEBUG ("PtlEQAlloc (callback)", rc);
235 return pingsrv_shutdown (2);
238 PORTAL_ALLOC (server->in_buf, MAXSIZE);
240 CDEBUG (D_OTHER,"Allocation error\n");
241 return pingsrv_shutdown(2);
244 /* Setup the incoming buffer */
245 server->mdin.start = server->in_buf;
246 server->mdin.length = MAXSIZE;
247 server->mdin.threshold = 1;
248 server->mdin.options = PTL_MD_OP_PUT;
249 server->mdin.user_ptr = NULL;
250 server->mdin.eventq = server->eq;
251 memset (server->in_buf, 0, STDSIZE);
253 if ((rc = PtlMDAttach (server->me, server->mdin,
254 PTL_UNLINK, &server->mdin_h))) {
255 PDEBUG ("PtlMDAttach (bulk)", rc);
256 CDEBUG (D_OTHER, "ping server resources allocated\n");
261 } /* pingsrv_setup() */
263 static int pingsrv_start(void)
265 /* Setup our server */
266 if (!pingsrv_setup()) {
267 CDEBUG (D_OTHER, "pingsrv_setup() failed, server stopped\n");
270 kernel_thread (pingsrv_thread,NULL,0);
272 } /* pingsrv_start() */
276 static int __init pingsrv_init(void)
278 ping_head_magic = PING_HEADER_MAGIC;
279 ping_bulk_magic = PING_BULK_MAGIC;
280 PORTAL_ALLOC (server, sizeof(struct pingsrv_data));
281 return pingsrv_start ();
282 } /* pingsrv_init() */
285 static void __exit pingsrv_cleanup(void)
287 remove_proc_entry ("net/pingsrv", NULL);
290 wake_up_process (server->tsk);
291 while (running != 1) {
292 set_current_state (TASK_UNINTERRUPTIBLE);
293 schedule_timeout (HZ);
296 } /* pingsrv_cleanup() */
299 MODULE_PARM(nal, "i");
300 MODULE_PARM_DESC(nal, "Use the specified NAL "
301 "(6-kscimacnal, 4-toenal, 2-ksocknal, 1-kqswnal)");
303 MODULE_AUTHOR("Brian Behlendorf (LLNL)");
304 MODULE_DESCRIPTION("A kernel space ping server for portals testing");
305 MODULE_LICENSE("GPL");
307 module_init(pingsrv_init);
308 module_exit(pingsrv_cleanup);