Whamcloud - gitweb
LU-5874 lnet: reject invalid net configuration
[fs/lustre-release.git] / lnet / lnet / api-ni.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
19  *
20  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21  * CA 95054 USA or visit www.sun.com if you need additional information or
22  * have any questions.
23  *
24  * GPL HEADER END
25  */
26 /*
27  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
28  * Use is subject to license terms.
29  *
30  * Copyright (c) 2011, 2014, Intel Corporation.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  */
36
37 #define DEBUG_SUBSYSTEM S_LNET
38 #include <lnet/lib-lnet.h>
39 #include <lnet/lib-dlc.h>
40 #ifdef __KERNEL__
41 #include <linux/log2.h>
42 #endif
43
44 #ifdef __KERNEL__
45 #define D_LNI D_CONSOLE
46 #else
47 #define D_LNI D_CONFIG
48 #endif
49
50 lnet_t      the_lnet;                           /* THE state of the network */
51 EXPORT_SYMBOL(the_lnet);
52
53 #ifdef __KERNEL__
54
55 static char *ip2nets = "";
56 CFS_MODULE_PARM(ip2nets, "s", charp, 0444,
57                 "LNET network <- IP table");
58
59 static char *networks = "";
60 CFS_MODULE_PARM(networks, "s", charp, 0444,
61                 "local networks");
62
63 static char *routes = "";
64 CFS_MODULE_PARM(routes, "s", charp, 0444,
65                 "routes to non-local networks");
66
67 static int rnet_htable_size = LNET_REMOTE_NETS_HASH_DEFAULT;
68 CFS_MODULE_PARM(rnet_htable_size, "i", int, 0444,
69                 "size of remote network hash table");
70
71 static int lnet_ping(lnet_process_id_t id, int timeout_ms,
72                      lnet_process_id_t *ids, int n_ids);
73
74 static char *
75 lnet_get_routes(void)
76 {
77         return routes;
78 }
79
80 static char *
81 lnet_get_networks(void)
82 {
83         char   *nets;
84         int     rc;
85
86         if (*networks != 0 && *ip2nets != 0) {
87                 LCONSOLE_ERROR_MSG(0x101, "Please specify EITHER 'networks' or "
88                                    "'ip2nets' but not both at once\n");
89                 return NULL;
90         }
91
92         if (*ip2nets != 0) {
93                 rc = lnet_parse_ip2nets(&nets, ip2nets);
94                 return (rc == 0) ? nets : NULL;
95         }
96
97         if (*networks != 0)
98                 return networks;
99
100         return "tcp";
101 }
102
103 static void
104 lnet_init_locks(void)
105 {
106         spin_lock_init(&the_lnet.ln_eq_wait_lock);
107         init_waitqueue_head(&the_lnet.ln_eq_waitq);
108         mutex_init(&the_lnet.ln_lnd_mutex);
109         mutex_init(&the_lnet.ln_api_mutex);
110 }
111
112 static void
113 lnet_fini_locks(void)
114 {
115 }
116
117 #else
118
119 static char *
120 lnet_get_routes(void)
121 {
122         char *str = getenv("LNET_ROUTES");
123
124         return (str == NULL) ? "" : str;
125 }
126
127 static char *
128 lnet_get_networks (void)
129 {
130         static char       default_networks[256];
131         char             *networks = getenv("LNET_NETWORKS");
132         char             *str;
133         char             *sep;
134         int               len;
135         int               nob;
136         struct list_head *tmp;
137
138         if (networks != NULL)
139                 return networks;
140
141         /* In userland, the default 'networks=' is the list of known net types */
142         len = sizeof(default_networks);
143         str = default_networks;
144         *str = 0;
145         sep = "";
146
147         list_for_each(tmp, &the_lnet.ln_lnds) {
148                 lnd_t *lnd = list_entry(tmp, lnd_t, lnd_list);
149
150                 nob = snprintf(str, len, "%s%s", sep,
151                                libcfs_lnd2str(lnd->lnd_type));
152                 if (nob >= len) {
153                         /* overflowed the string; leave it where it was */
154                         *str = 0;
155                         break;
156                 }
157                 len -= nob;
158                 str += nob;
159                 sep = ",";
160         }
161
162         return default_networks;
163 }
164
165 # ifndef HAVE_LIBPTHREAD
166
167 static void lnet_init_locks(void)
168 {
169         the_lnet.ln_eq_wait_lock = 0;
170         the_lnet.ln_lnd_mutex = 0;
171         the_lnet.ln_api_mutex = 0;
172 }
173
174 static void lnet_fini_locks(void)
175 {
176         LASSERT(the_lnet.ln_api_mutex == 0);
177         LASSERT(the_lnet.ln_lnd_mutex == 0);
178         LASSERT(the_lnet.ln_eq_wait_lock == 0);
179 }
180
181 # else
182
183 static void lnet_init_locks(void)
184 {
185         pthread_cond_init(&the_lnet.ln_eq_cond, NULL);
186         pthread_mutex_init(&the_lnet.ln_eq_wait_lock, NULL);
187         pthread_mutex_init(&the_lnet.ln_lnd_mutex, NULL);
188         pthread_mutex_init(&the_lnet.ln_api_mutex, NULL);
189 }
190
191 static void lnet_fini_locks(void)
192 {
193         pthread_mutex_destroy(&the_lnet.ln_api_mutex);
194         pthread_mutex_destroy(&the_lnet.ln_lnd_mutex);
195         pthread_mutex_destroy(&the_lnet.ln_eq_wait_lock);
196         pthread_cond_destroy(&the_lnet.ln_eq_cond);
197 }
198
199 # endif
200 #endif
201
202 static int
203 lnet_create_remote_nets_table(void)
204 {
205         int               i;
206         struct list_head *hash;
207
208         LASSERT(the_lnet.ln_remote_nets_hash == NULL);
209         LASSERT(the_lnet.ln_remote_nets_hbits > 0);
210         LIBCFS_ALLOC(hash, LNET_REMOTE_NETS_HASH_SIZE * sizeof(*hash));
211         if (hash == NULL) {
212                 CERROR("Failed to create remote nets hash table\n");
213                 return -ENOMEM;
214         }
215
216         for (i = 0; i < LNET_REMOTE_NETS_HASH_SIZE; i++)
217                 INIT_LIST_HEAD(&hash[i]);
218         the_lnet.ln_remote_nets_hash = hash;
219         return 0;
220 }
221
222 static void
223 lnet_destroy_remote_nets_table(void)
224 {
225         int i;
226
227         if (the_lnet.ln_remote_nets_hash == NULL)
228                 return;
229
230         for (i = 0; i < LNET_REMOTE_NETS_HASH_SIZE; i++)
231                 LASSERT(list_empty(&the_lnet.ln_remote_nets_hash[i]));
232
233         LIBCFS_FREE(the_lnet.ln_remote_nets_hash,
234                     LNET_REMOTE_NETS_HASH_SIZE *
235                     sizeof(the_lnet.ln_remote_nets_hash[0]));
236         the_lnet.ln_remote_nets_hash = NULL;
237 }
238
239 static void
240 lnet_destroy_locks(void)
241 {
242         if (the_lnet.ln_res_lock != NULL) {
243                 cfs_percpt_lock_free(the_lnet.ln_res_lock);
244                 the_lnet.ln_res_lock = NULL;
245         }
246
247         if (the_lnet.ln_net_lock != NULL) {
248                 cfs_percpt_lock_free(the_lnet.ln_net_lock);
249                 the_lnet.ln_net_lock = NULL;
250         }
251
252         lnet_fini_locks();
253 }
254
255 static int
256 lnet_create_locks(void)
257 {
258         lnet_init_locks();
259
260         the_lnet.ln_res_lock = cfs_percpt_lock_alloc(lnet_cpt_table());
261         if (the_lnet.ln_res_lock == NULL)
262                 goto failed;
263
264         the_lnet.ln_net_lock = cfs_percpt_lock_alloc(lnet_cpt_table());
265         if (the_lnet.ln_net_lock == NULL)
266                 goto failed;
267
268         return 0;
269
270  failed:
271         lnet_destroy_locks();
272         return -ENOMEM;
273 }
274
275 static void lnet_assert_wire_constants(void)
276 {
277         /* Wire protocol assertions generated by 'wirecheck'
278          * running on Linux robert.bartonsoftware.com 2.6.8-1.521
279          * #1 Mon Aug 16 09:01:18 EDT 2004 i686 athlon i386 GNU/Linux
280          * with gcc version 3.3.3 20040412 (Red Hat Linux 3.3.3-7) */
281
282         /* Constants... */
283         CLASSERT (LNET_PROTO_TCP_MAGIC == 0xeebc0ded);
284         CLASSERT (LNET_PROTO_TCP_VERSION_MAJOR == 1);
285         CLASSERT (LNET_PROTO_TCP_VERSION_MINOR == 0);
286         CLASSERT (LNET_MSG_ACK == 0);
287         CLASSERT (LNET_MSG_PUT == 1);
288         CLASSERT (LNET_MSG_GET == 2);
289         CLASSERT (LNET_MSG_REPLY == 3);
290         CLASSERT (LNET_MSG_HELLO == 4);
291
292         /* Checks for struct ptl_handle_wire_t */
293         CLASSERT ((int)sizeof(lnet_handle_wire_t) == 16);
294         CLASSERT ((int)offsetof(lnet_handle_wire_t, wh_interface_cookie) == 0);
295         CLASSERT ((int)sizeof(((lnet_handle_wire_t *)0)->wh_interface_cookie) == 8);
296         CLASSERT ((int)offsetof(lnet_handle_wire_t, wh_object_cookie) == 8);
297         CLASSERT ((int)sizeof(((lnet_handle_wire_t *)0)->wh_object_cookie) == 8);
298
299         /* Checks for struct lnet_magicversion_t */
300         CLASSERT ((int)sizeof(lnet_magicversion_t) == 8);
301         CLASSERT ((int)offsetof(lnet_magicversion_t, magic) == 0);
302         CLASSERT ((int)sizeof(((lnet_magicversion_t *)0)->magic) == 4);
303         CLASSERT ((int)offsetof(lnet_magicversion_t, version_major) == 4);
304         CLASSERT ((int)sizeof(((lnet_magicversion_t *)0)->version_major) == 2);
305         CLASSERT ((int)offsetof(lnet_magicversion_t, version_minor) == 6);
306         CLASSERT ((int)sizeof(((lnet_magicversion_t *)0)->version_minor) == 2);
307
308         /* Checks for struct lnet_hdr_t */
309         CLASSERT ((int)sizeof(lnet_hdr_t) == 72);
310         CLASSERT ((int)offsetof(lnet_hdr_t, dest_nid) == 0);
311         CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->dest_nid) == 8);
312         CLASSERT ((int)offsetof(lnet_hdr_t, src_nid) == 8);
313         CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->src_nid) == 8);
314         CLASSERT ((int)offsetof(lnet_hdr_t, dest_pid) == 16);
315         CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->dest_pid) == 4);
316         CLASSERT ((int)offsetof(lnet_hdr_t, src_pid) == 20);
317         CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->src_pid) == 4);
318         CLASSERT ((int)offsetof(lnet_hdr_t, type) == 24);
319         CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->type) == 4);
320         CLASSERT ((int)offsetof(lnet_hdr_t, payload_length) == 28);
321         CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->payload_length) == 4);
322         CLASSERT ((int)offsetof(lnet_hdr_t, msg) == 32);
323         CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->msg) == 40);
324
325         /* Ack */
326         CLASSERT ((int)offsetof(lnet_hdr_t, msg.ack.dst_wmd) == 32);
327         CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->msg.ack.dst_wmd) == 16);
328         CLASSERT ((int)offsetof(lnet_hdr_t, msg.ack.match_bits) == 48);
329         CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->msg.ack.match_bits) == 8);
330         CLASSERT ((int)offsetof(lnet_hdr_t, msg.ack.mlength) == 56);
331         CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->msg.ack.mlength) == 4);
332
333         /* Put */
334         CLASSERT ((int)offsetof(lnet_hdr_t, msg.put.ack_wmd) == 32);
335         CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->msg.put.ack_wmd) == 16);
336         CLASSERT ((int)offsetof(lnet_hdr_t, msg.put.match_bits) == 48);
337         CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->msg.put.match_bits) == 8);
338         CLASSERT ((int)offsetof(lnet_hdr_t, msg.put.hdr_data) == 56);
339         CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->msg.put.hdr_data) == 8);
340         CLASSERT ((int)offsetof(lnet_hdr_t, msg.put.ptl_index) == 64);
341         CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->msg.put.ptl_index) == 4);
342         CLASSERT ((int)offsetof(lnet_hdr_t, msg.put.offset) == 68);
343         CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->msg.put.offset) == 4);
344
345         /* Get */
346         CLASSERT ((int)offsetof(lnet_hdr_t, msg.get.return_wmd) == 32);
347         CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->msg.get.return_wmd) == 16);
348         CLASSERT ((int)offsetof(lnet_hdr_t, msg.get.match_bits) == 48);
349         CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->msg.get.match_bits) == 8);
350         CLASSERT ((int)offsetof(lnet_hdr_t, msg.get.ptl_index) == 56);
351         CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->msg.get.ptl_index) == 4);
352         CLASSERT ((int)offsetof(lnet_hdr_t, msg.get.src_offset) == 60);
353         CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->msg.get.src_offset) == 4);
354         CLASSERT ((int)offsetof(lnet_hdr_t, msg.get.sink_length) == 64);
355         CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->msg.get.sink_length) == 4);
356
357         /* Reply */
358         CLASSERT ((int)offsetof(lnet_hdr_t, msg.reply.dst_wmd) == 32);
359         CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->msg.reply.dst_wmd) == 16);
360
361         /* Hello */
362         CLASSERT ((int)offsetof(lnet_hdr_t, msg.hello.incarnation) == 32);
363         CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->msg.hello.incarnation) == 8);
364         CLASSERT ((int)offsetof(lnet_hdr_t, msg.hello.type) == 40);
365         CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->msg.hello.type) == 4);
366 }
367
368 static lnd_t *
369 lnet_find_lnd_by_type (int type)
370 {
371         lnd_t            *lnd;
372         struct list_head *tmp;
373
374         /* holding lnd mutex */
375         list_for_each(tmp, &the_lnet.ln_lnds) {
376                 lnd = list_entry(tmp, lnd_t, lnd_list);
377
378                 if ((int)lnd->lnd_type == type)
379                         return lnd;
380         }
381         return NULL;
382 }
383
384 void
385 lnet_register_lnd (lnd_t *lnd)
386 {
387         LNET_MUTEX_LOCK(&the_lnet.ln_lnd_mutex);
388
389         LASSERT(the_lnet.ln_init);
390         LASSERT(libcfs_isknown_lnd(lnd->lnd_type));
391         LASSERT(lnet_find_lnd_by_type(lnd->lnd_type) == NULL);
392
393         list_add_tail(&lnd->lnd_list, &the_lnet.ln_lnds);
394         lnd->lnd_refcount = 0;
395
396         CDEBUG(D_NET, "%s LND registered\n", libcfs_lnd2str(lnd->lnd_type));
397
398         LNET_MUTEX_UNLOCK(&the_lnet.ln_lnd_mutex);
399 }
400 EXPORT_SYMBOL(lnet_register_lnd);
401
402 void
403 lnet_unregister_lnd (lnd_t *lnd)
404 {
405         LNET_MUTEX_LOCK(&the_lnet.ln_lnd_mutex);
406
407         LASSERT(the_lnet.ln_init);
408         LASSERT(lnet_find_lnd_by_type(lnd->lnd_type) == lnd);
409         LASSERT(lnd->lnd_refcount == 0);
410
411         list_del(&lnd->lnd_list);
412         CDEBUG(D_NET, "%s LND unregistered\n", libcfs_lnd2str(lnd->lnd_type));
413
414         LNET_MUTEX_UNLOCK(&the_lnet.ln_lnd_mutex);
415 }
416 EXPORT_SYMBOL(lnet_unregister_lnd);
417
418 void
419 lnet_counters_get(lnet_counters_t *counters)
420 {
421         lnet_counters_t *ctr;
422         int             i;
423
424         memset(counters, 0, sizeof(*counters));
425
426         lnet_net_lock(LNET_LOCK_EX);
427
428         cfs_percpt_for_each(ctr, i, the_lnet.ln_counters) {
429                 counters->msgs_max     += ctr->msgs_max;
430                 counters->msgs_alloc   += ctr->msgs_alloc;
431                 counters->errors       += ctr->errors;
432                 counters->send_count   += ctr->send_count;
433                 counters->recv_count   += ctr->recv_count;
434                 counters->route_count  += ctr->route_count;
435                 counters->drop_count   += ctr->drop_count;
436                 counters->send_length  += ctr->send_length;
437                 counters->recv_length  += ctr->recv_length;
438                 counters->route_length += ctr->route_length;
439                 counters->drop_length  += ctr->drop_length;
440
441         }
442         lnet_net_unlock(LNET_LOCK_EX);
443 }
444 EXPORT_SYMBOL(lnet_counters_get);
445
446 void
447 lnet_counters_reset(void)
448 {
449         lnet_counters_t *counters;
450         int             i;
451
452         lnet_net_lock(LNET_LOCK_EX);
453
454         cfs_percpt_for_each(counters, i, the_lnet.ln_counters)
455                 memset(counters, 0, sizeof(lnet_counters_t));
456
457         lnet_net_unlock(LNET_LOCK_EX);
458 }
459 EXPORT_SYMBOL(lnet_counters_reset);
460
461 #ifdef LNET_USE_LIB_FREELIST
462
463 int
464 lnet_freelist_init(lnet_freelist_t *fl, int n, int size)
465 {
466         char *space;
467
468         LASSERT (n > 0);
469
470         size += offsetof (lnet_freeobj_t, fo_contents);
471
472         LIBCFS_ALLOC(space, n * size);
473         if (space == NULL)
474                 return (-ENOMEM);
475
476         INIT_LIST_HEAD(&fl->fl_list);
477         fl->fl_objs = space;
478         fl->fl_nobjs = n;
479         fl->fl_objsize = size;
480
481         do {
482                 list_add((struct list_head *)space, &fl->fl_list);
483                 space += size;
484         } while (--n != 0);
485
486         return 0;
487 }
488
489 void
490 lnet_freelist_fini(lnet_freelist_t *fl)
491 {
492         struct list_head *el;
493         int               count;
494
495         if (fl->fl_nobjs == 0)
496                 return;
497
498         count = 0;
499         for (el = fl->fl_list.next; el != &fl->fl_list; el = el->next)
500                 count++;
501
502         LASSERT (count == fl->fl_nobjs);
503
504         LIBCFS_FREE(fl->fl_objs, fl->fl_nobjs * fl->fl_objsize);
505         memset (fl, 0, sizeof (*fl));
506 }
507
508 #endif /* LNET_USE_LIB_FREELIST */
509
510 static __u64 lnet_create_interface_cookie(void)
511 {
512         /* NB the interface cookie in wire handles guards against delayed
513          * replies and ACKs appearing valid after reboot. Initialisation time,
514          * even if it's only implemented to millisecond resolution is probably
515          * easily good enough. */
516         struct timeval tv;
517         __u64          cookie;
518 #ifndef __KERNEL__
519         int            rc = gettimeofday (&tv, NULL);
520         LASSERT (rc == 0);
521 #else
522         do_gettimeofday(&tv);
523 #endif
524         cookie = tv.tv_sec;
525         cookie *= 1000000;
526         cookie += tv.tv_usec;
527         return cookie;
528 }
529
530 static char *
531 lnet_res_type2str(int type)
532 {
533         switch (type) {
534         default:
535                 LBUG();
536         case LNET_COOKIE_TYPE_MD:
537                 return "MD";
538         case LNET_COOKIE_TYPE_ME:
539                 return "ME";
540         case LNET_COOKIE_TYPE_EQ:
541                 return "EQ";
542         }
543 }
544
545 static void
546 lnet_res_container_cleanup(struct lnet_res_container *rec)
547 {
548         int     count = 0;
549
550         if (rec->rec_type == 0) /* not set yet, it's uninitialized */
551                 return;
552
553         while (!list_empty(&rec->rec_active)) {
554                 struct list_head *e = rec->rec_active.next;
555
556                 list_del_init(e);
557                 if (rec->rec_type == LNET_COOKIE_TYPE_EQ) {
558                         lnet_eq_free(list_entry(e, lnet_eq_t, eq_list));
559
560                 } else if (rec->rec_type == LNET_COOKIE_TYPE_MD) {
561                         lnet_md_free(list_entry(e, lnet_libmd_t, md_list));
562
563                 } else { /* NB: Active MEs should be attached on portals */
564                         LBUG();
565                 }
566                 count++;
567         }
568
569         if (count > 0) {
570                 /* Found alive MD/ME/EQ, user really should unlink/free
571                  * all of them before finalize LNet, but if someone didn't,
572                  * we have to recycle garbage for him */
573                 CERROR("%d active elements on exit of %s container\n",
574                        count, lnet_res_type2str(rec->rec_type));
575         }
576
577 #ifdef LNET_USE_LIB_FREELIST
578         lnet_freelist_fini(&rec->rec_freelist);
579 #endif
580         if (rec->rec_lh_hash != NULL) {
581                 LIBCFS_FREE(rec->rec_lh_hash,
582                             LNET_LH_HASH_SIZE * sizeof(rec->rec_lh_hash[0]));
583                 rec->rec_lh_hash = NULL;
584         }
585
586         rec->rec_type = 0; /* mark it as finalized */
587 }
588
589 static int
590 lnet_res_container_setup(struct lnet_res_container *rec,
591                          int cpt, int type, int objnum, int objsz)
592 {
593         int     rc = 0;
594         int     i;
595
596         LASSERT(rec->rec_type == 0);
597
598         rec->rec_type = type;
599         INIT_LIST_HEAD(&rec->rec_active);
600
601 #ifdef LNET_USE_LIB_FREELIST
602         memset(&rec->rec_freelist, 0, sizeof(rec->rec_freelist));
603         rc = lnet_freelist_init(&rec->rec_freelist, objnum, objsz);
604         if (rc != 0)
605                 goto out;
606 #endif
607         rec->rec_lh_cookie = (cpt << LNET_COOKIE_TYPE_BITS) | type;
608
609         /* Arbitrary choice of hash table size */
610         LIBCFS_CPT_ALLOC(rec->rec_lh_hash, lnet_cpt_table(), cpt,
611                          LNET_LH_HASH_SIZE * sizeof(rec->rec_lh_hash[0]));
612         if (rec->rec_lh_hash == NULL) {
613                 rc = -ENOMEM;
614                 goto out;
615         }
616
617         for (i = 0; i < LNET_LH_HASH_SIZE; i++)
618                 INIT_LIST_HEAD(&rec->rec_lh_hash[i]);
619
620         return 0;
621
622 out:
623         CERROR("Failed to setup %s resource container\n",
624                lnet_res_type2str(type));
625         lnet_res_container_cleanup(rec);
626         return rc;
627 }
628
629 static void
630 lnet_res_containers_destroy(struct lnet_res_container **recs)
631 {
632         struct lnet_res_container       *rec;
633         int                             i;
634
635         cfs_percpt_for_each(rec, i, recs)
636                 lnet_res_container_cleanup(rec);
637
638         cfs_percpt_free(recs);
639 }
640
641 static struct lnet_res_container **
642 lnet_res_containers_create(int type, int objnum, int objsz)
643 {
644         struct lnet_res_container       **recs;
645         struct lnet_res_container       *rec;
646         int                             rc;
647         int                             i;
648
649         recs = cfs_percpt_alloc(lnet_cpt_table(), sizeof(*rec));
650         if (recs == NULL) {
651                 CERROR("Failed to allocate %s resource containers\n",
652                        lnet_res_type2str(type));
653                 return NULL;
654         }
655
656         cfs_percpt_for_each(rec, i, recs) {
657                 rc = lnet_res_container_setup(rec, i, type, objnum, objsz);
658                 if (rc != 0) {
659                         lnet_res_containers_destroy(recs);
660                         return NULL;
661                 }
662         }
663
664         return recs;
665 }
666
667 lnet_libhandle_t *
668 lnet_res_lh_lookup(struct lnet_res_container *rec, __u64 cookie)
669 {
670         /* ALWAYS called with lnet_res_lock held */
671         struct list_head        *head;
672         lnet_libhandle_t        *lh;
673         unsigned int            hash;
674
675         if ((cookie & LNET_COOKIE_MASK) != rec->rec_type)
676                 return NULL;
677
678         hash = cookie >> (LNET_COOKIE_TYPE_BITS + LNET_CPT_BITS);
679         head = &rec->rec_lh_hash[hash & LNET_LH_HASH_MASK];
680
681         list_for_each_entry(lh, head, lh_hash_chain) {
682                 if (lh->lh_cookie == cookie)
683                         return lh;
684         }
685
686         return NULL;
687 }
688
689 void
690 lnet_res_lh_initialize(struct lnet_res_container *rec, lnet_libhandle_t *lh)
691 {
692         /* ALWAYS called with lnet_res_lock held */
693         unsigned int    ibits = LNET_COOKIE_TYPE_BITS + LNET_CPT_BITS;
694         unsigned int    hash;
695
696         lh->lh_cookie = rec->rec_lh_cookie;
697         rec->rec_lh_cookie += 1 << ibits;
698
699         hash = (lh->lh_cookie >> ibits) & LNET_LH_HASH_MASK;
700
701         list_add(&lh->lh_hash_chain, &rec->rec_lh_hash[hash]);
702 }
703
704 #ifndef __KERNEL__
705 /**
706  * Reserved API - do not use.
707  * Temporary workaround to allow uOSS and test programs force server
708  * mode in userspace. See comments near ln_server_mode_flag in
709  * lnet/lib-types.h */
710
711 void
712 lnet_server_mode() {
713         the_lnet.ln_server_mode_flag = 1;
714 }
715 #endif
716
717 static int lnet_unprepare(void);
718
719 static int
720 lnet_prepare(lnet_pid_t requested_pid)
721 {
722         /* Prepare to bring up the network */
723         struct lnet_res_container **recs;
724         int                       rc = 0;
725
726         if (requested_pid == LNET_PID_ANY) {
727                 /* Don't instantiate LNET just for me */
728                 return -ENETDOWN;
729         }
730
731         LASSERT (the_lnet.ln_refcount == 0);
732
733         the_lnet.ln_routing = 0;
734
735 #ifdef __KERNEL__
736         LASSERT ((requested_pid & LNET_PID_USERFLAG) == 0);
737         the_lnet.ln_pid = requested_pid;
738 #else
739         if (the_lnet.ln_server_mode_flag) {/* server case (uOSS) */
740                 LASSERT ((requested_pid & LNET_PID_USERFLAG) == 0);
741
742                 if (current_uid() != 0) /* Only root can run user-space server */
743                         return -EPERM;
744                 the_lnet.ln_pid = requested_pid;
745
746         } else {/* client case (liblustre) */
747
748                 /* My PID must be unique on this node and flag I'm userspace */
749                 the_lnet.ln_pid = getpid() | LNET_PID_USERFLAG;
750         }
751 #endif
752
753         INIT_LIST_HEAD(&the_lnet.ln_test_peers);
754         INIT_LIST_HEAD(&the_lnet.ln_nis);
755         INIT_LIST_HEAD(&the_lnet.ln_nis_cpt);
756         INIT_LIST_HEAD(&the_lnet.ln_nis_zombie);
757         INIT_LIST_HEAD(&the_lnet.ln_routers);
758         INIT_LIST_HEAD(&the_lnet.ln_drop_rules);
759         INIT_LIST_HEAD(&the_lnet.ln_delay_rules);
760
761         rc = lnet_create_remote_nets_table();
762         if (rc != 0)
763                 goto failed;
764
765         the_lnet.ln_interface_cookie = lnet_create_interface_cookie();
766
767         the_lnet.ln_counters = cfs_percpt_alloc(lnet_cpt_table(),
768                                                 sizeof(lnet_counters_t));
769         if (the_lnet.ln_counters == NULL) {
770                 CERROR("Failed to allocate counters for LNet\n");
771                 rc = -ENOMEM;
772                 goto failed;
773         }
774
775         rc = lnet_peer_tables_create();
776         if (rc != 0)
777                 goto failed;
778
779         rc = lnet_msg_containers_create();
780         if (rc != 0)
781                 goto failed;
782
783         rc = lnet_res_container_setup(&the_lnet.ln_eq_container, 0,
784                                       LNET_COOKIE_TYPE_EQ, LNET_FL_MAX_EQS,
785                                       sizeof(lnet_eq_t));
786         if (rc != 0)
787                 goto failed;
788
789         recs = lnet_res_containers_create(LNET_COOKIE_TYPE_ME, LNET_FL_MAX_MES,
790                                           sizeof(lnet_me_t));
791         if (recs == NULL)
792                 goto failed;
793
794         the_lnet.ln_me_containers = recs;
795
796         recs = lnet_res_containers_create(LNET_COOKIE_TYPE_MD, LNET_FL_MAX_MDS,
797                                           sizeof(lnet_libmd_t));
798         if (recs == NULL)
799                 goto failed;
800
801         the_lnet.ln_md_containers = recs;
802
803         rc = lnet_portals_create();
804         if (rc != 0) {
805                 CERROR("Failed to create portals for LNet: %d\n", rc);
806                 goto failed;
807         }
808
809         return 0;
810
811  failed:
812         lnet_unprepare();
813         return rc;
814 }
815
816 static int
817 lnet_unprepare (void)
818 {
819         /* NB no LNET_LOCK since this is the last reference.  All LND instances
820          * have shut down already, so it is safe to unlink and free all
821          * descriptors, even those that appear committed to a network op (eg MD
822          * with non-zero pending count) */
823
824         lnet_fail_nid(LNET_NID_ANY, 0);
825
826         LASSERT(the_lnet.ln_refcount == 0);
827         LASSERT(list_empty(&the_lnet.ln_test_peers));
828         LASSERT(list_empty(&the_lnet.ln_nis));
829         LASSERT(list_empty(&the_lnet.ln_nis_cpt));
830         LASSERT(list_empty(&the_lnet.ln_nis_zombie));
831
832         lnet_portals_destroy();
833
834         if (the_lnet.ln_md_containers != NULL) {
835                 lnet_res_containers_destroy(the_lnet.ln_md_containers);
836                 the_lnet.ln_md_containers = NULL;
837         }
838
839         if (the_lnet.ln_me_containers != NULL) {
840                 lnet_res_containers_destroy(the_lnet.ln_me_containers);
841                 the_lnet.ln_me_containers = NULL;
842         }
843
844         lnet_res_container_cleanup(&the_lnet.ln_eq_container);
845
846         lnet_msg_containers_destroy();
847         lnet_peer_tables_destroy();
848         lnet_rtrpools_free(0);
849
850         if (the_lnet.ln_counters != NULL) {
851                 cfs_percpt_free(the_lnet.ln_counters);
852                 the_lnet.ln_counters = NULL;
853         }
854         lnet_destroy_remote_nets_table();
855
856         return 0;
857 }
858
859 lnet_ni_t  *
860 lnet_net2ni_locked(__u32 net, int cpt)
861 {
862         struct list_head *tmp;
863         lnet_ni_t        *ni;
864
865         LASSERT(cpt != LNET_LOCK_EX);
866
867         list_for_each(tmp, &the_lnet.ln_nis) {
868                 ni = list_entry(tmp, lnet_ni_t, ni_list);
869
870                 if (LNET_NIDNET(ni->ni_nid) == net) {
871                         lnet_ni_addref_locked(ni, cpt);
872                         return ni;
873                 }
874         }
875
876         return NULL;
877 }
878
879 lnet_ni_t *
880 lnet_net2ni(__u32 net)
881 {
882         lnet_ni_t *ni;
883
884         lnet_net_lock(0);
885         ni = lnet_net2ni_locked(net, 0);
886         lnet_net_unlock(0);
887
888         return ni;
889 }
890 EXPORT_SYMBOL(lnet_net2ni);
891
892 static unsigned int
893 lnet_nid_cpt_hash(lnet_nid_t nid, unsigned int number)
894 {
895         __u64           key = nid;
896         unsigned int    val;
897
898         LASSERT(number >= 1 && number <= LNET_CPT_NUMBER);
899
900         if (number == 1)
901                 return 0;
902
903         val = hash_long(key, LNET_CPT_BITS);
904         /* NB: LNET_CP_NUMBER doesn't have to be PO2 */
905         if (val < number)
906                 return val;
907
908         return (unsigned int)(key + val + (val >> 1)) % number;
909 }
910
911 int
912 lnet_cpt_of_nid_locked(lnet_nid_t nid)
913 {
914         struct lnet_ni *ni;
915
916         /* must called with hold of lnet_net_lock */
917         if (LNET_CPT_NUMBER == 1)
918                 return 0; /* the only one */
919
920         /* take lnet_net_lock(any) would be OK */
921         if (!list_empty(&the_lnet.ln_nis_cpt)) {
922                 list_for_each_entry(ni, &the_lnet.ln_nis_cpt, ni_cptlist) {
923                         if (LNET_NIDNET(ni->ni_nid) != LNET_NIDNET(nid))
924                                 continue;
925
926                         LASSERT(ni->ni_cpts != NULL);
927                         return ni->ni_cpts[lnet_nid_cpt_hash
928                                            (nid, ni->ni_ncpts)];
929                 }
930         }
931
932         return lnet_nid_cpt_hash(nid, LNET_CPT_NUMBER);
933 }
934
935 int
936 lnet_cpt_of_nid(lnet_nid_t nid)
937 {
938         int     cpt;
939         int     cpt2;
940
941         if (LNET_CPT_NUMBER == 1)
942                 return 0; /* the only one */
943
944         if (list_empty(&the_lnet.ln_nis_cpt))
945                 return lnet_nid_cpt_hash(nid, LNET_CPT_NUMBER);
946
947         cpt = lnet_net_lock_current();
948         cpt2 = lnet_cpt_of_nid_locked(nid);
949         lnet_net_unlock(cpt);
950
951         return cpt2;
952 }
953 EXPORT_SYMBOL(lnet_cpt_of_nid);
954
955 int
956 lnet_islocalnet(__u32 net)
957 {
958         struct lnet_ni  *ni;
959         int             cpt;
960
961         cpt = lnet_net_lock_current();
962
963         ni = lnet_net2ni_locked(net, cpt);
964         if (ni != NULL)
965                 lnet_ni_decref_locked(ni, cpt);
966
967         lnet_net_unlock(cpt);
968
969         return ni != NULL;
970 }
971
972 lnet_ni_t  *
973 lnet_nid2ni_locked(lnet_nid_t nid, int cpt)
974 {
975         struct lnet_ni   *ni;
976         struct list_head *tmp;
977
978         LASSERT(cpt != LNET_LOCK_EX);
979
980         list_for_each(tmp, &the_lnet.ln_nis) {
981                 ni = list_entry(tmp, lnet_ni_t, ni_list);
982
983                 if (ni->ni_nid == nid) {
984                         lnet_ni_addref_locked(ni, cpt);
985                         return ni;
986                 }
987         }
988
989         return NULL;
990 }
991
992 int
993 lnet_islocalnid(lnet_nid_t nid)
994 {
995         struct lnet_ni  *ni;
996         int             cpt;
997
998         cpt = lnet_net_lock_current();
999         ni = lnet_nid2ni_locked(nid, cpt);
1000         if (ni != NULL)
1001                 lnet_ni_decref_locked(ni, cpt);
1002         lnet_net_unlock(cpt);
1003
1004         return ni != NULL;
1005 }
1006
1007 int
1008 lnet_count_acceptor_nis (void)
1009 {
1010         /* Return the # of NIs that need the acceptor. */
1011         int              count = 0;
1012 #if defined(__KERNEL__) || defined(HAVE_LIBPTHREAD)
1013         struct list_head *tmp;
1014         struct lnet_ni   *ni;
1015         int              cpt;
1016
1017         cpt = lnet_net_lock_current();
1018         list_for_each(tmp, &the_lnet.ln_nis) {
1019                 ni = list_entry(tmp, lnet_ni_t, ni_list);
1020
1021                 if (ni->ni_lnd->lnd_accept != NULL)
1022                         count++;
1023         }
1024
1025         lnet_net_unlock(cpt);
1026
1027 #endif /* defined(__KERNEL__) || defined(HAVE_LIBPTHREAD) */
1028         return count;
1029 }
1030
1031 static lnet_ping_info_t *
1032 lnet_ping_info_create(int num_ni)
1033 {
1034         lnet_ping_info_t *ping_info;
1035         unsigned int     infosz;
1036
1037         infosz = offsetof(lnet_ping_info_t, pi_ni[num_ni]);
1038         LIBCFS_ALLOC(ping_info, infosz);
1039         if (ping_info == NULL) {
1040                 CERROR("Can't allocate ping info[%d]\n", num_ni);
1041                 return NULL;
1042         }
1043
1044         ping_info->pi_nnis = num_ni;
1045         ping_info->pi_pid = the_lnet.ln_pid;
1046         ping_info->pi_magic = LNET_PROTO_PING_MAGIC;
1047         ping_info->pi_features = LNET_PING_FEAT_NI_STATUS;
1048
1049         return ping_info;
1050 }
1051
1052 static inline int
1053 lnet_get_ni_count(void)
1054 {
1055         struct lnet_ni *ni;
1056         int            count = 0;
1057
1058         lnet_net_lock(0);
1059
1060         list_for_each_entry(ni, &the_lnet.ln_nis, ni_list)
1061                 count++;
1062
1063         lnet_net_unlock(0);
1064
1065         return count;
1066 }
1067
1068 static inline void
1069 lnet_ping_info_free(lnet_ping_info_t *pinfo)
1070 {
1071         LIBCFS_FREE(pinfo,
1072                     offsetof(lnet_ping_info_t,
1073                              pi_ni[pinfo->pi_nnis]));
1074 }
1075
1076 static void
1077 lnet_ping_info_destroy(void)
1078 {
1079         struct lnet_ni  *ni;
1080
1081         lnet_net_lock(LNET_LOCK_EX);
1082
1083         list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) {
1084                 lnet_ni_lock(ni);
1085                 ni->ni_status = NULL;
1086                 lnet_ni_unlock(ni);
1087         }
1088
1089         lnet_ping_info_free(the_lnet.ln_ping_info);
1090         the_lnet.ln_ping_info = NULL;
1091
1092         lnet_net_unlock(LNET_LOCK_EX);
1093 }
1094
1095 static void
1096 lnet_ping_event_handler(lnet_event_t *event)
1097 {
1098         lnet_ping_info_t *pinfo = event->md.user_ptr;
1099
1100         if (event->unlinked)
1101                 pinfo->pi_features = LNET_PING_FEAT_INVAL;
1102 }
1103
1104 static int
1105 lnet_ping_info_setup(lnet_ping_info_t **ppinfo, lnet_handle_md_t *md_handle,
1106                      int ni_count, bool set_eq)
1107 {
1108         lnet_handle_me_t  me_handle;
1109         lnet_process_id_t id = {LNET_NID_ANY, LNET_PID_ANY};
1110         lnet_md_t         md = {NULL};
1111         int               rc, rc2;
1112
1113         if (set_eq) {
1114                 rc = LNetEQAlloc(0, lnet_ping_event_handler,
1115                                  &the_lnet.ln_ping_target_eq);
1116                 if (rc != 0) {
1117                         CERROR("Can't allocate ping EQ: %d\n", rc);
1118                         return rc;
1119                 }
1120         }
1121
1122         *ppinfo = lnet_ping_info_create(ni_count);
1123         if (*ppinfo == NULL) {
1124                 rc = -ENOMEM;
1125                 goto failed_0;
1126         }
1127
1128         rc = LNetMEAttach(LNET_RESERVED_PORTAL, id,
1129                           LNET_PROTO_PING_MATCHBITS, 0,
1130                           LNET_UNLINK, LNET_INS_AFTER,
1131                           &me_handle);
1132         if (rc != 0) {
1133                 CERROR("Can't create ping ME: %d\n", rc);
1134                 goto failed_1;
1135         }
1136
1137         /* initialize md content */
1138         md.start     = *ppinfo;
1139         md.length    = offsetof(lnet_ping_info_t,
1140                                 pi_ni[(*ppinfo)->pi_nnis]);
1141         md.threshold = LNET_MD_THRESH_INF;
1142         md.max_size  = 0;
1143         md.options   = LNET_MD_OP_GET | LNET_MD_TRUNCATE |
1144                        LNET_MD_MANAGE_REMOTE;
1145         md.user_ptr  = NULL;
1146         md.eq_handle = the_lnet.ln_ping_target_eq;
1147         md.user_ptr = *ppinfo;
1148
1149         rc = LNetMDAttach(me_handle, md, LNET_RETAIN, md_handle);
1150         if (rc != 0) {
1151                 CERROR("Can't attach ping MD: %d\n", rc);
1152                 goto failed_2;
1153         }
1154
1155         return 0;
1156
1157 failed_2:
1158         rc2 = LNetMEUnlink(me_handle);
1159         LASSERT(rc2 == 0);
1160 failed_1:
1161         lnet_ping_info_free(*ppinfo);
1162         *ppinfo = NULL;
1163 failed_0:
1164         if (set_eq)
1165                 LNetEQFree(the_lnet.ln_ping_target_eq);
1166         return rc;
1167 }
1168
1169 static void
1170 lnet_ping_md_unlink(lnet_ping_info_t *pinfo, lnet_handle_md_t *md_handle)
1171 {
1172         sigset_t        blocked = cfs_block_allsigs();
1173
1174         LNetMDUnlink(*md_handle);
1175         LNetInvalidateHandle(md_handle);
1176
1177         /* NB md could be busy; this just starts the unlink */
1178         while (pinfo->pi_features != LNET_PING_FEAT_INVAL) {
1179                 CDEBUG(D_NET, "Still waiting for ping MD to unlink\n");
1180                 cfs_pause(cfs_time_seconds(1));
1181         }
1182
1183         cfs_restore_sigs(blocked);
1184 }
1185
1186 static void
1187 lnet_ping_info_install_locked(lnet_ping_info_t *ping_info)
1188 {
1189         int                     i;
1190         lnet_ni_t               *ni;
1191         lnet_ni_status_t        *ns;
1192
1193         i = 0;
1194         list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) {
1195                 LASSERT(i < ping_info->pi_nnis);
1196
1197                 ns = &ping_info->pi_ni[i];
1198
1199                 ns->ns_nid = ni->ni_nid;
1200
1201                 lnet_ni_lock(ni);
1202                 ns->ns_status = (ni->ni_status != NULL) ?
1203                                 ni->ni_status->ns_status : LNET_NI_STATUS_UP;
1204                 ni->ni_status = ns;
1205                 lnet_ni_unlock(ni);
1206
1207                 i++;
1208         }
1209 }
1210
1211 static void
1212 lnet_ping_target_update(lnet_ping_info_t *pinfo, lnet_handle_md_t md_handle)
1213 {
1214         lnet_ping_info_t *old_pinfo = NULL;
1215         lnet_handle_md_t old_md;
1216
1217         /* switch the NIs to point to the new ping info created */
1218         lnet_net_lock(LNET_LOCK_EX);
1219
1220         if (!the_lnet.ln_routing)
1221                 pinfo->pi_features |= LNET_PING_FEAT_RTE_DISABLED;
1222         lnet_ping_info_install_locked(pinfo);
1223
1224         if (the_lnet.ln_ping_info != NULL) {
1225                 old_pinfo = the_lnet.ln_ping_info;
1226                 old_md = the_lnet.ln_ping_target_md;
1227         }
1228         the_lnet.ln_ping_target_md = md_handle;
1229         the_lnet.ln_ping_info = pinfo;
1230
1231         lnet_net_unlock(LNET_LOCK_EX);
1232
1233         if (old_pinfo != NULL) {
1234                 /* unlink the old ping info */
1235                 lnet_ping_md_unlink(old_pinfo, &old_md);
1236                 lnet_ping_info_free(old_pinfo);
1237         }
1238 }
1239
1240 static void
1241 lnet_ping_target_fini(void)
1242 {
1243         int             rc;
1244
1245         lnet_ping_md_unlink(the_lnet.ln_ping_info,
1246                             &the_lnet.ln_ping_target_md);
1247
1248         rc = LNetEQFree(the_lnet.ln_ping_target_eq);
1249         LASSERT(rc == 0);
1250
1251         lnet_ping_info_destroy();
1252 }
1253
1254 static int
1255 lnet_ni_tq_credits(lnet_ni_t *ni)
1256 {
1257         int     credits;
1258
1259         LASSERT(ni->ni_ncpts >= 1);
1260
1261         if (ni->ni_ncpts == 1)
1262                 return ni->ni_maxtxcredits;
1263
1264         credits = ni->ni_maxtxcredits / ni->ni_ncpts;
1265         credits = max(credits, 8 * ni->ni_peertxcredits);
1266         credits = min(credits, ni->ni_maxtxcredits);
1267
1268         return credits;
1269 }
1270
1271 static void
1272 lnet_ni_unlink_locked(lnet_ni_t *ni)
1273 {
1274         if (!list_empty(&ni->ni_cptlist)) {
1275                 list_del_init(&ni->ni_cptlist);
1276                 lnet_ni_decref_locked(ni, 0);
1277         }
1278
1279         /* move it to zombie list and nobody can find it anymore */
1280         LASSERT(!list_empty(&ni->ni_list));
1281         list_move(&ni->ni_list, &the_lnet.ln_nis_zombie);
1282         lnet_ni_decref_locked(ni, 0);   /* drop ln_nis' ref */
1283 }
1284
1285 static void
1286 lnet_clear_zombies_nis_locked(void)
1287 {
1288         int             i;
1289         int             islo;
1290         lnet_ni_t       *ni;
1291
1292         /* Now wait for the NI's I just nuked to show up on ln_zombie_nis
1293          * and shut them down in guaranteed thread context */
1294         i = 2;
1295         while (!list_empty(&the_lnet.ln_nis_zombie)) {
1296                 int     *ref;
1297                 int     j;
1298
1299                 ni = list_entry(the_lnet.ln_nis_zombie.next,
1300                                 lnet_ni_t, ni_list);
1301                 list_del_init(&ni->ni_list);
1302                 cfs_percpt_for_each(ref, j, ni->ni_refs) {
1303                         if (*ref == 0)
1304                                 continue;
1305                         /* still busy, add it back to zombie list */
1306                         list_add(&ni->ni_list, &the_lnet.ln_nis_zombie);
1307                         break;
1308                 }
1309
1310                 if (!list_empty(&ni->ni_list)) {
1311                         lnet_net_unlock(LNET_LOCK_EX);
1312                         ++i;
1313                         if ((i & (-i)) == i) {
1314                                 CDEBUG(D_WARNING,
1315                                        "Waiting for zombie LNI %s\n",
1316                                        libcfs_nid2str(ni->ni_nid));
1317                         }
1318                         cfs_pause(cfs_time_seconds(1));
1319                         lnet_net_lock(LNET_LOCK_EX);
1320                         continue;
1321                 }
1322
1323                 ni->ni_lnd->lnd_refcount--;
1324                 lnet_net_unlock(LNET_LOCK_EX);
1325
1326                 islo = ni->ni_lnd->lnd_type == LOLND;
1327
1328                 LASSERT(!in_interrupt());
1329                 (ni->ni_lnd->lnd_shutdown)(ni);
1330
1331                 /* can't deref lnd anymore now; it might have unregistered
1332                  * itself...  */
1333
1334                 if (!islo)
1335                         CDEBUG(D_LNI, "Removed LNI %s\n",
1336                               libcfs_nid2str(ni->ni_nid));
1337
1338                 lnet_ni_free(ni);
1339                 i = 2;
1340                 lnet_net_lock(LNET_LOCK_EX);
1341         }
1342 }
1343
1344 static void
1345 lnet_shutdown_lndnis(void)
1346 {
1347         int             i;
1348         lnet_ni_t       *ni;
1349
1350         /* NB called holding the global mutex */
1351
1352         /* All quiet on the API front */
1353         LASSERT(!the_lnet.ln_shutdown);
1354         LASSERT(the_lnet.ln_refcount == 0);
1355         LASSERT(list_empty(&the_lnet.ln_nis_zombie));
1356
1357         lnet_net_lock(LNET_LOCK_EX);
1358         the_lnet.ln_shutdown = 1;       /* flag shutdown */
1359
1360         /* Unlink NIs from the global table */
1361         while (!list_empty(&the_lnet.ln_nis)) {
1362                 ni = list_entry(the_lnet.ln_nis.next,
1363                                 lnet_ni_t, ni_list);
1364                 lnet_ni_unlink_locked(ni);
1365         }
1366
1367         /* Drop the cached eqwait NI. */
1368         if (the_lnet.ln_eq_waitni != NULL) {
1369                 lnet_ni_decref_locked(the_lnet.ln_eq_waitni, 0);
1370                 the_lnet.ln_eq_waitni = NULL;
1371         }
1372
1373         /* Drop the cached loopback NI. */
1374         if (the_lnet.ln_loni != NULL) {
1375                 lnet_ni_decref_locked(the_lnet.ln_loni, 0);
1376                 the_lnet.ln_loni = NULL;
1377         }
1378
1379         lnet_net_unlock(LNET_LOCK_EX);
1380
1381         /* Clear lazy portals and drop delayed messages which hold refs
1382          * on their lnet_msg_t::msg_rxpeer */
1383         for (i = 0; i < the_lnet.ln_nportals; i++)
1384                 LNetClearLazyPortal(i);
1385
1386         /* Clear the peer table and wait for all peers to go (they hold refs on
1387          * their NIs) */
1388         lnet_peer_tables_cleanup(NULL);
1389
1390         lnet_net_lock(LNET_LOCK_EX);
1391
1392         lnet_clear_zombies_nis_locked();
1393         the_lnet.ln_shutdown = 0;
1394         lnet_net_unlock(LNET_LOCK_EX);
1395 }
1396
1397 /* shutdown down the NI and release refcount */
1398 static void
1399 lnet_shutdown_lndni(struct lnet_ni *ni)
1400 {
1401         lnet_net_lock(LNET_LOCK_EX);
1402         lnet_ni_unlink_locked(ni);
1403         lnet_net_unlock(LNET_LOCK_EX);
1404
1405         /* Do peer table cleanup for this ni */
1406         lnet_peer_tables_cleanup(ni);
1407
1408         lnet_net_lock(LNET_LOCK_EX);
1409         lnet_clear_zombies_nis_locked();
1410         lnet_net_unlock(LNET_LOCK_EX);
1411 }
1412
1413 static int
1414 lnet_startup_lndni(struct lnet_ni *ni, __s32 peer_timeout,
1415                    __s32 peer_cr, __s32 peer_buf_cr, __s32 credits)
1416 {
1417         int                     rc = 0;
1418         int                     lnd_type;
1419         lnd_t                   *lnd;
1420         struct lnet_tx_queue    *tq;
1421         int                     i;
1422
1423         lnd_type = LNET_NETTYP(LNET_NIDNET(ni->ni_nid));
1424
1425         LASSERT(libcfs_isknown_lnd(lnd_type));
1426
1427         if (lnd_type == CIBLND || lnd_type == OPENIBLND ||
1428             lnd_type == IIBLND || lnd_type == VIBLND) {
1429                 CERROR("LND %s obsoleted\n", libcfs_lnd2str(lnd_type));
1430                 goto failed0;
1431         }
1432
1433         /* Make sure this new NI is unique. */
1434         lnet_net_lock(LNET_LOCK_EX);
1435         if (!lnet_net_unique(LNET_NIDNET(ni->ni_nid), &the_lnet.ln_nis)) {
1436                 if (lnd_type == LOLND) {
1437                         lnet_net_unlock(LNET_LOCK_EX);
1438                         lnet_ni_free(ni);
1439                         return 0;
1440                 }
1441                 lnet_net_unlock(LNET_LOCK_EX);
1442
1443                 CERROR("Net %s is not unique\n",
1444                        libcfs_net2str(LNET_NIDNET(ni->ni_nid)));
1445                 goto failed0;
1446         }
1447         lnet_net_unlock(LNET_LOCK_EX);
1448
1449         LNET_MUTEX_LOCK(&the_lnet.ln_lnd_mutex);
1450         lnd = lnet_find_lnd_by_type(lnd_type);
1451
1452 #ifdef __KERNEL__
1453         if (lnd == NULL) {
1454                 LNET_MUTEX_UNLOCK(&the_lnet.ln_lnd_mutex);
1455                 rc = request_module("%s",
1456                                     libcfs_lnd2modname(lnd_type));
1457                 LNET_MUTEX_LOCK(&the_lnet.ln_lnd_mutex);
1458
1459                 lnd = lnet_find_lnd_by_type(lnd_type);
1460                 if (lnd == NULL) {
1461                         LNET_MUTEX_UNLOCK(&the_lnet.ln_lnd_mutex);
1462                         CERROR("Can't load LND %s, module %s, rc=%d\n",
1463                                libcfs_lnd2str(lnd_type),
1464                                libcfs_lnd2modname(lnd_type), rc);
1465 #ifndef HAVE_MODULE_LOADING_SUPPORT
1466                         LCONSOLE_ERROR_MSG(0x104, "Your kernel must be "
1467                                            "compiled with kernel module "
1468                                            "loading support.");
1469 #endif
1470                         goto failed0;
1471                 }
1472         }
1473 #else
1474         if (lnd == NULL) {
1475                 LNET_MUTEX_UNLOCK(&the_lnet.ln_lnd_mutex);
1476                 CERROR("LND %s not supported\n",
1477                         libcfs_lnd2str(lnd_type));
1478                 goto failed0;
1479         }
1480 #endif
1481
1482         lnet_net_lock(LNET_LOCK_EX);
1483         lnd->lnd_refcount++;
1484         lnet_net_unlock(LNET_LOCK_EX);
1485
1486         ni->ni_lnd = lnd;
1487
1488         rc = (lnd->lnd_startup)(ni);
1489
1490         LNET_MUTEX_UNLOCK(&the_lnet.ln_lnd_mutex);
1491
1492         if (rc != 0) {
1493                 LCONSOLE_ERROR_MSG(0x105, "Error %d starting up LNI %s\n",
1494                                    rc, libcfs_lnd2str(lnd->lnd_type));
1495                 lnet_net_lock(LNET_LOCK_EX);
1496                 lnd->lnd_refcount--;
1497                 lnet_net_unlock(LNET_LOCK_EX);
1498                 goto failed0;
1499         }
1500
1501         /* If given some LND tunable parameters, parse those now to
1502          * override the values in the NI structure. */
1503         if (peer_buf_cr >= 0)
1504                 ni->ni_peerrtrcredits = peer_buf_cr;
1505         if (peer_timeout >= 0)
1506                 ni->ni_peertimeout = peer_timeout;
1507         /*
1508          * TODO
1509          * Note: For now, don't allow the user to change
1510          * peertxcredits as this number is used in the
1511          * IB LND to control queue depth.
1512          * if (peer_cr != -1)
1513          *      ni->ni_peertxcredits = peer_cr;
1514          */
1515         if (credits >= 0)
1516                 ni->ni_maxtxcredits = credits;
1517
1518         LASSERT(ni->ni_peertimeout <= 0 || lnd->lnd_query != NULL);
1519
1520         lnet_net_lock(LNET_LOCK_EX);
1521         /* refcount for ln_nis */
1522         lnet_ni_addref_locked(ni, 0);
1523         list_add_tail(&ni->ni_list, &the_lnet.ln_nis);
1524         if (ni->ni_cpts != NULL) {
1525                 lnet_ni_addref_locked(ni, 0);
1526                 list_add_tail(&ni->ni_cptlist, &the_lnet.ln_nis_cpt);
1527         }
1528
1529         lnet_net_unlock(LNET_LOCK_EX);
1530
1531         if (lnd->lnd_type == LOLND) {
1532                 lnet_ni_addref(ni);
1533                 LASSERT(the_lnet.ln_loni == NULL);
1534                 the_lnet.ln_loni = ni;
1535                 return 0;
1536         }
1537
1538 #ifndef __KERNEL__
1539         if (lnd->lnd_wait != NULL) {
1540                 if (the_lnet.ln_eq_waitni == NULL) {
1541                         lnet_ni_addref(ni);
1542                         the_lnet.ln_eq_waitni = ni;
1543                 }
1544         } else {
1545 # ifndef HAVE_LIBPTHREAD
1546                 LCONSOLE_ERROR_MSG(0x106, "LND %s not supported in a "
1547                                         "single-threaded runtime\n",
1548                                         libcfs_lnd2str(lnd_type));
1549                 /* shutdown the NI since if we get here then it must've already
1550                  * been started
1551                  */
1552                 lnet_shutdown_lndni(ni);
1553                 return -EINVAL;
1554 # endif
1555         }
1556 #endif
1557         if (ni->ni_peertxcredits == 0 || ni->ni_maxtxcredits == 0) {
1558                 LCONSOLE_ERROR_MSG(0x107, "LNI %s has no %scredits\n",
1559                                    libcfs_lnd2str(lnd->lnd_type),
1560                                    ni->ni_peertxcredits == 0 ? 
1561                                         "" : "per-peer ");
1562                 /* shutdown the NI since if we get here then it must've already
1563                  * been started
1564                  */
1565                 lnet_shutdown_lndni(ni);
1566                 return -EINVAL;
1567         }
1568
1569         cfs_percpt_for_each(tq, i, ni->ni_tx_queues) {
1570                 tq->tq_credits_min =
1571                 tq->tq_credits_max =
1572                 tq->tq_credits = lnet_ni_tq_credits(ni);
1573         }
1574
1575         CDEBUG(D_LNI, "Added LNI %s [%d/%d/%d/%d]\n",
1576                 libcfs_nid2str(ni->ni_nid), ni->ni_peertxcredits,
1577                 lnet_ni_tq_credits(ni) * LNET_CPT_NUMBER,
1578                 ni->ni_peerrtrcredits, ni->ni_peertimeout);
1579
1580         return 0;
1581 failed0:
1582         lnet_ni_free(ni);
1583         return -EINVAL;
1584 }
1585
1586 static int
1587 lnet_startup_lndnis(struct list_head *nilist)
1588 {
1589         struct lnet_ni          *ni;
1590         int                     rc;
1591         int                     lnd_type;
1592         int                     ni_count = 0;
1593
1594         while (!list_empty(nilist)) {
1595                 ni = list_entry(nilist->next, lnet_ni_t, ni_list);
1596                 list_del(&ni->ni_list);
1597                 rc = lnet_startup_lndni(ni, -1, -1, -1, -1);
1598
1599                 if (rc < 0)
1600                         goto failed;
1601
1602                 ni_count++;
1603         }
1604
1605         if (the_lnet.ln_eq_waitni != NULL && ni_count > 1) {
1606                 lnd_type = the_lnet.ln_eq_waitni->ni_lnd->lnd_type;
1607                 LCONSOLE_ERROR_MSG(0x109, "LND %s can only run single-network"
1608                                    "\n",
1609                                    libcfs_lnd2str(lnd_type));
1610                 rc = -EINVAL;
1611                 goto failed;
1612         }
1613
1614         return ni_count;
1615 failed:
1616         lnet_shutdown_lndnis();
1617
1618         return rc;
1619 }
1620
1621 /**
1622  * Initialize LNet library.
1623  *
1624  * Only userspace program needs to call this function - it's automatically
1625  * called in the kernel at module loading time. Caller has to call LNetFini()
1626  * after a call to LNetInit(), if and only if the latter returned 0. It must
1627  * be called exactly once.
1628  *
1629  * \return 0 on success, and -ve on failures.
1630  */
1631 int
1632 LNetInit(void)
1633 {
1634         int     rc;
1635
1636         lnet_assert_wire_constants();
1637         LASSERT(!the_lnet.ln_init);
1638
1639         memset(&the_lnet, 0, sizeof(the_lnet));
1640
1641         /* refer to global cfs_cpt_table for now */
1642         the_lnet.ln_cpt_table   = cfs_cpt_table;
1643         the_lnet.ln_cpt_number  = cfs_cpt_number(cfs_cpt_table);
1644
1645         LASSERT(the_lnet.ln_cpt_number > 0);
1646         if (the_lnet.ln_cpt_number > LNET_CPT_MAX) {
1647                 /* we are under risk of consuming all lh_cookie */
1648                 CERROR("Can't have %d CPTs for LNet (max allowed is %d), "
1649                        "please change setting of CPT-table and retry\n",
1650                        the_lnet.ln_cpt_number, LNET_CPT_MAX);
1651                 return -1;
1652         }
1653
1654         while ((1 << the_lnet.ln_cpt_bits) < the_lnet.ln_cpt_number)
1655                 the_lnet.ln_cpt_bits++;
1656
1657         rc = lnet_create_locks();
1658         if (rc != 0) {
1659                 CERROR("Can't create LNet global locks: %d\n", rc);
1660                 return -1;
1661         }
1662
1663         the_lnet.ln_refcount = 0;
1664         the_lnet.ln_init = 1;
1665         LNetInvalidateHandle(&the_lnet.ln_rc_eqh);
1666         INIT_LIST_HEAD(&the_lnet.ln_lnds);
1667         INIT_LIST_HEAD(&the_lnet.ln_rcd_zombie);
1668         INIT_LIST_HEAD(&the_lnet.ln_rcd_deathrow);
1669
1670 #ifdef __KERNEL__
1671         /* The hash table size is the number of bits it takes to express the set
1672          * ln_num_routes, minus 1 (better to under estimate than over so we
1673          * don't waste memory). */
1674         if (rnet_htable_size <= 0)
1675                 rnet_htable_size = LNET_REMOTE_NETS_HASH_DEFAULT;
1676         else if (rnet_htable_size > LNET_REMOTE_NETS_HASH_MAX)
1677                 rnet_htable_size = LNET_REMOTE_NETS_HASH_MAX;
1678         the_lnet.ln_remote_nets_hbits = max_t(int, 1,
1679                                            order_base_2(rnet_htable_size) - 1);
1680
1681         /* All LNDs apart from the LOLND are in separate modules.  They
1682          * register themselves when their module loads, and unregister
1683          * themselves when their module is unloaded. */
1684 #else
1685         the_lnet.ln_remote_nets_hbits = 8;
1686
1687         /* Register LNDs
1688          * NB the order here determines default 'networks=' order */
1689 # ifdef HAVE_LIBPTHREAD
1690         LNET_REGISTER_ULND(the_tcplnd);
1691 # endif
1692 #endif
1693         lnet_register_lnd(&the_lolnd);
1694         return 0;
1695 }
1696 EXPORT_SYMBOL(LNetInit);
1697
1698 /**
1699  * Finalize LNet library.
1700  *
1701  * Only userspace program needs to call this function. It can be called
1702  * at most once.
1703  *
1704  * \pre LNetInit() called with success.
1705  * \pre All LNet users called LNetNIFini() for matching LNetNIInit() calls.
1706  */
1707 void
1708 LNetFini(void)
1709 {
1710         LASSERT(the_lnet.ln_init);
1711         LASSERT(the_lnet.ln_refcount == 0);
1712
1713         while (!list_empty(&the_lnet.ln_lnds))
1714                 lnet_unregister_lnd(list_entry(the_lnet.ln_lnds.next,
1715                                                lnd_t, lnd_list));
1716         lnet_destroy_locks();
1717
1718         the_lnet.ln_init = 0;
1719 }
1720 EXPORT_SYMBOL(LNetFini);
1721
1722 /**
1723  * Set LNet PID and start LNet interfaces, routing, and forwarding.
1724  *
1725  * Userspace program should call this after a successful call to LNetInit().
1726  * Users must call this function at least once before any other functions.
1727  * For each successful call there must be a corresponding call to
1728  * LNetNIFini(). For subsequent calls to LNetNIInit(), \a requested_pid is
1729  * ignored.
1730  *
1731  * The PID used by LNet may be different from the one requested.
1732  * See LNetGetId().
1733  *
1734  * \param requested_pid PID requested by the caller.
1735  *
1736  * \return >= 0 on success, and < 0 error code on failures.
1737  */
1738 int
1739 LNetNIInit(lnet_pid_t requested_pid)
1740 {
1741         int                     im_a_router = 0;
1742         int                     rc, rc2;
1743         int                     ni_count;
1744         lnet_ping_info_t        *pinfo;
1745         lnet_handle_md_t        md_handle;
1746         struct list_head        net_head;
1747
1748         INIT_LIST_HEAD(&net_head);
1749
1750         LNET_MUTEX_LOCK(&the_lnet.ln_api_mutex);
1751
1752         LASSERT(the_lnet.ln_init);
1753         CDEBUG(D_OTHER, "refs %d\n", the_lnet.ln_refcount);
1754
1755         if (the_lnet.ln_refcount > 0) {
1756                 rc = the_lnet.ln_refcount++;
1757                 LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex);
1758                 return rc;
1759         }
1760
1761         rc = lnet_prepare(requested_pid);
1762         if (rc != 0) {
1763                 LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex);
1764                 return rc;
1765         }
1766
1767         /* Add in the loopback network */
1768         if (lnet_ni_alloc(LNET_MKNET(LOLND, 0), NULL, &net_head) == NULL) {
1769                 rc = -ENOMEM;
1770                 goto failed0;
1771         }
1772
1773         /* If LNet is being initialized via DLC it is possible
1774          * that the user requests not to load module parameters (ones which
1775          * are supported by DLC) on initialization.  Therefore, make sure not
1776          * to load networks, routes and forwarding from module parameters
1777          * in this case.  On cleanup in case of failure only clean up
1778          * routes if it has been loaded */
1779         if (!the_lnet.ln_nis_from_mod_params) {
1780                 rc = lnet_parse_networks(&net_head,
1781                                          lnet_get_networks());
1782                 if (rc < 0)
1783                         goto failed0;
1784         }
1785
1786         ni_count = lnet_startup_lndnis(&net_head);
1787         if (ni_count < 0) {
1788                 rc = ni_count;
1789                 goto failed0;
1790         }
1791
1792         if (!the_lnet.ln_nis_from_mod_params) {
1793                 rc = lnet_parse_routes(lnet_get_routes(), &im_a_router);
1794                 if (rc != 0)
1795                         goto failed1;
1796
1797                 rc = lnet_check_routes();
1798                 if (rc != 0)
1799                         goto failed2;
1800
1801                 rc = lnet_rtrpools_alloc(im_a_router);
1802                 if (rc != 0)
1803                         goto failed2;
1804         }
1805
1806         rc = lnet_acceptor_start();
1807         if (rc != 0)
1808                 goto failed2;
1809         the_lnet.ln_refcount = 1;
1810         /* Now I may use my own API functions... */
1811
1812         rc = lnet_ping_info_setup(&pinfo, &md_handle, ni_count, true);
1813         if (rc != 0)
1814                 goto failed3;
1815
1816         lnet_ping_target_update(pinfo, md_handle);
1817
1818         rc = lnet_router_checker_start();
1819         if (rc != 0)
1820                 goto failed4;
1821
1822         lnet_fault_init();
1823         lnet_proc_init();
1824
1825         LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex);
1826
1827         return 0;
1828
1829 failed4:
1830         lnet_ping_md_unlink(pinfo, &md_handle);
1831         lnet_ping_info_free(pinfo);
1832         rc2 = LNetEQFree(the_lnet.ln_ping_target_eq);
1833         LASSERT(rc2 == 0);
1834 failed3:
1835         the_lnet.ln_refcount = 0;
1836         lnet_acceptor_stop();
1837 failed2:
1838         if (!the_lnet.ln_nis_from_mod_params)
1839                 lnet_destroy_routes();
1840 failed1:
1841         lnet_shutdown_lndnis();
1842 failed0:
1843         lnet_unprepare();
1844         LASSERT(rc < 0);
1845         LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex);
1846         while (!list_empty(&net_head)) {
1847                 struct lnet_ni *ni;
1848                 ni = list_entry(net_head.next, struct lnet_ni, ni_list);
1849                 list_del_init(&ni->ni_list);
1850                 lnet_ni_free(ni);
1851         }
1852         return rc;
1853 }
1854 EXPORT_SYMBOL(LNetNIInit);
1855
1856 /**
1857  * Stop LNet interfaces, routing, and forwarding.
1858  *
1859  * Users must call this function once for each successful call to LNetNIInit().
1860  * Once the LNetNIFini() operation has been started, the results of pending
1861  * API operations are undefined.
1862  *
1863  * \return always 0 for current implementation.
1864  */
1865 int
1866 LNetNIFini()
1867 {
1868         LNET_MUTEX_LOCK(&the_lnet.ln_api_mutex);
1869
1870         LASSERT (the_lnet.ln_init);
1871         LASSERT (the_lnet.ln_refcount > 0);
1872
1873         if (the_lnet.ln_refcount != 1) {
1874                 the_lnet.ln_refcount--;
1875         } else {
1876                 LASSERT(!the_lnet.ln_niinit_self);
1877
1878                 lnet_fault_fini();
1879
1880                 lnet_proc_fini();
1881                 lnet_router_checker_stop();
1882                 lnet_ping_target_fini();
1883
1884                 /* Teardown fns that use my own API functions BEFORE here */
1885                 the_lnet.ln_refcount = 0;
1886
1887                 lnet_acceptor_stop();
1888                 lnet_destroy_routes();
1889                 lnet_shutdown_lndnis();
1890                 lnet_unprepare();
1891         }
1892
1893         LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex);
1894         return 0;
1895 }
1896 EXPORT_SYMBOL(LNetNIFini);
1897
1898 /**
1899  * Grabs the ni data from the ni structure and fills the out
1900  * parameters
1901  *
1902  * \param[in] ni network        interface structure
1903  * \param[out] cpt_count        the number of cpts the ni is on
1904  * \param[out] nid              Network Interface ID
1905  * \param[out] peer_timeout     NI peer timeout
1906  * \param[out] peer_tx_crdits   NI peer transmit credits
1907  * \param[out] peer_rtr_credits NI peer router credits
1908  * \param[out] max_tx_credits   NI max transmit credit
1909  * \param[out] net_config       Network configuration
1910  */
1911 static void
1912 lnet_fill_ni_info(struct lnet_ni *ni, __u32 *cpt_count, __u64 *nid,
1913                   int *peer_timeout, int *peer_tx_credits,
1914                   int *peer_rtr_credits, int *max_tx_credits,
1915                   struct lnet_ioctl_net_config *net_config)
1916 {
1917         int i;
1918
1919         if (ni == NULL)
1920                 return;
1921
1922         if (net_config == NULL)
1923                 return;
1924
1925         CLASSERT(ARRAY_SIZE(ni->ni_interfaces) ==
1926                  ARRAY_SIZE(net_config->ni_interfaces));
1927
1928         if (ni->ni_interfaces[0] != NULL) {
1929                 for (i = 0; i < ARRAY_SIZE(ni->ni_interfaces); i++) {
1930                         if (ni->ni_interfaces[i] != NULL) {
1931                                 strncpy(net_config->ni_interfaces[i],
1932                                         ni->ni_interfaces[i],
1933                                         sizeof(net_config->ni_interfaces[i]));
1934                         }
1935                 }
1936         }
1937
1938         *nid = ni->ni_nid;
1939         *peer_timeout = ni->ni_peertimeout;
1940         *peer_tx_credits = ni->ni_peertxcredits;
1941         *peer_rtr_credits = ni->ni_peerrtrcredits;
1942         *max_tx_credits = ni->ni_maxtxcredits;
1943
1944         net_config->ni_status = ni->ni_status->ns_status;
1945
1946         for (i = 0;
1947              ni->ni_cpts != NULL && i < ni->ni_ncpts &&
1948              i < LNET_MAX_SHOW_NUM_CPT;
1949              i++)
1950                 net_config->ni_cpts[i] = ni->ni_cpts[i];
1951
1952         *cpt_count = ni->ni_ncpts;
1953 }
1954
1955 int
1956 lnet_get_net_config(int idx, __u32 *cpt_count, __u64 *nid, int *peer_timeout,
1957                     int *peer_tx_credits, int *peer_rtr_credits,
1958                     int *max_tx_credits,
1959                     struct lnet_ioctl_net_config *net_config)
1960 {
1961         struct lnet_ni          *ni;
1962         struct list_head        *tmp;
1963         int                     cpt;
1964         int                     rc = -ENOENT;
1965
1966         cpt = lnet_net_lock_current();
1967
1968         list_for_each(tmp, &the_lnet.ln_nis) {
1969                 ni = list_entry(tmp, lnet_ni_t, ni_list);
1970                 if (idx-- == 0) {
1971                         rc = 0;
1972                         lnet_ni_lock(ni);
1973                         lnet_fill_ni_info(ni, cpt_count, nid, peer_timeout,
1974                                           peer_tx_credits, peer_rtr_credits,
1975                                           max_tx_credits, net_config);
1976                         lnet_ni_unlock(ni);
1977                         break;
1978                 }
1979         }
1980
1981         lnet_net_unlock(cpt);
1982         return rc;
1983 }
1984
1985 int
1986 lnet_dyn_add_ni(lnet_pid_t requested_pid, char *nets,
1987                 __s32 peer_timeout, __s32 peer_cr, __s32 peer_buf_cr,
1988                 __s32 credits)
1989 {
1990         lnet_ping_info_t        *pinfo;
1991         lnet_handle_md_t        md_handle;
1992         struct lnet_ni          *ni;
1993         struct list_head        net_head;
1994         int                     rc;
1995         lnet_remotenet_t        *rnet;
1996
1997         INIT_LIST_HEAD(&net_head);
1998
1999         /* Create a ni structure for the network string */
2000         rc = lnet_parse_networks(&net_head, nets);
2001         if (rc <= 0)
2002                 return rc == 0 ? -EINVAL : rc;
2003
2004         LNET_MUTEX_LOCK(&the_lnet.ln_api_mutex);
2005
2006         if (rc > 1) {
2007                 rc = -EINVAL; /* only add one interface per call */
2008                 goto failed0;
2009         }
2010
2011         ni = list_entry(net_head.next, struct lnet_ni, ni_list);
2012
2013         lnet_net_lock(LNET_LOCK_EX);
2014         rnet = lnet_find_net_locked(LNET_NIDNET(ni->ni_nid));
2015         lnet_net_unlock(LNET_LOCK_EX);
2016         /* make sure that the net added doesn't invalidate the current
2017          * configuration LNet is keeping */
2018         if (rnet != NULL) {
2019                 CERROR("Adding net %s will invalidate routing configuration\n",
2020                        nets);
2021                 rc = -EUSERS;
2022                 goto failed0;
2023         }
2024
2025         rc = lnet_ping_info_setup(&pinfo, &md_handle, 1 + lnet_get_ni_count(),
2026                                   false);
2027         if (rc != 0)
2028                 goto failed0;
2029
2030         list_del_init(&ni->ni_list);
2031
2032         rc = lnet_startup_lndni(ni, peer_timeout, peer_cr,
2033                                 peer_buf_cr, credits);
2034         if (rc != 0)
2035                 goto failed1;
2036
2037         if (ni->ni_lnd->lnd_accept != NULL) {
2038                 rc = lnet_acceptor_start();
2039                 if (rc < 0) {
2040                         /* shutdown the ni that we just started */
2041                         CERROR("Failed to start up acceptor thread\n");
2042                         lnet_shutdown_lndni(ni);
2043                         goto failed1;
2044                 }
2045         }
2046
2047         lnet_ping_target_update(pinfo, md_handle);
2048         LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex);
2049
2050         return 0;
2051
2052 failed1:
2053         lnet_ping_md_unlink(pinfo, &md_handle);
2054         lnet_ping_info_free(pinfo);
2055 failed0:
2056         LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex);
2057         while (!list_empty(&net_head)) {
2058                 ni = list_entry(net_head.next, struct lnet_ni, ni_list);
2059                 list_del_init(&ni->ni_list);
2060                 lnet_ni_free(ni);
2061         }
2062         return rc;
2063 }
2064
2065 int
2066 lnet_dyn_del_ni(__u32 net)
2067 {
2068         lnet_ni_t        *ni;
2069         lnet_ping_info_t *pinfo;
2070         lnet_handle_md_t  md_handle;
2071         int               rc;
2072
2073         /* don't allow userspace to shutdown the LOLND */
2074         if (LNET_NETTYP(net) == LOLND)
2075                 return -EINVAL;
2076
2077         LNET_MUTEX_LOCK(&the_lnet.ln_api_mutex);
2078         /* create and link a new ping info, before removing the old one */
2079         rc = lnet_ping_info_setup(&pinfo, &md_handle,
2080                                   lnet_get_ni_count() - 1, false);
2081         if (rc != 0)
2082                 goto out;
2083
2084         ni = lnet_net2ni(net);
2085         if (ni == NULL) {
2086                 rc = -EINVAL;
2087                 goto failed;
2088         }
2089
2090         /* decrement the reference counter taken by lnet_net2ni() */
2091         lnet_ni_decref_locked(ni, 0);
2092
2093         lnet_shutdown_lndni(ni);
2094
2095         if (lnet_count_acceptor_nis() == 0)
2096                 lnet_acceptor_stop();
2097
2098         lnet_ping_target_update(pinfo, md_handle);
2099         goto out;
2100 failed:
2101         lnet_ping_md_unlink(pinfo, &md_handle);
2102         lnet_ping_info_free(pinfo);
2103 out:
2104         LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex);
2105
2106         return rc;
2107 }
2108
2109 /**
2110  * This is an ugly hack to export IOC_LIBCFS_DEBUG_PEER and
2111  * IOC_LIBCFS_PORTALS_COMPATIBILITY commands to users, by tweaking the LNet
2112  * internal ioctl handler.
2113  *
2114  * IOC_LIBCFS_PORTALS_COMPATIBILITY is now deprecated, don't use it.
2115  *
2116  * \param cmd IOC_LIBCFS_DEBUG_PEER to print debugging data about a peer.
2117  * The data will be printed to system console. Don't use it excessively.
2118  * \param arg A pointer to lnet_process_id_t, process ID of the peer.
2119  *
2120  * \return Always return 0 when called by users directly (i.e., not via ioctl).
2121  */
2122 int
2123 LNetCtl(unsigned int cmd, void *arg)
2124 {
2125         struct libcfs_ioctl_data *data = arg;
2126         struct lnet_ioctl_config_data *config;
2127         lnet_process_id_t         id = {0};
2128         lnet_ni_t                *ni;
2129         int                       rc;
2130
2131         CLASSERT(LIBCFS_IOC_DATA_MAX >= sizeof(struct lnet_ioctl_net_config) +
2132                                         sizeof(struct lnet_ioctl_config_data));
2133         LASSERT(the_lnet.ln_init);
2134
2135         switch (cmd) {
2136         case IOC_LIBCFS_GET_NI:
2137                 rc = LNetGetId(data->ioc_count, &id);
2138                 data->ioc_nid = id.nid;
2139                 return rc;
2140
2141         case IOC_LIBCFS_FAIL_NID:
2142                 return lnet_fail_nid(data->ioc_nid, data->ioc_count);
2143
2144         case IOC_LIBCFS_ADD_ROUTE:
2145                 config = arg;
2146
2147                 if (config->cfg_hdr.ioc_len < sizeof(*config))
2148                         return -EINVAL;
2149
2150                 LNET_MUTEX_LOCK(&the_lnet.ln_api_mutex);
2151                 rc = lnet_add_route(config->cfg_net,
2152                                     config->cfg_config_u.cfg_route.rtr_hop,
2153                                     config->cfg_nid,
2154                                     config->cfg_config_u.cfg_route.
2155                                         rtr_priority);
2156                 LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex);
2157                 return (rc != 0) ? rc : lnet_check_routes();
2158
2159         case IOC_LIBCFS_DEL_ROUTE:
2160                 config = arg;
2161
2162                 if (config->cfg_hdr.ioc_len < sizeof(*config))
2163                         return -EINVAL;
2164
2165                 LNET_MUTEX_LOCK(&the_lnet.ln_api_mutex);
2166                 rc = lnet_del_route(config->cfg_net, config->cfg_nid);
2167                 LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex);
2168                 return rc;
2169
2170         case IOC_LIBCFS_GET_ROUTE:
2171                 config = arg;
2172
2173                 if (config->cfg_hdr.ioc_len < sizeof(*config))
2174                         return -EINVAL;
2175
2176                 return lnet_get_route(config->cfg_count,
2177                                       &config->cfg_net,
2178                                       &config->cfg_config_u.cfg_route.rtr_hop,
2179                                       &config->cfg_nid,
2180                                       &config->cfg_config_u.cfg_route.rtr_flags,
2181                                       &config->cfg_config_u.cfg_route.
2182                                         rtr_priority);
2183
2184         case IOC_LIBCFS_GET_NET: {
2185                 struct lnet_ioctl_net_config *net_config;
2186                 size_t total = sizeof(*config) + sizeof(*net_config);
2187
2188                 config = arg;
2189
2190                 if (config->cfg_hdr.ioc_len < total)
2191                         return -EINVAL;
2192
2193                 net_config = (struct lnet_ioctl_net_config *)
2194                         config->cfg_bulk;
2195                 if (config == NULL || net_config == NULL)
2196                         return -1;
2197
2198                 return lnet_get_net_config(config->cfg_count,
2199                                            &config->cfg_ncpts,
2200                                            &config->cfg_nid,
2201                                            &config->cfg_config_u.
2202                                                 cfg_net.net_peer_timeout,
2203                                            &config->cfg_config_u.cfg_net.
2204                                                 net_peer_tx_credits,
2205                                            &config->cfg_config_u.cfg_net.
2206                                                 net_peer_rtr_credits,
2207                                            &config->cfg_config_u.cfg_net.
2208                                                 net_max_tx_credits,
2209                                            net_config);
2210         }
2211
2212         case IOC_LIBCFS_GET_LNET_STATS:
2213         {
2214                 struct lnet_ioctl_lnet_stats *lnet_stats = arg;
2215
2216                 if (lnet_stats->st_hdr.ioc_len < sizeof(*lnet_stats))
2217                         return -EINVAL;
2218
2219                 lnet_counters_get(&lnet_stats->st_cntrs);
2220                 return 0;
2221         }
2222
2223 #if defined(__KERNEL__) && defined(LNET_ROUTER)
2224         case IOC_LIBCFS_CONFIG_RTR:
2225                 config = arg;
2226
2227                 if (config->cfg_hdr.ioc_len < sizeof(*config))
2228                         return -EINVAL;
2229
2230                 LNET_MUTEX_LOCK(&the_lnet.ln_api_mutex);
2231                 if (config->cfg_config_u.cfg_buffers.buf_enable) {
2232                         rc = lnet_rtrpools_enable();
2233                         LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex);
2234                         return rc;
2235                 }
2236                 lnet_rtrpools_disable();
2237                 LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex);
2238                 return 0;
2239
2240         case IOC_LIBCFS_ADD_BUF:
2241                 config = arg;
2242
2243                 if (config->cfg_hdr.ioc_len < sizeof(*config))
2244                         return -EINVAL;
2245
2246                 LNET_MUTEX_LOCK(&the_lnet.ln_api_mutex);
2247                 rc = lnet_rtrpools_adjust(config->cfg_config_u.cfg_buffers.
2248                                                 buf_tiny,
2249                                           config->cfg_config_u.cfg_buffers.
2250                                                 buf_small,
2251                                           config->cfg_config_u.cfg_buffers.
2252                                                 buf_large);
2253                 LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex);
2254                 return rc;
2255 #endif
2256
2257         case IOC_LIBCFS_GET_BUF: {
2258                 struct lnet_ioctl_pool_cfg *pool_cfg;
2259                 size_t total = sizeof(*config) + sizeof(*pool_cfg);
2260
2261                 config = arg;
2262
2263                 if (config->cfg_hdr.ioc_len < total)
2264                         return -EINVAL;
2265
2266                 pool_cfg = (struct lnet_ioctl_pool_cfg *)config->cfg_bulk;
2267                 return lnet_get_rtr_pool_cfg(config->cfg_count, pool_cfg);
2268         }
2269
2270         case IOC_LIBCFS_GET_PEER_INFO: {
2271                 struct lnet_ioctl_peer *peer_info = arg;
2272
2273                 if (peer_info->pr_hdr.ioc_len < sizeof(*peer_info))
2274                         return -EINVAL;
2275
2276                 return lnet_get_peer_info(
2277                    peer_info->pr_count,
2278                    &peer_info->pr_nid,
2279                    peer_info->pr_lnd_u.pr_peer_credits.cr_aliveness,
2280                    &peer_info->pr_lnd_u.pr_peer_credits.cr_ncpt,
2281                    &peer_info->pr_lnd_u.pr_peer_credits.cr_refcount,
2282                    &peer_info->pr_lnd_u.pr_peer_credits.cr_ni_peer_tx_credits,
2283                    &peer_info->pr_lnd_u.pr_peer_credits.cr_peer_tx_credits,
2284                    &peer_info->pr_lnd_u.pr_peer_credits.cr_peer_rtr_credits,
2285                    &peer_info->pr_lnd_u.pr_peer_credits.cr_peer_min_rtr_credits,
2286                    &peer_info->pr_lnd_u.pr_peer_credits.cr_peer_tx_qnob);
2287         }
2288
2289         case IOC_LIBCFS_NOTIFY_ROUTER:
2290                 return lnet_notify(NULL, data->ioc_nid, data->ioc_flags,
2291                                    cfs_time_current() -
2292                                    cfs_time_seconds(cfs_time_current_sec() -
2293                                                     (time_t)data->ioc_u64[0]));
2294
2295         case IOC_LIBCFS_PORTALS_COMPATIBILITY:
2296                 /* This can be removed once lustre stops calling it */
2297                 return 0;
2298
2299         case IOC_LIBCFS_LNET_DIST:
2300                 rc = LNetDist(data->ioc_nid, &data->ioc_nid, &data->ioc_u32[1]);
2301                 if (rc < 0 && rc != -EHOSTUNREACH)
2302                         return rc;
2303
2304                 data->ioc_u32[0] = rc;
2305                 return 0;
2306
2307         case IOC_LIBCFS_TESTPROTOCOMPAT:
2308                 lnet_net_lock(LNET_LOCK_EX);
2309                 the_lnet.ln_testprotocompat = data->ioc_flags;
2310                 lnet_net_unlock(LNET_LOCK_EX);
2311                 return 0;
2312
2313         case IOC_LIBCFS_LNET_FAULT:
2314                 return lnet_fault_ctl(data->ioc_flags, data);
2315
2316         case IOC_LIBCFS_PING:
2317                 id.nid = data->ioc_nid;
2318                 id.pid = data->ioc_u32[0];
2319                 rc = lnet_ping(id, data->ioc_u32[1], /* timeout */
2320                                (lnet_process_id_t __user *)data->ioc_pbuf1,
2321                                data->ioc_plen1/sizeof(lnet_process_id_t));
2322                 if (rc < 0)
2323                         return rc;
2324                 data->ioc_count = rc;
2325                 return 0;
2326
2327         case IOC_LIBCFS_DEBUG_PEER: {
2328                 /* CAVEAT EMPTOR: this one designed for calling directly; not
2329                  * via an ioctl */
2330                 id = *((lnet_process_id_t *) arg);
2331
2332                 lnet_debug_peer(id.nid);
2333
2334                 ni = lnet_net2ni(LNET_NIDNET(id.nid));
2335                 if (ni == NULL) {
2336                         CDEBUG(D_WARNING, "No NI for %s\n", libcfs_id2str(id));
2337                 } else {
2338                         if (ni->ni_lnd->lnd_ctl == NULL) {
2339                                 CDEBUG(D_WARNING, "No ctl for %s\n",
2340                                        libcfs_id2str(id));
2341                         } else {
2342                                 (void)ni->ni_lnd->lnd_ctl(ni, cmd, arg);
2343                         }
2344
2345                         lnet_ni_decref(ni);
2346                 }
2347                 return 0;
2348         }
2349
2350         default:
2351                 ni = lnet_net2ni(data->ioc_net);
2352                 if (ni == NULL)
2353                         return -EINVAL;
2354
2355                 if (ni->ni_lnd->lnd_ctl == NULL)
2356                         rc = -EINVAL;
2357                 else
2358                         rc = ni->ni_lnd->lnd_ctl(ni, cmd, arg);
2359
2360                 lnet_ni_decref(ni);
2361                 return rc;
2362         }
2363         /* not reached */
2364 }
2365 EXPORT_SYMBOL(LNetCtl);
2366
2367 /**
2368  * Retrieve the lnet_process_id_t ID of LNet interface at \a index. Note that
2369  * all interfaces share a same PID, as requested by LNetNIInit().
2370  *
2371  * \param index Index of the interface to look up.
2372  * \param id On successful return, this location will hold the
2373  * lnet_process_id_t ID of the interface.
2374  *
2375  * \retval 0 If an interface exists at \a index.
2376  * \retval -ENOENT If no interface has been found.
2377  */
2378 int
2379 LNetGetId(unsigned int index, lnet_process_id_t *id)
2380 {
2381         struct lnet_ni   *ni;
2382         struct list_head *tmp;
2383         int               cpt;
2384         int               rc = -ENOENT;
2385
2386         LASSERT(the_lnet.ln_init);
2387         LASSERT(the_lnet.ln_refcount > 0);
2388
2389         cpt = lnet_net_lock_current();
2390
2391         list_for_each(tmp, &the_lnet.ln_nis) {
2392                 if (index-- != 0)
2393                         continue;
2394
2395                 ni = list_entry(tmp, lnet_ni_t, ni_list);
2396
2397                 id->nid = ni->ni_nid;
2398                 id->pid = the_lnet.ln_pid;
2399                 rc = 0;
2400                 break;
2401         }
2402
2403         lnet_net_unlock(cpt);
2404         return rc;
2405 }
2406 EXPORT_SYMBOL(LNetGetId);
2407
2408 /**
2409  * Print a string representation of handle \a h into buffer \a str of
2410  * \a len bytes.
2411  */
2412 void
2413 LNetSnprintHandle(char *str, int len, lnet_handle_any_t h)
2414 {
2415         snprintf(str, len, LPX64, h.cookie);
2416 }
2417 EXPORT_SYMBOL(LNetSnprintHandle);
2418
2419 static int
2420 lnet_ping(lnet_process_id_t id, int timeout_ms, lnet_process_id_t __user *ids,
2421           int n_ids)
2422 {
2423         lnet_handle_eq_t     eqh;
2424         lnet_handle_md_t     mdh;
2425         lnet_event_t         event;
2426         lnet_md_t            md = { NULL };
2427         int                  which;
2428         int                  unlinked = 0;
2429         int                  replied = 0;
2430         const int            a_long_time = 60000; /* mS */
2431         int                  infosz;
2432         lnet_ping_info_t    *info;
2433         lnet_process_id_t    tmpid;
2434         int                  i;
2435         int                  nob;
2436         int                  rc;
2437         int                  rc2;
2438         sigset_t         blocked;
2439
2440         infosz = offsetof(lnet_ping_info_t, pi_ni[n_ids]);
2441
2442         if (n_ids <= 0 ||
2443             id.nid == LNET_NID_ANY ||
2444             timeout_ms > 500000 ||              /* arbitrary limit! */
2445             n_ids > 20)                         /* arbitrary limit! */
2446                 return -EINVAL;
2447
2448         if (id.pid == LNET_PID_ANY)
2449                 id.pid = LNET_PID_LUSTRE;
2450
2451         LIBCFS_ALLOC(info, infosz);
2452         if (info == NULL)
2453                 return -ENOMEM;
2454
2455         /* NB 2 events max (including any unlink event) */
2456         rc = LNetEQAlloc(2, LNET_EQ_HANDLER_NONE, &eqh);
2457         if (rc != 0) {
2458                 CERROR("Can't allocate EQ: %d\n", rc);
2459                 goto out_0;
2460         }
2461
2462         /* initialize md content */
2463         md.start     = info;
2464         md.length    = infosz;
2465         md.threshold = 2; /*GET/REPLY*/
2466         md.max_size  = 0;
2467         md.options   = LNET_MD_TRUNCATE;
2468         md.user_ptr  = NULL;
2469         md.eq_handle = eqh;
2470
2471         rc = LNetMDBind(md, LNET_UNLINK, &mdh);
2472         if (rc != 0) {
2473                 CERROR("Can't bind MD: %d\n", rc);
2474                 goto out_1;
2475         }
2476
2477         rc = LNetGet(LNET_NID_ANY, mdh, id,
2478                      LNET_RESERVED_PORTAL,
2479                      LNET_PROTO_PING_MATCHBITS, 0);
2480
2481         if (rc != 0) {
2482                 /* Don't CERROR; this could be deliberate! */
2483
2484                 rc2 = LNetMDUnlink(mdh);
2485                 LASSERT(rc2 == 0);
2486
2487                 /* NB must wait for the UNLINK event below... */
2488                 unlinked = 1;
2489                 timeout_ms = a_long_time;
2490         }
2491
2492         do {
2493                 /* MUST block for unlink to complete */
2494                 if (unlinked)
2495                         blocked = cfs_block_allsigs();
2496
2497                 rc2 = LNetEQPoll(&eqh, 1, timeout_ms, &event, &which);
2498
2499                 if (unlinked)
2500                         cfs_restore_sigs(blocked);
2501
2502                 CDEBUG(D_NET, "poll %d(%d %d)%s\n", rc2,
2503                        (rc2 <= 0) ? -1 : event.type,
2504                        (rc2 <= 0) ? -1 : event.status,
2505                        (rc2 > 0 && event.unlinked) ? " unlinked" : "");
2506
2507                 LASSERT(rc2 != -EOVERFLOW);     /* can't miss anything */
2508
2509                 if (rc2 <= 0 || event.status != 0) {
2510                         /* timeout or error */
2511                         if (!replied && rc == 0)
2512                                 rc = (rc2 < 0) ? rc2 :
2513                                      (rc2 == 0) ? -ETIMEDOUT :
2514                                      event.status;
2515
2516                         if (!unlinked) {
2517                                 /* Ensure completion in finite time... */
2518                                 LNetMDUnlink(mdh);
2519                                 /* No assertion (racing with network) */
2520                                 unlinked = 1;
2521                                 timeout_ms = a_long_time;
2522                         } else if (rc2 == 0) {
2523                                 /* timed out waiting for unlink */
2524                                 CWARN("ping %s: late network completion\n",
2525                                       libcfs_id2str(id));
2526                         }
2527                 } else if (event.type == LNET_EVENT_REPLY) {
2528                         replied = 1;
2529                         rc = event.mlength;
2530                 }
2531
2532         } while (rc2 <= 0 || !event.unlinked);
2533
2534         if (!replied) {
2535                 if (rc >= 0)
2536                         CWARN("%s: Unexpected rc >= 0 but no reply!\n",
2537                               libcfs_id2str(id));
2538                 rc = -EIO;
2539                 goto out_1;
2540         }
2541
2542         nob = rc;
2543         LASSERT(nob >= 0 && nob <= infosz);
2544
2545         rc = -EPROTO;                           /* if I can't parse... */
2546
2547         if (nob < 8) {
2548                 /* can't check magic/version */
2549                 CERROR("%s: ping info too short %d\n",
2550                        libcfs_id2str(id), nob);
2551                 goto out_1;
2552         }
2553
2554         if (info->pi_magic == __swab32(LNET_PROTO_PING_MAGIC)) {
2555                 lnet_swap_pinginfo(info);
2556         } else if (info->pi_magic != LNET_PROTO_PING_MAGIC) {
2557                 CERROR("%s: Unexpected magic %08x\n",
2558                        libcfs_id2str(id), info->pi_magic);
2559                 goto out_1;
2560         }
2561
2562         if ((info->pi_features & LNET_PING_FEAT_NI_STATUS) == 0) {
2563                 CERROR("%s: ping w/o NI status: 0x%x\n",
2564                        libcfs_id2str(id), info->pi_features);
2565                 goto out_1;
2566         }
2567
2568         if (nob < offsetof(lnet_ping_info_t, pi_ni[0])) {
2569                 CERROR("%s: Short reply %d(%d min)\n", libcfs_id2str(id),
2570                        nob, (int)offsetof(lnet_ping_info_t, pi_ni[0]));
2571                 goto out_1;
2572         }
2573
2574         if (info->pi_nnis < n_ids)
2575                 n_ids = info->pi_nnis;
2576
2577         if (nob < offsetof(lnet_ping_info_t, pi_ni[n_ids])) {
2578                 CERROR("%s: Short reply %d(%d expected)\n", libcfs_id2str(id),
2579                        nob, (int)offsetof(lnet_ping_info_t, pi_ni[n_ids]));
2580                 goto out_1;
2581         }
2582
2583         rc = -EFAULT;                           /* If I SEGV... */
2584
2585         for (i = 0; i < n_ids; i++) {
2586                 tmpid.pid = info->pi_pid;
2587                 tmpid.nid = info->pi_ni[i].ns_nid;
2588                 if (copy_to_user(&ids[i], &tmpid, sizeof(tmpid)))
2589                         goto out_1;
2590         }
2591         rc = info->pi_nnis;
2592
2593  out_1:
2594         rc2 = LNetEQFree(eqh);
2595         if (rc2 != 0)
2596                 CERROR("rc2 %d\n", rc2);
2597         LASSERT(rc2 == 0);
2598
2599  out_0:
2600         LIBCFS_FREE(info, infosz);
2601         return rc;
2602 }