Whamcloud - gitweb
LU-5875 lnet: return -EEXIST if NI is not unique
[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 = -EINVAL;
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         rc = lnet_net_unique(LNET_NIDNET(ni->ni_nid), &the_lnet.ln_nis);
1436         lnet_net_unlock(LNET_LOCK_EX);
1437
1438         if (!rc) {
1439                 if (lnd_type == LOLND) {
1440                         lnet_ni_free(ni);
1441                         return 0;
1442                 }
1443
1444                 CERROR("Net %s is not unique\n",
1445                        libcfs_net2str(LNET_NIDNET(ni->ni_nid)));
1446
1447                 rc = -EEXIST;
1448                 goto failed0;
1449         }
1450
1451         LNET_MUTEX_LOCK(&the_lnet.ln_lnd_mutex);
1452         lnd = lnet_find_lnd_by_type(lnd_type);
1453
1454 #ifdef __KERNEL__
1455         if (lnd == NULL) {
1456                 LNET_MUTEX_UNLOCK(&the_lnet.ln_lnd_mutex);
1457                 rc = request_module("%s", libcfs_lnd2modname(lnd_type));
1458                 LNET_MUTEX_LOCK(&the_lnet.ln_lnd_mutex);
1459
1460                 lnd = lnet_find_lnd_by_type(lnd_type);
1461                 if (lnd == NULL) {
1462                         LNET_MUTEX_UNLOCK(&the_lnet.ln_lnd_mutex);
1463                         CERROR("Can't load LND %s, module %s, rc=%d\n",
1464                                libcfs_lnd2str(lnd_type),
1465                                libcfs_lnd2modname(lnd_type), rc);
1466 #ifndef HAVE_MODULE_LOADING_SUPPORT
1467                         LCONSOLE_ERROR_MSG(0x104, "Your kernel must be "
1468                                            "compiled with kernel module "
1469                                            "loading support.");
1470 #endif
1471                         rc = -EINVAL;
1472                         goto failed0;
1473                 }
1474         }
1475 #else
1476         if (lnd == NULL) {
1477                 LNET_MUTEX_UNLOCK(&the_lnet.ln_lnd_mutex);
1478                 CERROR("LND %s not supported\n",
1479                         libcfs_lnd2str(lnd_type));
1480                 goto failed0;
1481         }
1482 #endif
1483
1484         lnet_net_lock(LNET_LOCK_EX);
1485         lnd->lnd_refcount++;
1486         lnet_net_unlock(LNET_LOCK_EX);
1487
1488         ni->ni_lnd = lnd;
1489
1490         rc = (lnd->lnd_startup)(ni);
1491
1492         LNET_MUTEX_UNLOCK(&the_lnet.ln_lnd_mutex);
1493
1494         if (rc != 0) {
1495                 LCONSOLE_ERROR_MSG(0x105, "Error %d starting up LNI %s\n",
1496                                    rc, libcfs_lnd2str(lnd->lnd_type));
1497                 lnet_net_lock(LNET_LOCK_EX);
1498                 lnd->lnd_refcount--;
1499                 lnet_net_unlock(LNET_LOCK_EX);
1500                 goto failed0;
1501         }
1502
1503         /* If given some LND tunable parameters, parse those now to
1504          * override the values in the NI structure. */
1505         if (peer_buf_cr >= 0)
1506                 ni->ni_peerrtrcredits = peer_buf_cr;
1507         if (peer_timeout >= 0)
1508                 ni->ni_peertimeout = peer_timeout;
1509         /*
1510          * TODO
1511          * Note: For now, don't allow the user to change
1512          * peertxcredits as this number is used in the
1513          * IB LND to control queue depth.
1514          * if (peer_cr != -1)
1515          *      ni->ni_peertxcredits = peer_cr;
1516          */
1517         if (credits >= 0)
1518                 ni->ni_maxtxcredits = credits;
1519
1520         LASSERT(ni->ni_peertimeout <= 0 || lnd->lnd_query != NULL);
1521
1522         lnet_net_lock(LNET_LOCK_EX);
1523         /* refcount for ln_nis */
1524         lnet_ni_addref_locked(ni, 0);
1525         list_add_tail(&ni->ni_list, &the_lnet.ln_nis);
1526         if (ni->ni_cpts != NULL) {
1527                 lnet_ni_addref_locked(ni, 0);
1528                 list_add_tail(&ni->ni_cptlist, &the_lnet.ln_nis_cpt);
1529         }
1530
1531         lnet_net_unlock(LNET_LOCK_EX);
1532
1533         if (lnd->lnd_type == LOLND) {
1534                 lnet_ni_addref(ni);
1535                 LASSERT(the_lnet.ln_loni == NULL);
1536                 the_lnet.ln_loni = ni;
1537                 return 0;
1538         }
1539
1540 #ifndef __KERNEL__
1541         if (lnd->lnd_wait != NULL) {
1542                 if (the_lnet.ln_eq_waitni == NULL) {
1543                         lnet_ni_addref(ni);
1544                         the_lnet.ln_eq_waitni = ni;
1545                 }
1546         } else {
1547 # ifndef HAVE_LIBPTHREAD
1548                 LCONSOLE_ERROR_MSG(0x106, "LND %s not supported in a "
1549                                         "single-threaded runtime\n",
1550                                         libcfs_lnd2str(lnd_type));
1551                 /* shutdown the NI since if we get here then it must've already
1552                  * been started
1553                  */
1554                 lnet_shutdown_lndni(ni);
1555                 return -EINVAL;
1556 # endif
1557         }
1558 #endif
1559         if (ni->ni_peertxcredits == 0 || ni->ni_maxtxcredits == 0) {
1560                 LCONSOLE_ERROR_MSG(0x107, "LNI %s has no %scredits\n",
1561                                    libcfs_lnd2str(lnd->lnd_type),
1562                                    ni->ni_peertxcredits == 0 ?
1563                                         "" : "per-peer ");
1564                 /* shutdown the NI since if we get here then it must've already
1565                  * been started
1566                  */
1567                 lnet_shutdown_lndni(ni);
1568                 return -EINVAL;
1569         }
1570
1571         cfs_percpt_for_each(tq, i, ni->ni_tx_queues) {
1572                 tq->tq_credits_min =
1573                 tq->tq_credits_max =
1574                 tq->tq_credits = lnet_ni_tq_credits(ni);
1575         }
1576
1577         CDEBUG(D_LNI, "Added LNI %s [%d/%d/%d/%d]\n",
1578                 libcfs_nid2str(ni->ni_nid), ni->ni_peertxcredits,
1579                 lnet_ni_tq_credits(ni) * LNET_CPT_NUMBER,
1580                 ni->ni_peerrtrcredits, ni->ni_peertimeout);
1581
1582         return 0;
1583 failed0:
1584         lnet_ni_free(ni);
1585         return rc;
1586 }
1587
1588 static int
1589 lnet_startup_lndnis(struct list_head *nilist)
1590 {
1591         struct lnet_ni          *ni;
1592         int                     rc;
1593         int                     lnd_type;
1594         int                     ni_count = 0;
1595
1596         while (!list_empty(nilist)) {
1597                 ni = list_entry(nilist->next, lnet_ni_t, ni_list);
1598                 list_del(&ni->ni_list);
1599                 rc = lnet_startup_lndni(ni, -1, -1, -1, -1);
1600
1601                 if (rc < 0)
1602                         goto failed;
1603
1604                 ni_count++;
1605         }
1606
1607         if (the_lnet.ln_eq_waitni != NULL && ni_count > 1) {
1608                 lnd_type = the_lnet.ln_eq_waitni->ni_lnd->lnd_type;
1609                 LCONSOLE_ERROR_MSG(0x109, "LND %s can only run single-network"
1610                                    "\n",
1611                                    libcfs_lnd2str(lnd_type));
1612                 rc = -EINVAL;
1613                 goto failed;
1614         }
1615
1616         return ni_count;
1617 failed:
1618         lnet_shutdown_lndnis();
1619
1620         return rc;
1621 }
1622
1623 /**
1624  * Initialize LNet library.
1625  *
1626  * Only userspace program needs to call this function - it's automatically
1627  * called in the kernel at module loading time. Caller has to call LNetFini()
1628  * after a call to LNetInit(), if and only if the latter returned 0. It must
1629  * be called exactly once.
1630  *
1631  * \return 0 on success, and -ve on failures.
1632  */
1633 int
1634 LNetInit(void)
1635 {
1636         int     rc;
1637
1638         lnet_assert_wire_constants();
1639         LASSERT(!the_lnet.ln_init);
1640
1641         memset(&the_lnet, 0, sizeof(the_lnet));
1642
1643         /* refer to global cfs_cpt_table for now */
1644         the_lnet.ln_cpt_table   = cfs_cpt_table;
1645         the_lnet.ln_cpt_number  = cfs_cpt_number(cfs_cpt_table);
1646
1647         LASSERT(the_lnet.ln_cpt_number > 0);
1648         if (the_lnet.ln_cpt_number > LNET_CPT_MAX) {
1649                 /* we are under risk of consuming all lh_cookie */
1650                 CERROR("Can't have %d CPTs for LNet (max allowed is %d), "
1651                        "please change setting of CPT-table and retry\n",
1652                        the_lnet.ln_cpt_number, LNET_CPT_MAX);
1653                 return -1;
1654         }
1655
1656         while ((1 << the_lnet.ln_cpt_bits) < the_lnet.ln_cpt_number)
1657                 the_lnet.ln_cpt_bits++;
1658
1659         rc = lnet_create_locks();
1660         if (rc != 0) {
1661                 CERROR("Can't create LNet global locks: %d\n", rc);
1662                 return -1;
1663         }
1664
1665         the_lnet.ln_refcount = 0;
1666         the_lnet.ln_init = 1;
1667         LNetInvalidateHandle(&the_lnet.ln_rc_eqh);
1668         INIT_LIST_HEAD(&the_lnet.ln_lnds);
1669         INIT_LIST_HEAD(&the_lnet.ln_rcd_zombie);
1670         INIT_LIST_HEAD(&the_lnet.ln_rcd_deathrow);
1671
1672 #ifdef __KERNEL__
1673         /* The hash table size is the number of bits it takes to express the set
1674          * ln_num_routes, minus 1 (better to under estimate than over so we
1675          * don't waste memory). */
1676         if (rnet_htable_size <= 0)
1677                 rnet_htable_size = LNET_REMOTE_NETS_HASH_DEFAULT;
1678         else if (rnet_htable_size > LNET_REMOTE_NETS_HASH_MAX)
1679                 rnet_htable_size = LNET_REMOTE_NETS_HASH_MAX;
1680         the_lnet.ln_remote_nets_hbits = max_t(int, 1,
1681                                            order_base_2(rnet_htable_size) - 1);
1682
1683         /* All LNDs apart from the LOLND are in separate modules.  They
1684          * register themselves when their module loads, and unregister
1685          * themselves when their module is unloaded. */
1686 #else
1687         the_lnet.ln_remote_nets_hbits = 8;
1688
1689         /* Register LNDs
1690          * NB the order here determines default 'networks=' order */
1691 # ifdef HAVE_LIBPTHREAD
1692         LNET_REGISTER_ULND(the_tcplnd);
1693 # endif
1694 #endif
1695         lnet_register_lnd(&the_lolnd);
1696         return 0;
1697 }
1698 EXPORT_SYMBOL(LNetInit);
1699
1700 /**
1701  * Finalize LNet library.
1702  *
1703  * Only userspace program needs to call this function. It can be called
1704  * at most once.
1705  *
1706  * \pre LNetInit() called with success.
1707  * \pre All LNet users called LNetNIFini() for matching LNetNIInit() calls.
1708  */
1709 void
1710 LNetFini(void)
1711 {
1712         LASSERT(the_lnet.ln_init);
1713         LASSERT(the_lnet.ln_refcount == 0);
1714
1715         while (!list_empty(&the_lnet.ln_lnds))
1716                 lnet_unregister_lnd(list_entry(the_lnet.ln_lnds.next,
1717                                                lnd_t, lnd_list));
1718         lnet_destroy_locks();
1719
1720         the_lnet.ln_init = 0;
1721 }
1722 EXPORT_SYMBOL(LNetFini);
1723
1724 /**
1725  * Set LNet PID and start LNet interfaces, routing, and forwarding.
1726  *
1727  * Userspace program should call this after a successful call to LNetInit().
1728  * Users must call this function at least once before any other functions.
1729  * For each successful call there must be a corresponding call to
1730  * LNetNIFini(). For subsequent calls to LNetNIInit(), \a requested_pid is
1731  * ignored.
1732  *
1733  * The PID used by LNet may be different from the one requested.
1734  * See LNetGetId().
1735  *
1736  * \param requested_pid PID requested by the caller.
1737  *
1738  * \return >= 0 on success, and < 0 error code on failures.
1739  */
1740 int
1741 LNetNIInit(lnet_pid_t requested_pid)
1742 {
1743         int                     im_a_router = 0;
1744         int                     rc;
1745         int                     ni_count;
1746         lnet_ping_info_t        *pinfo;
1747         lnet_handle_md_t        md_handle;
1748         struct list_head        net_head;
1749
1750         INIT_LIST_HEAD(&net_head);
1751
1752         LNET_MUTEX_LOCK(&the_lnet.ln_api_mutex);
1753
1754         LASSERT(the_lnet.ln_init);
1755         CDEBUG(D_OTHER, "refs %d\n", the_lnet.ln_refcount);
1756
1757         if (the_lnet.ln_refcount > 0) {
1758                 rc = the_lnet.ln_refcount++;
1759                 LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex);
1760                 return rc;
1761         }
1762
1763         rc = lnet_prepare(requested_pid);
1764         if (rc != 0) {
1765                 LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex);
1766                 return rc;
1767         }
1768
1769         /* Add in the loopback network */
1770         if (lnet_ni_alloc(LNET_MKNET(LOLND, 0), NULL, &net_head) == NULL) {
1771                 rc = -ENOMEM;
1772                 goto failed0;
1773         }
1774
1775         /* If LNet is being initialized via DLC it is possible
1776          * that the user requests not to load module parameters (ones which
1777          * are supported by DLC) on initialization.  Therefore, make sure not
1778          * to load networks, routes and forwarding from module parameters
1779          * in this case.  On cleanup in case of failure only clean up
1780          * routes if it has been loaded */
1781         if (!the_lnet.ln_nis_from_mod_params) {
1782                 rc = lnet_parse_networks(&net_head,
1783                                          lnet_get_networks());
1784                 if (rc < 0)
1785                         goto failed0;
1786         }
1787
1788         ni_count = lnet_startup_lndnis(&net_head);
1789         if (ni_count < 0) {
1790                 rc = ni_count;
1791                 goto failed0;
1792         }
1793
1794         if (!the_lnet.ln_nis_from_mod_params) {
1795                 rc = lnet_parse_routes(lnet_get_routes(), &im_a_router);
1796                 if (rc != 0)
1797                         goto failed1;
1798
1799                 rc = lnet_check_routes();
1800                 if (rc != 0)
1801                         goto failed2;
1802
1803                 rc = lnet_rtrpools_alloc(im_a_router);
1804                 if (rc != 0)
1805                         goto failed2;
1806         }
1807
1808         rc = lnet_acceptor_start();
1809         if (rc != 0)
1810                 goto failed2;
1811         the_lnet.ln_refcount = 1;
1812         /* Now I may use my own API functions... */
1813
1814         rc = lnet_ping_info_setup(&pinfo, &md_handle, ni_count, true);
1815         if (rc != 0)
1816                 goto failed3;
1817
1818         lnet_ping_target_update(pinfo, md_handle);
1819
1820         rc = lnet_router_checker_start();
1821         if (rc != 0)
1822                 goto failed4;
1823
1824         lnet_fault_init();
1825         lnet_proc_init();
1826
1827         LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex);
1828
1829         return 0;
1830
1831 failed4:
1832         lnet_ping_target_fini();
1833 failed3:
1834         the_lnet.ln_refcount = 0;
1835         lnet_acceptor_stop();
1836 failed2:
1837         if (!the_lnet.ln_nis_from_mod_params)
1838                 lnet_destroy_routes();
1839 failed1:
1840         lnet_shutdown_lndnis();
1841 failed0:
1842         lnet_unprepare();
1843         LASSERT(rc < 0);
1844         LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex);
1845         while (!list_empty(&net_head)) {
1846                 struct lnet_ni *ni;
1847                 ni = list_entry(net_head.next, struct lnet_ni, ni_list);
1848                 list_del_init(&ni->ni_list);
1849                 lnet_ni_free(ni);
1850         }
1851         return rc;
1852 }
1853 EXPORT_SYMBOL(LNetNIInit);
1854
1855 /**
1856  * Stop LNet interfaces, routing, and forwarding.
1857  *
1858  * Users must call this function once for each successful call to LNetNIInit().
1859  * Once the LNetNIFini() operation has been started, the results of pending
1860  * API operations are undefined.
1861  *
1862  * \return always 0 for current implementation.
1863  */
1864 int
1865 LNetNIFini()
1866 {
1867         LNET_MUTEX_LOCK(&the_lnet.ln_api_mutex);
1868
1869         LASSERT (the_lnet.ln_init);
1870         LASSERT (the_lnet.ln_refcount > 0);
1871
1872         if (the_lnet.ln_refcount != 1) {
1873                 the_lnet.ln_refcount--;
1874         } else {
1875                 LASSERT(!the_lnet.ln_niinit_self);
1876
1877                 lnet_fault_fini();
1878
1879                 lnet_proc_fini();
1880                 lnet_router_checker_stop();
1881                 lnet_ping_target_fini();
1882
1883                 /* Teardown fns that use my own API functions BEFORE here */
1884                 the_lnet.ln_refcount = 0;
1885
1886                 lnet_acceptor_stop();
1887                 lnet_destroy_routes();
1888                 lnet_shutdown_lndnis();
1889                 lnet_unprepare();
1890         }
1891
1892         LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex);
1893         return 0;
1894 }
1895 EXPORT_SYMBOL(LNetNIFini);
1896
1897 /**
1898  * Grabs the ni data from the ni structure and fills the out
1899  * parameters
1900  *
1901  * \param[in] ni network        interface structure
1902  * \param[out] cpt_count        the number of cpts the ni is on
1903  * \param[out] nid              Network Interface ID
1904  * \param[out] peer_timeout     NI peer timeout
1905  * \param[out] peer_tx_crdits   NI peer transmit credits
1906  * \param[out] peer_rtr_credits NI peer router credits
1907  * \param[out] max_tx_credits   NI max transmit credit
1908  * \param[out] net_config       Network configuration
1909  */
1910 static void
1911 lnet_fill_ni_info(struct lnet_ni *ni, __u32 *cpt_count, __u64 *nid,
1912                   int *peer_timeout, int *peer_tx_credits,
1913                   int *peer_rtr_credits, int *max_tx_credits,
1914                   struct lnet_ioctl_net_config *net_config)
1915 {
1916         int i;
1917
1918         if (ni == NULL)
1919                 return;
1920
1921         if (net_config == NULL)
1922                 return;
1923
1924         CLASSERT(ARRAY_SIZE(ni->ni_interfaces) ==
1925                  ARRAY_SIZE(net_config->ni_interfaces));
1926
1927         if (ni->ni_interfaces[0] != NULL) {
1928                 for (i = 0; i < ARRAY_SIZE(ni->ni_interfaces); i++) {
1929                         if (ni->ni_interfaces[i] != NULL) {
1930                                 strncpy(net_config->ni_interfaces[i],
1931                                         ni->ni_interfaces[i],
1932                                         sizeof(net_config->ni_interfaces[i]));
1933                         }
1934                 }
1935         }
1936
1937         *nid = ni->ni_nid;
1938         *peer_timeout = ni->ni_peertimeout;
1939         *peer_tx_credits = ni->ni_peertxcredits;
1940         *peer_rtr_credits = ni->ni_peerrtrcredits;
1941         *max_tx_credits = ni->ni_maxtxcredits;
1942
1943         net_config->ni_status = ni->ni_status->ns_status;
1944
1945         for (i = 0;
1946              ni->ni_cpts != NULL && i < ni->ni_ncpts &&
1947              i < LNET_MAX_SHOW_NUM_CPT;
1948              i++)
1949                 net_config->ni_cpts[i] = ni->ni_cpts[i];
1950
1951         *cpt_count = ni->ni_ncpts;
1952 }
1953
1954 int
1955 lnet_get_net_config(int idx, __u32 *cpt_count, __u64 *nid, int *peer_timeout,
1956                     int *peer_tx_credits, int *peer_rtr_credits,
1957                     int *max_tx_credits,
1958                     struct lnet_ioctl_net_config *net_config)
1959 {
1960         struct lnet_ni          *ni;
1961         struct list_head        *tmp;
1962         int                     cpt;
1963         int                     rc = -ENOENT;
1964
1965         cpt = lnet_net_lock_current();
1966
1967         list_for_each(tmp, &the_lnet.ln_nis) {
1968                 ni = list_entry(tmp, lnet_ni_t, ni_list);
1969                 if (idx-- == 0) {
1970                         rc = 0;
1971                         lnet_ni_lock(ni);
1972                         lnet_fill_ni_info(ni, cpt_count, nid, peer_timeout,
1973                                           peer_tx_credits, peer_rtr_credits,
1974                                           max_tx_credits, net_config);
1975                         lnet_ni_unlock(ni);
1976                         break;
1977                 }
1978         }
1979
1980         lnet_net_unlock(cpt);
1981         return rc;
1982 }
1983
1984 int
1985 lnet_dyn_add_ni(lnet_pid_t requested_pid, char *nets,
1986                 __s32 peer_timeout, __s32 peer_cr, __s32 peer_buf_cr,
1987                 __s32 credits)
1988 {
1989         lnet_ping_info_t        *pinfo;
1990         lnet_handle_md_t        md_handle;
1991         struct lnet_ni          *ni;
1992         struct list_head        net_head;
1993         int                     rc;
1994         lnet_remotenet_t        *rnet;
1995
1996         INIT_LIST_HEAD(&net_head);
1997
1998         /* Create a ni structure for the network string */
1999         rc = lnet_parse_networks(&net_head, nets);
2000         if (rc <= 0)
2001                 return rc == 0 ? -EINVAL : rc;
2002
2003         LNET_MUTEX_LOCK(&the_lnet.ln_api_mutex);
2004
2005         if (rc > 1) {
2006                 rc = -EINVAL; /* only add one interface per call */
2007                 goto failed0;
2008         }
2009
2010         ni = list_entry(net_head.next, struct lnet_ni, ni_list);
2011
2012         lnet_net_lock(LNET_LOCK_EX);
2013         rnet = lnet_find_net_locked(LNET_NIDNET(ni->ni_nid));
2014         lnet_net_unlock(LNET_LOCK_EX);
2015         /* make sure that the net added doesn't invalidate the current
2016          * configuration LNet is keeping */
2017         if (rnet != NULL) {
2018                 CERROR("Adding net %s will invalidate routing configuration\n",
2019                        nets);
2020                 rc = -EUSERS;
2021                 goto failed0;
2022         }
2023
2024         rc = lnet_ping_info_setup(&pinfo, &md_handle, 1 + lnet_get_ni_count(),
2025                                   false);
2026         if (rc != 0)
2027                 goto failed0;
2028
2029         list_del_init(&ni->ni_list);
2030
2031         rc = lnet_startup_lndni(ni, peer_timeout, peer_cr,
2032                                 peer_buf_cr, credits);
2033         if (rc != 0)
2034                 goto failed1;
2035
2036         if (ni->ni_lnd->lnd_accept != NULL) {
2037                 rc = lnet_acceptor_start();
2038                 if (rc < 0) {
2039                         /* shutdown the ni that we just started */
2040                         CERROR("Failed to start up acceptor thread\n");
2041                         lnet_shutdown_lndni(ni);
2042                         goto failed1;
2043                 }
2044         }
2045
2046         lnet_ping_target_update(pinfo, md_handle);
2047         LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex);
2048
2049         return 0;
2050
2051 failed1:
2052         lnet_ping_md_unlink(pinfo, &md_handle);
2053         lnet_ping_info_free(pinfo);
2054 failed0:
2055         LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex);
2056         while (!list_empty(&net_head)) {
2057                 ni = list_entry(net_head.next, struct lnet_ni, ni_list);
2058                 list_del_init(&ni->ni_list);
2059                 lnet_ni_free(ni);
2060         }
2061         return rc;
2062 }
2063
2064 int
2065 lnet_dyn_del_ni(__u32 net)
2066 {
2067         lnet_ni_t        *ni;
2068         lnet_ping_info_t *pinfo;
2069         lnet_handle_md_t  md_handle;
2070         int               rc;
2071
2072         /* don't allow userspace to shutdown the LOLND */
2073         if (LNET_NETTYP(net) == LOLND)
2074                 return -EINVAL;
2075
2076         LNET_MUTEX_LOCK(&the_lnet.ln_api_mutex);
2077         /* create and link a new ping info, before removing the old one */
2078         rc = lnet_ping_info_setup(&pinfo, &md_handle,
2079                                   lnet_get_ni_count() - 1, false);
2080         if (rc != 0)
2081                 goto out;
2082
2083         ni = lnet_net2ni(net);
2084         if (ni == NULL) {
2085                 rc = -EINVAL;
2086                 goto failed;
2087         }
2088
2089         /* decrement the reference counter taken by lnet_net2ni() */
2090         lnet_ni_decref_locked(ni, 0);
2091
2092         lnet_shutdown_lndni(ni);
2093
2094         if (lnet_count_acceptor_nis() == 0)
2095                 lnet_acceptor_stop();
2096
2097         lnet_ping_target_update(pinfo, md_handle);
2098         goto out;
2099 failed:
2100         lnet_ping_md_unlink(pinfo, &md_handle);
2101         lnet_ping_info_free(pinfo);
2102 out:
2103         LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex);
2104
2105         return rc;
2106 }
2107
2108 /**
2109  * This is an ugly hack to export IOC_LIBCFS_DEBUG_PEER and
2110  * IOC_LIBCFS_PORTALS_COMPATIBILITY commands to users, by tweaking the LNet
2111  * internal ioctl handler.
2112  *
2113  * IOC_LIBCFS_PORTALS_COMPATIBILITY is now deprecated, don't use it.
2114  *
2115  * \param cmd IOC_LIBCFS_DEBUG_PEER to print debugging data about a peer.
2116  * The data will be printed to system console. Don't use it excessively.
2117  * \param arg A pointer to lnet_process_id_t, process ID of the peer.
2118  *
2119  * \return Always return 0 when called by users directly (i.e., not via ioctl).
2120  */
2121 int
2122 LNetCtl(unsigned int cmd, void *arg)
2123 {
2124         struct libcfs_ioctl_data *data = arg;
2125         struct lnet_ioctl_config_data *config;
2126         lnet_process_id_t         id = {0};
2127         lnet_ni_t                *ni;
2128         int                       rc;
2129
2130         CLASSERT(LIBCFS_IOC_DATA_MAX >= sizeof(struct lnet_ioctl_net_config) +
2131                                         sizeof(struct lnet_ioctl_config_data));
2132         LASSERT(the_lnet.ln_init);
2133
2134         switch (cmd) {
2135         case IOC_LIBCFS_GET_NI:
2136                 rc = LNetGetId(data->ioc_count, &id);
2137                 data->ioc_nid = id.nid;
2138                 return rc;
2139
2140         case IOC_LIBCFS_FAIL_NID:
2141                 return lnet_fail_nid(data->ioc_nid, data->ioc_count);
2142
2143         case IOC_LIBCFS_ADD_ROUTE:
2144                 config = arg;
2145
2146                 if (config->cfg_hdr.ioc_len < sizeof(*config))
2147                         return -EINVAL;
2148
2149                 LNET_MUTEX_LOCK(&the_lnet.ln_api_mutex);
2150                 rc = lnet_add_route(config->cfg_net,
2151                                     config->cfg_config_u.cfg_route.rtr_hop,
2152                                     config->cfg_nid,
2153                                     config->cfg_config_u.cfg_route.
2154                                         rtr_priority);
2155                 LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex);
2156                 return (rc != 0) ? rc : lnet_check_routes();
2157
2158         case IOC_LIBCFS_DEL_ROUTE:
2159                 config = arg;
2160
2161                 if (config->cfg_hdr.ioc_len < sizeof(*config))
2162                         return -EINVAL;
2163
2164                 LNET_MUTEX_LOCK(&the_lnet.ln_api_mutex);
2165                 rc = lnet_del_route(config->cfg_net, config->cfg_nid);
2166                 LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex);
2167                 return rc;
2168
2169         case IOC_LIBCFS_GET_ROUTE:
2170                 config = arg;
2171
2172                 if (config->cfg_hdr.ioc_len < sizeof(*config))
2173                         return -EINVAL;
2174
2175                 return lnet_get_route(config->cfg_count,
2176                                       &config->cfg_net,
2177                                       &config->cfg_config_u.cfg_route.rtr_hop,
2178                                       &config->cfg_nid,
2179                                       &config->cfg_config_u.cfg_route.rtr_flags,
2180                                       &config->cfg_config_u.cfg_route.
2181                                         rtr_priority);
2182
2183         case IOC_LIBCFS_GET_NET: {
2184                 struct lnet_ioctl_net_config *net_config;
2185                 size_t total = sizeof(*config) + sizeof(*net_config);
2186
2187                 config = arg;
2188
2189                 if (config->cfg_hdr.ioc_len < total)
2190                         return -EINVAL;
2191
2192                 net_config = (struct lnet_ioctl_net_config *)
2193                         config->cfg_bulk;
2194                 if (config == NULL || net_config == NULL)
2195                         return -1;
2196
2197                 return lnet_get_net_config(config->cfg_count,
2198                                            &config->cfg_ncpts,
2199                                            &config->cfg_nid,
2200                                            &config->cfg_config_u.
2201                                                 cfg_net.net_peer_timeout,
2202                                            &config->cfg_config_u.cfg_net.
2203                                                 net_peer_tx_credits,
2204                                            &config->cfg_config_u.cfg_net.
2205                                                 net_peer_rtr_credits,
2206                                            &config->cfg_config_u.cfg_net.
2207                                                 net_max_tx_credits,
2208                                            net_config);
2209         }
2210
2211         case IOC_LIBCFS_GET_LNET_STATS:
2212         {
2213                 struct lnet_ioctl_lnet_stats *lnet_stats = arg;
2214
2215                 if (lnet_stats->st_hdr.ioc_len < sizeof(*lnet_stats))
2216                         return -EINVAL;
2217
2218                 lnet_counters_get(&lnet_stats->st_cntrs);
2219                 return 0;
2220         }
2221
2222 #if defined(__KERNEL__) && defined(LNET_ROUTER)
2223         case IOC_LIBCFS_CONFIG_RTR:
2224                 config = arg;
2225
2226                 if (config->cfg_hdr.ioc_len < sizeof(*config))
2227                         return -EINVAL;
2228
2229                 LNET_MUTEX_LOCK(&the_lnet.ln_api_mutex);
2230                 if (config->cfg_config_u.cfg_buffers.buf_enable) {
2231                         rc = lnet_rtrpools_enable();
2232                         LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex);
2233                         return rc;
2234                 }
2235                 lnet_rtrpools_disable();
2236                 LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex);
2237                 return 0;
2238
2239         case IOC_LIBCFS_ADD_BUF:
2240                 config = arg;
2241
2242                 if (config->cfg_hdr.ioc_len < sizeof(*config))
2243                         return -EINVAL;
2244
2245                 LNET_MUTEX_LOCK(&the_lnet.ln_api_mutex);
2246                 rc = lnet_rtrpools_adjust(config->cfg_config_u.cfg_buffers.
2247                                                 buf_tiny,
2248                                           config->cfg_config_u.cfg_buffers.
2249                                                 buf_small,
2250                                           config->cfg_config_u.cfg_buffers.
2251                                                 buf_large);
2252                 LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex);
2253                 return rc;
2254 #endif
2255
2256         case IOC_LIBCFS_GET_BUF: {
2257                 struct lnet_ioctl_pool_cfg *pool_cfg;
2258                 size_t total = sizeof(*config) + sizeof(*pool_cfg);
2259
2260                 config = arg;
2261
2262                 if (config->cfg_hdr.ioc_len < total)
2263                         return -EINVAL;
2264
2265                 pool_cfg = (struct lnet_ioctl_pool_cfg *)config->cfg_bulk;
2266                 return lnet_get_rtr_pool_cfg(config->cfg_count, pool_cfg);
2267         }
2268
2269         case IOC_LIBCFS_GET_PEER_INFO: {
2270                 struct lnet_ioctl_peer *peer_info = arg;
2271
2272                 if (peer_info->pr_hdr.ioc_len < sizeof(*peer_info))
2273                         return -EINVAL;
2274
2275                 return lnet_get_peer_info(
2276                    peer_info->pr_count,
2277                    &peer_info->pr_nid,
2278                    peer_info->pr_lnd_u.pr_peer_credits.cr_aliveness,
2279                    &peer_info->pr_lnd_u.pr_peer_credits.cr_ncpt,
2280                    &peer_info->pr_lnd_u.pr_peer_credits.cr_refcount,
2281                    &peer_info->pr_lnd_u.pr_peer_credits.cr_ni_peer_tx_credits,
2282                    &peer_info->pr_lnd_u.pr_peer_credits.cr_peer_tx_credits,
2283                    &peer_info->pr_lnd_u.pr_peer_credits.cr_peer_rtr_credits,
2284                    &peer_info->pr_lnd_u.pr_peer_credits.cr_peer_min_rtr_credits,
2285                    &peer_info->pr_lnd_u.pr_peer_credits.cr_peer_tx_qnob);
2286         }
2287
2288         case IOC_LIBCFS_NOTIFY_ROUTER:
2289                 return lnet_notify(NULL, data->ioc_nid, data->ioc_flags,
2290                                    cfs_time_current() -
2291                                    cfs_time_seconds(cfs_time_current_sec() -
2292                                                     (time_t)data->ioc_u64[0]));
2293
2294         case IOC_LIBCFS_PORTALS_COMPATIBILITY:
2295                 /* This can be removed once lustre stops calling it */
2296                 return 0;
2297
2298         case IOC_LIBCFS_LNET_DIST:
2299                 rc = LNetDist(data->ioc_nid, &data->ioc_nid, &data->ioc_u32[1]);
2300                 if (rc < 0 && rc != -EHOSTUNREACH)
2301                         return rc;
2302
2303                 data->ioc_u32[0] = rc;
2304                 return 0;
2305
2306         case IOC_LIBCFS_TESTPROTOCOMPAT:
2307                 lnet_net_lock(LNET_LOCK_EX);
2308                 the_lnet.ln_testprotocompat = data->ioc_flags;
2309                 lnet_net_unlock(LNET_LOCK_EX);
2310                 return 0;
2311
2312         case IOC_LIBCFS_LNET_FAULT:
2313                 return lnet_fault_ctl(data->ioc_flags, data);
2314
2315         case IOC_LIBCFS_PING:
2316                 id.nid = data->ioc_nid;
2317                 id.pid = data->ioc_u32[0];
2318                 rc = lnet_ping(id, data->ioc_u32[1], /* timeout */
2319                                (lnet_process_id_t __user *)data->ioc_pbuf1,
2320                                data->ioc_plen1/sizeof(lnet_process_id_t));
2321                 if (rc < 0)
2322                         return rc;
2323                 data->ioc_count = rc;
2324                 return 0;
2325
2326         case IOC_LIBCFS_DEBUG_PEER: {
2327                 /* CAVEAT EMPTOR: this one designed for calling directly; not
2328                  * via an ioctl */
2329                 id = *((lnet_process_id_t *) arg);
2330
2331                 lnet_debug_peer(id.nid);
2332
2333                 ni = lnet_net2ni(LNET_NIDNET(id.nid));
2334                 if (ni == NULL) {
2335                         CDEBUG(D_WARNING, "No NI for %s\n", libcfs_id2str(id));
2336                 } else {
2337                         if (ni->ni_lnd->lnd_ctl == NULL) {
2338                                 CDEBUG(D_WARNING, "No ctl for %s\n",
2339                                        libcfs_id2str(id));
2340                         } else {
2341                                 (void)ni->ni_lnd->lnd_ctl(ni, cmd, arg);
2342                         }
2343
2344                         lnet_ni_decref(ni);
2345                 }
2346                 return 0;
2347         }
2348
2349         default:
2350                 ni = lnet_net2ni(data->ioc_net);
2351                 if (ni == NULL)
2352                         return -EINVAL;
2353
2354                 if (ni->ni_lnd->lnd_ctl == NULL)
2355                         rc = -EINVAL;
2356                 else
2357                         rc = ni->ni_lnd->lnd_ctl(ni, cmd, arg);
2358
2359                 lnet_ni_decref(ni);
2360                 return rc;
2361         }
2362         /* not reached */
2363 }
2364 EXPORT_SYMBOL(LNetCtl);
2365
2366 /**
2367  * Retrieve the lnet_process_id_t ID of LNet interface at \a index. Note that
2368  * all interfaces share a same PID, as requested by LNetNIInit().
2369  *
2370  * \param index Index of the interface to look up.
2371  * \param id On successful return, this location will hold the
2372  * lnet_process_id_t ID of the interface.
2373  *
2374  * \retval 0 If an interface exists at \a index.
2375  * \retval -ENOENT If no interface has been found.
2376  */
2377 int
2378 LNetGetId(unsigned int index, lnet_process_id_t *id)
2379 {
2380         struct lnet_ni   *ni;
2381         struct list_head *tmp;
2382         int               cpt;
2383         int               rc = -ENOENT;
2384
2385         LASSERT(the_lnet.ln_init);
2386         LASSERT(the_lnet.ln_refcount > 0);
2387
2388         cpt = lnet_net_lock_current();
2389
2390         list_for_each(tmp, &the_lnet.ln_nis) {
2391                 if (index-- != 0)
2392                         continue;
2393
2394                 ni = list_entry(tmp, lnet_ni_t, ni_list);
2395
2396                 id->nid = ni->ni_nid;
2397                 id->pid = the_lnet.ln_pid;
2398                 rc = 0;
2399                 break;
2400         }
2401
2402         lnet_net_unlock(cpt);
2403         return rc;
2404 }
2405 EXPORT_SYMBOL(LNetGetId);
2406
2407 /**
2408  * Print a string representation of handle \a h into buffer \a str of
2409  * \a len bytes.
2410  */
2411 void
2412 LNetSnprintHandle(char *str, int len, lnet_handle_any_t h)
2413 {
2414         snprintf(str, len, LPX64, h.cookie);
2415 }
2416 EXPORT_SYMBOL(LNetSnprintHandle);
2417
2418 static int
2419 lnet_ping(lnet_process_id_t id, int timeout_ms, lnet_process_id_t __user *ids,
2420           int n_ids)
2421 {
2422         lnet_handle_eq_t     eqh;
2423         lnet_handle_md_t     mdh;
2424         lnet_event_t         event;
2425         lnet_md_t            md = { NULL };
2426         int                  which;
2427         int                  unlinked = 0;
2428         int                  replied = 0;
2429         const int            a_long_time = 60000; /* mS */
2430         int                  infosz;
2431         lnet_ping_info_t    *info;
2432         lnet_process_id_t    tmpid;
2433         int                  i;
2434         int                  nob;
2435         int                  rc;
2436         int                  rc2;
2437         sigset_t         blocked;
2438
2439         infosz = offsetof(lnet_ping_info_t, pi_ni[n_ids]);
2440
2441         if (n_ids <= 0 ||
2442             id.nid == LNET_NID_ANY ||
2443             timeout_ms > 500000 ||              /* arbitrary limit! */
2444             n_ids > 20)                         /* arbitrary limit! */
2445                 return -EINVAL;
2446
2447         if (id.pid == LNET_PID_ANY)
2448                 id.pid = LNET_PID_LUSTRE;
2449
2450         LIBCFS_ALLOC(info, infosz);
2451         if (info == NULL)
2452                 return -ENOMEM;
2453
2454         /* NB 2 events max (including any unlink event) */
2455         rc = LNetEQAlloc(2, LNET_EQ_HANDLER_NONE, &eqh);
2456         if (rc != 0) {
2457                 CERROR("Can't allocate EQ: %d\n", rc);
2458                 goto out_0;
2459         }
2460
2461         /* initialize md content */
2462         md.start     = info;
2463         md.length    = infosz;
2464         md.threshold = 2; /*GET/REPLY*/
2465         md.max_size  = 0;
2466         md.options   = LNET_MD_TRUNCATE;
2467         md.user_ptr  = NULL;
2468         md.eq_handle = eqh;
2469
2470         rc = LNetMDBind(md, LNET_UNLINK, &mdh);
2471         if (rc != 0) {
2472                 CERROR("Can't bind MD: %d\n", rc);
2473                 goto out_1;
2474         }
2475
2476         rc = LNetGet(LNET_NID_ANY, mdh, id,
2477                      LNET_RESERVED_PORTAL,
2478                      LNET_PROTO_PING_MATCHBITS, 0);
2479
2480         if (rc != 0) {
2481                 /* Don't CERROR; this could be deliberate! */
2482
2483                 rc2 = LNetMDUnlink(mdh);
2484                 LASSERT(rc2 == 0);
2485
2486                 /* NB must wait for the UNLINK event below... */
2487                 unlinked = 1;
2488                 timeout_ms = a_long_time;
2489         }
2490
2491         do {
2492                 /* MUST block for unlink to complete */
2493                 if (unlinked)
2494                         blocked = cfs_block_allsigs();
2495
2496                 rc2 = LNetEQPoll(&eqh, 1, timeout_ms, &event, &which);
2497
2498                 if (unlinked)
2499                         cfs_restore_sigs(blocked);
2500
2501                 CDEBUG(D_NET, "poll %d(%d %d)%s\n", rc2,
2502                        (rc2 <= 0) ? -1 : event.type,
2503                        (rc2 <= 0) ? -1 : event.status,
2504                        (rc2 > 0 && event.unlinked) ? " unlinked" : "");
2505
2506                 LASSERT(rc2 != -EOVERFLOW);     /* can't miss anything */
2507
2508                 if (rc2 <= 0 || event.status != 0) {
2509                         /* timeout or error */
2510                         if (!replied && rc == 0)
2511                                 rc = (rc2 < 0) ? rc2 :
2512                                      (rc2 == 0) ? -ETIMEDOUT :
2513                                      event.status;
2514
2515                         if (!unlinked) {
2516                                 /* Ensure completion in finite time... */
2517                                 LNetMDUnlink(mdh);
2518                                 /* No assertion (racing with network) */
2519                                 unlinked = 1;
2520                                 timeout_ms = a_long_time;
2521                         } else if (rc2 == 0) {
2522                                 /* timed out waiting for unlink */
2523                                 CWARN("ping %s: late network completion\n",
2524                                       libcfs_id2str(id));
2525                         }
2526                 } else if (event.type == LNET_EVENT_REPLY) {
2527                         replied = 1;
2528                         rc = event.mlength;
2529                 }
2530
2531         } while (rc2 <= 0 || !event.unlinked);
2532
2533         if (!replied) {
2534                 if (rc >= 0)
2535                         CWARN("%s: Unexpected rc >= 0 but no reply!\n",
2536                               libcfs_id2str(id));
2537                 rc = -EIO;
2538                 goto out_1;
2539         }
2540
2541         nob = rc;
2542         LASSERT(nob >= 0 && nob <= infosz);
2543
2544         rc = -EPROTO;                           /* if I can't parse... */
2545
2546         if (nob < 8) {
2547                 /* can't check magic/version */
2548                 CERROR("%s: ping info too short %d\n",
2549                        libcfs_id2str(id), nob);
2550                 goto out_1;
2551         }
2552
2553         if (info->pi_magic == __swab32(LNET_PROTO_PING_MAGIC)) {
2554                 lnet_swap_pinginfo(info);
2555         } else if (info->pi_magic != LNET_PROTO_PING_MAGIC) {
2556                 CERROR("%s: Unexpected magic %08x\n",
2557                        libcfs_id2str(id), info->pi_magic);
2558                 goto out_1;
2559         }
2560
2561         if ((info->pi_features & LNET_PING_FEAT_NI_STATUS) == 0) {
2562                 CERROR("%s: ping w/o NI status: 0x%x\n",
2563                        libcfs_id2str(id), info->pi_features);
2564                 goto out_1;
2565         }
2566
2567         if (nob < offsetof(lnet_ping_info_t, pi_ni[0])) {
2568                 CERROR("%s: Short reply %d(%d min)\n", libcfs_id2str(id),
2569                        nob, (int)offsetof(lnet_ping_info_t, pi_ni[0]));
2570                 goto out_1;
2571         }
2572
2573         if (info->pi_nnis < n_ids)
2574                 n_ids = info->pi_nnis;
2575
2576         if (nob < offsetof(lnet_ping_info_t, pi_ni[n_ids])) {
2577                 CERROR("%s: Short reply %d(%d expected)\n", libcfs_id2str(id),
2578                        nob, (int)offsetof(lnet_ping_info_t, pi_ni[n_ids]));
2579                 goto out_1;
2580         }
2581
2582         rc = -EFAULT;                           /* If I SEGV... */
2583
2584         for (i = 0; i < n_ids; i++) {
2585                 tmpid.pid = info->pi_pid;
2586                 tmpid.nid = info->pi_ni[i].ns_nid;
2587                 if (copy_to_user(&ids[i], &tmpid, sizeof(tmpid)))
2588                         goto out_1;
2589         }
2590         rc = info->pi_nnis;
2591
2592  out_1:
2593         rc2 = LNetEQFree(eqh);
2594         if (rc2 != 0)
2595                 CERROR("rc2 %d\n", rc2);
2596         LASSERT(rc2 == 0);
2597
2598  out_0:
2599         LIBCFS_FREE(info, infosz);
2600         return rc;
2601 }