Whamcloud - gitweb
* Landed portals:b_port_step as follows...
[fs/lustre-release.git] / lnet / tests / ping_srv.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
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>
8  *
9  *
10  * This file is part of Portals, http://www.sf.net/projects/lustre/
11  *
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.
15  *
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.
20  *
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.
24  */
25
26 #define DEBUG_SUBSYSTEM S_PINGER
27
28 #include <libcfs/kp30.h>
29 #include <portals/p30.h>
30 #include "ping.h"
31
32 #define STDSIZE (sizeof(int) + sizeof(int) + sizeof(struct timeval))
33 #define MAXSIZE (16*1024)
34
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;
40 atomic_t pkt;
41        
42 static struct pingsrv_data *server=NULL;             // Our ping server
43
44 static void *pingsrv_shutdown(int err)
45 {
46         int rc;
47
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.
51          */
52         switch (err) {
53                 case 1:
54                         /* Unlink any memory descriptors we may have used */
55                         if ((rc = PtlMDUnlink (server->mdin_h)))
56                                 PDEBUG ("PtlMDUnlink (out head buffer)", rc);
57                 case 2:
58                         /* Free the event queue */
59                         if ((rc = PtlEQFree (server->eq)))
60                                 PDEBUG ("PtlEQFree", rc);
61
62                         /* Unlink the client portal from the ME list */
63                         if ((rc = PtlMEUnlink (server->me)))
64                                         PDEBUG ("PtlMEUnlink", rc);
65
66                 case 3:
67                         PtlNIFini (server->ni);
68
69                 case 4:
70                         
71                 case 5:
72                         if (server->in_buf != NULL)
73                                 PORTAL_FREE (server->in_buf, MAXSIZE);
74                         
75                         if (server != NULL)
76                                 PORTAL_FREE (server, 
77                                              sizeof (struct pingsrv_data));
78                         
79         }
80
81         CDEBUG (D_OTHER, "ping sever resources released\n");
82         return NULL;
83 } /* pingsrv_shutdown() */
84
85
86 int pingsrv_thread(void *arg)
87 {
88         int rc;
89         unsigned long magic;
90         unsigned long ping_bulk_magic = __cpu_to_le32(0xcafebabe);
91         
92         kportal_daemonize ("pingsrv");
93         server->tsk =  cfs_current();
94         
95         while (running) {
96                 set_current_state (TASK_INTERRUPTIBLE);
97                 if (atomic_read (&pkt) == 0) {
98                         schedule_timeout (MAX_SCHEDULE_TIMEOUT);
99                         continue;
100                 }
101                
102                 magic =  __le32_to_cpu(*((int *)(server->evnt.md.start 
103                                         + server->evnt.offset)));
104                 
105                 
106                 if(magic != 0xdeadbeef) {
107                         CERROR("Unexpected Packet to the server, magic: %lx %d\n", magic, server->evnt.offset);
108                         
109                 } 
110                 memcpy (server->in_buf, &ping_bulk_magic, sizeof(ping_bulk_magic));
111                                 
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;
118        
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);
124                          return 1;
125                 }
126          
127                 
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;
134         
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");
139                 }
140                 
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);
144                 
145                 atomic_dec (&pkt);
146                 
147         }
148         pingsrv_shutdown (1);
149         running = 1;
150         return 0;    
151 }
152
153 static void pingsrv_packet(ptl_event_t *ev)
154 {
155         atomic_inc (&pkt);
156         wake_up_process (server->tsk);
157 } /* pingsrv_head() */
158
159 static void pingsrv_callback(ptl_event_t *ev)
160 {
161         
162         if (ev == NULL) {
163                 CERROR ("null in callback, ev=%p\n", ev);
164                 return;
165         }
166         server->evnt = *ev;
167         
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)))));
175         
176         packets_valid++;
177
178         pingsrv_packet(ev);
179         
180 } /* pingsrv_callback() */
181
182
183 static struct pingsrv_data *pingsrv_setup(void)
184 {
185         int rc;
186
187         server->ni = PTL_INVALID_HANDLE;
188
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);
194         }
195
196
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);
201         }
202
203         server->id_local.nid = PTL_NID_ANY;
204         server->id_local.pid = PTL_PID_ANY;
205
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);
212         }
213
214
215         if ((rc = PtlEQAlloc (server->ni, 1024, &pingsrv_callback,
216                                         &server->eq))) {
217                 PDEBUG ("PtlEQAlloc (callback)", rc);
218                 return pingsrv_shutdown (2);
219         }
220         
221         PORTAL_ALLOC (server->in_buf, MAXSIZE);
222         if(!server->in_buf){
223                 CDEBUG (D_OTHER,"Allocation error\n");
224                 return pingsrv_shutdown(2);
225         }
226         
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);
235         
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");
240        }
241  
242         /* Success! */
243         return server; 
244 } /* pingsrv_setup() */
245
246 static int pingsrv_start(void) 
247 {
248         /* Setup our server */
249         if (!pingsrv_setup()) {
250                 CDEBUG (D_OTHER, "pingsrv_setup() failed, server stopped\n");
251                 return -ENOMEM;
252         }
253         cfs_kernel_thread (pingsrv_thread,NULL,0);
254         return 0;
255 } /* pingsrv_start() */
256
257 static int __init pingsrv_init(void)
258 {
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));  
262         atomic_set(&pkt, 0);
263         return pingsrv_start ();
264 } /* pingsrv_init() */
265
266 static void /*__exit*/ pingsrv_cleanup(void)
267 {
268         cfs_remove_proc_entry ("net/pingsrv", NULL);
269         
270         running = 0;
271         wake_up_process (server->tsk);
272         while (running != 1) {
273                 set_current_state (TASK_UNINTERRUPTIBLE);
274                 schedule_timeout (cfs_time_seconds(1));
275         }
276         
277 } /* pingsrv_cleanup() */
278
279
280 MODULE_PARM(nal, "i");
281 MODULE_PARM_DESC(nal, "Use the specified NAL "
282                 "(2-ksocknal, 1-kqswnal)");
283  
284 MODULE_AUTHOR("Brian Behlendorf (LLNL)");
285 MODULE_DESCRIPTION("A kernel space ping server for portals testing");
286 MODULE_LICENSE("GPL");
287
288 cfs_module(ping_srv, "1.0.0", pingsrv_init, pingsrv_cleanup);