Whamcloud - gitweb
b=22860 lnet_msg_alloc does double memset to zero
[fs/lustre-release.git] / lnet / include / lnet / lib-lnet.h
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * GPL HEADER START
5  *
6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 only,
10  * as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License version 2 for more details (a copy is included
16  * in the LICENSE file that accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License
19  * version 2 along with this program; If not, see
20  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
21  *
22  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23  * CA 95054 USA or visit www.sun.com if you need additional information or
24  * have any questions.
25  *
26  * GPL HEADER END
27  */
28 /*
29  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
30  * Use is subject to license terms.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  *
36  * lnet/include/lnet/lib-lnet.h
37  *
38  * Top level include for library side routines
39  */
40
41 #ifndef __LNET_LIB_LNET_H__
42 #define __LNET_LIB_LNET_H__
43
44 #if defined(__linux__)
45 #include <lnet/linux/lib-lnet.h>
46 #elif defined(__APPLE__)
47 #include <lnet/darwin/lib-lnet.h>
48 #elif defined(__WINNT__)
49 #include <lnet/winnt/lib-lnet.h>
50 #else
51 #error Unsupported Operating System
52 #endif
53
54 #include <libcfs/libcfs.h>
55 #include <lnet/types.h>
56 #include <lnet/lnet.h>
57 #include <lnet/lib-types.h>
58
59 extern lnet_t  the_lnet;                        /* THE network */
60
61 static inline int lnet_is_wire_handle_none (lnet_handle_wire_t *wh)
62 {
63         return (wh->wh_interface_cookie == LNET_WIRE_HANDLE_COOKIE_NONE &&
64                 wh->wh_object_cookie == LNET_WIRE_HANDLE_COOKIE_NONE);
65 }
66
67 static inline int lnet_md_exhausted (lnet_libmd_t *md)
68 {
69         return (md->md_threshold == 0 ||
70                 ((md->md_options & LNET_MD_MAX_SIZE) != 0 &&
71                  md->md_offset + md->md_max_size > md->md_length));
72 }
73
74 static inline int lnet_md_unlinkable (lnet_libmd_t *md)
75 {
76         /* Should unlink md when its refcount is 0 and either:
77          *  - md has been flagged for deletion (by auto unlink or LNetM[DE]Unlink,
78          *    in the latter case md may not be exhausted).
79          *  - auto unlink is on and md is exhausted.
80          */
81         if (md->md_refcount != 0)
82                 return 0;
83
84         if ((md->md_flags & LNET_MD_FLAG_ZOMBIE) != 0)
85                 return 1;
86
87         return ((md->md_flags & LNET_MD_FLAG_AUTO_UNLINK) != 0 &&
88                 lnet_md_exhausted(md));
89 }
90
91 static inline unsigned int
92 lnet_match_to_hash(lnet_process_id_t id, __u64 mbits)
93 {
94         mbits += id.nid + id.pid;
95         return cfs_hash_long((unsigned long)mbits, LNET_PORTAL_HASH_BITS);
96 }
97
98 #ifdef __KERNEL__
99 #define LNET_LOCK()        cfs_spin_lock(&the_lnet.ln_lock)
100 #define LNET_UNLOCK()      cfs_spin_unlock(&the_lnet.ln_lock)
101 #define LNET_MUTEX_DOWN(m) cfs_mutex_down(m)
102 #define LNET_MUTEX_UP(m)   cfs_mutex_up(m)
103 #else
104 # ifndef HAVE_LIBPTHREAD
105 #define LNET_SINGLE_THREADED_LOCK(l)            \
106 do {                                            \
107         LASSERT ((l) == 0);                     \
108         (l) = 1;                                \
109 } while (0)
110
111 #define LNET_SINGLE_THREADED_UNLOCK(l)          \
112 do {                                            \
113         LASSERT ((l) == 1);                     \
114         (l) = 0;                                \
115 } while (0)
116
117 #define LNET_LOCK()        LNET_SINGLE_THREADED_LOCK(the_lnet.ln_lock)
118 #define LNET_UNLOCK()      LNET_SINGLE_THREADED_UNLOCK(the_lnet.ln_lock)
119 #define LNET_MUTEX_DOWN(m) LNET_SINGLE_THREADED_LOCK(*(m))
120 #define LNET_MUTEX_UP(m)   LNET_SINGLE_THREADED_UNLOCK(*(m))
121 # else
122 #define LNET_LOCK()        pthread_mutex_lock(&the_lnet.ln_lock)
123 #define LNET_UNLOCK()      pthread_mutex_unlock(&the_lnet.ln_lock)
124 #define LNET_MUTEX_DOWN(m) pthread_mutex_lock(m)
125 #define LNET_MUTEX_UP(m)   pthread_mutex_unlock(m)
126 # endif
127 #endif
128
129 #define MAX_PORTALS     64
130
131 #ifdef LNET_USE_LIB_FREELIST
132
133 #define MAX_MES         2048
134 #define MAX_MDS         2048
135 #define MAX_MSGS        2048    /* Outstanding messages */
136 #define MAX_EQS         512
137
138 static inline void *
139 lnet_freelist_alloc (lnet_freelist_t *fl)
140 {
141         /* ALWAYS called with liblock held */
142         lnet_freeobj_t *o;
143
144         if (cfs_list_empty (&fl->fl_list))
145                 return (NULL);
146
147         o = cfs_list_entry (fl->fl_list.next, lnet_freeobj_t, fo_list);
148         cfs_list_del (&o->fo_list);
149         return ((void *)&o->fo_contents);
150 }
151
152 static inline void
153 lnet_freelist_free (lnet_freelist_t *fl, void *obj)
154 {
155         /* ALWAYS called with liblock held */
156         lnet_freeobj_t *o = cfs_list_entry (obj, lnet_freeobj_t, fo_contents);
157
158         cfs_list_add (&o->fo_list, &fl->fl_list);
159 }
160
161
162 static inline lnet_eq_t *
163 lnet_eq_alloc (void)
164 {
165         /* NEVER called with liblock held */
166         lnet_eq_t     *eq;
167
168         LNET_LOCK();
169         eq = (lnet_eq_t *)lnet_freelist_alloc(&the_lnet.ln_free_eqs);
170         LNET_UNLOCK();
171
172         return (eq);
173 }
174
175 static inline void
176 lnet_eq_free (lnet_eq_t *eq)
177 {
178         /* ALWAYS called with liblock held */
179         lnet_freelist_free(&the_lnet.ln_free_eqs, eq);
180 }
181
182 static inline lnet_libmd_t *
183 lnet_md_alloc (lnet_md_t *umd)
184 {
185         /* NEVER called with liblock held */
186         lnet_libmd_t  *md;
187
188         LNET_LOCK();
189         md = (lnet_libmd_t *)lnet_freelist_alloc(&the_lnet.ln_free_mds);
190         LNET_UNLOCK();
191
192         if (md != NULL)
193                 CFS_INIT_LIST_HEAD(&md->md_list);
194
195         return (md);
196 }
197
198 static inline void
199 lnet_md_free (lnet_libmd_t *md)
200 {
201         /* ALWAYS called with liblock held */
202         lnet_freelist_free (&the_lnet.ln_free_mds, md);
203 }
204
205 static inline lnet_me_t *
206 lnet_me_alloc (void)
207 {
208         /* NEVER called with liblock held */
209         lnet_me_t     *me;
210
211         LNET_LOCK();
212         me = (lnet_me_t *)lnet_freelist_alloc(&the_lnet.ln_free_mes);
213         LNET_UNLOCK();
214
215         return (me);
216 }
217
218 static inline void
219 lnet_me_free (lnet_me_t *me)
220 {
221         /* ALWAYS called with liblock held */
222         lnet_freelist_free (&the_lnet.ln_free_mes, me);
223 }
224
225 static inline lnet_msg_t *
226 lnet_msg_alloc (void)
227 {
228         /* NEVER called with liblock held */
229         lnet_msg_t    *msg;
230
231         LNET_LOCK();
232         msg = (lnet_msg_t *)lnet_freelist_alloc(&the_lnet.ln_free_msgs);
233         LNET_UNLOCK();
234
235         if (msg != NULL) {
236                 /* NULL pointers, clear flags etc */
237                 memset (msg, 0, sizeof (*msg));
238 #ifdef CRAY_XT3
239                 msg->msg_ev.uid = LNET_UID_ANY;
240 #endif
241         }
242         return(msg);
243 }
244
245 static inline void
246 lnet_msg_free (lnet_msg_t *msg)
247 {
248         /* ALWAYS called with liblock held */
249         LASSERT (!msg->msg_onactivelist);
250         lnet_freelist_free(&the_lnet.ln_free_msgs, msg);
251 }
252
253 #else
254
255 static inline lnet_eq_t *
256 lnet_eq_alloc (void)
257 {
258         /* NEVER called with liblock held */
259         lnet_eq_t *eq;
260
261         LIBCFS_ALLOC(eq, sizeof(*eq));
262         return (eq);
263 }
264
265 static inline void
266 lnet_eq_free (lnet_eq_t *eq)
267 {
268         /* ALWAYS called with liblock held */
269         LIBCFS_FREE(eq, sizeof(*eq));
270 }
271
272 static inline lnet_libmd_t *
273 lnet_md_alloc (lnet_md_t *umd)
274 {
275         /* NEVER called with liblock held */
276         lnet_libmd_t *md;
277         unsigned int  size;
278         unsigned int  niov;
279
280         if ((umd->options & LNET_MD_KIOV) != 0) {
281                 niov = umd->length;
282                 size = offsetof(lnet_libmd_t, md_iov.kiov[niov]);
283         } else {
284                 niov = ((umd->options & LNET_MD_IOVEC) != 0) ?
285                        umd->length : 1;
286                 size = offsetof(lnet_libmd_t, md_iov.iov[niov]);
287         }
288
289         LIBCFS_ALLOC(md, size);
290
291         if (md != NULL) {
292                 /* Set here in case of early free */
293                 md->md_options = umd->options;
294                 md->md_niov = niov;
295                 CFS_INIT_LIST_HEAD(&md->md_list);
296         }
297
298         return (md);
299 }
300
301 static inline void
302 lnet_md_free (lnet_libmd_t *md)
303 {
304         /* ALWAYS called with liblock held */
305         unsigned int  size;
306
307         if ((md->md_options & LNET_MD_KIOV) != 0)
308                 size = offsetof(lnet_libmd_t, md_iov.kiov[md->md_niov]);
309         else
310                 size = offsetof(lnet_libmd_t, md_iov.iov[md->md_niov]);
311
312         LIBCFS_FREE(md, size);
313 }
314
315 static inline lnet_me_t *
316 lnet_me_alloc (void)
317 {
318         /* NEVER called with liblock held */
319         lnet_me_t *me;
320
321         LIBCFS_ALLOC(me, sizeof(*me));
322         return (me);
323 }
324
325 static inline void
326 lnet_me_free(lnet_me_t *me)
327 {
328         /* ALWAYS called with liblock held */
329         LIBCFS_FREE(me, sizeof(*me));
330 }
331
332 static inline lnet_msg_t *
333 lnet_msg_alloc(void)
334 {
335         /* NEVER called with liblock held */
336         lnet_msg_t *msg;
337
338         LIBCFS_ALLOC(msg, sizeof(*msg));
339
340         /* no need to zero, LIBCFS_ALLOC does for us */
341
342 #ifdef CRAY_XT3
343         if (msg != NULL) {
344                 msg->msg_ev.uid = LNET_UID_ANY;
345         }
346 #endif
347         return (msg);
348 }
349
350 static inline void
351 lnet_msg_free(lnet_msg_t *msg)
352 {
353         /* ALWAYS called with liblock held */
354         LASSERT (!msg->msg_onactivelist);
355         LIBCFS_FREE(msg, sizeof(*msg));
356 }
357 #endif
358
359 extern lnet_libhandle_t *lnet_lookup_cookie (__u64 cookie, int type);
360 extern void lnet_initialise_handle (lnet_libhandle_t *lh, int type);
361 extern void lnet_invalidate_handle (lnet_libhandle_t *lh);
362
363 static inline void
364 lnet_eq2handle (lnet_handle_eq_t *handle, lnet_eq_t *eq)
365 {
366         if (eq == NULL) {
367                 LNetInvalidateHandle(handle);
368                 return;
369         }
370
371         handle->cookie = eq->eq_lh.lh_cookie;
372 }
373
374 static inline lnet_eq_t *
375 lnet_handle2eq (lnet_handle_eq_t *handle)
376 {
377         /* ALWAYS called with liblock held */
378         lnet_libhandle_t *lh = lnet_lookup_cookie(handle->cookie,
379                                                   LNET_COOKIE_TYPE_EQ);
380         if (lh == NULL)
381                 return (NULL);
382
383         return (lh_entry (lh, lnet_eq_t, eq_lh));
384 }
385
386 static inline void
387 lnet_md2handle (lnet_handle_md_t *handle, lnet_libmd_t *md)
388 {
389         handle->cookie = md->md_lh.lh_cookie;
390 }
391
392 static inline lnet_libmd_t *
393 lnet_handle2md (lnet_handle_md_t *handle)
394 {
395         /* ALWAYS called with liblock held */
396         lnet_libhandle_t *lh = lnet_lookup_cookie(handle->cookie,
397                                                   LNET_COOKIE_TYPE_MD);
398         if (lh == NULL)
399                 return (NULL);
400
401         return (lh_entry (lh, lnet_libmd_t, md_lh));
402 }
403
404 static inline lnet_libmd_t *
405 lnet_wire_handle2md (lnet_handle_wire_t *wh)
406 {
407         /* ALWAYS called with liblock held */
408         lnet_libhandle_t *lh;
409
410         if (wh->wh_interface_cookie != the_lnet.ln_interface_cookie)
411                 return (NULL);
412
413         lh = lnet_lookup_cookie(wh->wh_object_cookie,
414                                 LNET_COOKIE_TYPE_MD);
415         if (lh == NULL)
416                 return (NULL);
417
418         return (lh_entry (lh, lnet_libmd_t, md_lh));
419 }
420
421 static inline void
422 lnet_me2handle (lnet_handle_me_t *handle, lnet_me_t *me)
423 {
424         handle->cookie = me->me_lh.lh_cookie;
425 }
426
427 static inline lnet_me_t *
428 lnet_handle2me (lnet_handle_me_t *handle)
429 {
430         /* ALWAYS called with liblock held */
431         lnet_libhandle_t *lh = lnet_lookup_cookie(handle->cookie,
432                                                   LNET_COOKIE_TYPE_ME);
433         if (lh == NULL)
434                 return (NULL);
435
436         return (lh_entry (lh, lnet_me_t, me_lh));
437 }
438
439 static inline int
440 lnet_portal_is_lazy(lnet_portal_t *ptl)
441 {
442         return !!(ptl->ptl_options & LNET_PTL_LAZY);
443 }
444
445 static inline int
446 lnet_portal_is_unique(lnet_portal_t *ptl)
447 {
448         return !!(ptl->ptl_options & LNET_PTL_MATCH_UNIQUE); 
449 }
450
451 static inline int
452 lnet_portal_is_wildcard(lnet_portal_t *ptl)
453 {
454         return !!(ptl->ptl_options & LNET_PTL_MATCH_WILDCARD);
455 }
456
457 static inline void
458 lnet_portal_setopt(lnet_portal_t *ptl, int opt)
459 {
460         ptl->ptl_options |= opt;
461 }
462
463 static inline void
464 lnet_portal_unsetopt(lnet_portal_t *ptl, int opt)
465 {
466         ptl->ptl_options &= ~opt;
467 }
468
469 static inline int
470 lnet_match_is_unique(lnet_process_id_t match_id,
471                      __u64 match_bits, __u64 ignore_bits)
472 {
473         return ignore_bits == 0 &&
474                match_id.nid != LNET_NID_ANY &&
475                match_id.pid != LNET_PID_ANY;
476 }
477
478 static inline cfs_list_t *
479 lnet_portal_me_head(int index, lnet_process_id_t id, __u64 mbits)
480 {
481         lnet_portal_t *ptl = &the_lnet.ln_portals[index];
482
483         if (lnet_portal_is_wildcard(ptl)) {
484                 return &ptl->ptl_mlist;
485         } else if (lnet_portal_is_unique(ptl)) {
486                 LASSERT (ptl->ptl_mhash != NULL);
487                 return &ptl->ptl_mhash[lnet_match_to_hash(id, mbits)];
488         }
489         return NULL;
490 }
491
492 cfs_list_t *lnet_portal_mhash_alloc(void);
493 void lnet_portal_mhash_free(cfs_list_t *mhash);
494
495 static inline void
496 lnet_peer_addref_locked(lnet_peer_t *lp)
497 {
498         LASSERT (lp->lp_refcount > 0);
499         lp->lp_refcount++;
500 }
501
502 extern void lnet_destroy_peer_locked(lnet_peer_t *lp);
503
504 static inline void
505 lnet_peer_decref_locked(lnet_peer_t *lp)
506 {
507         LASSERT (lp->lp_refcount > 0);
508         lp->lp_refcount--;
509         if (lp->lp_refcount == 0)
510                 lnet_destroy_peer_locked(lp);
511 }
512
513 static inline int
514 lnet_isrouter(lnet_peer_t *lp)
515 {
516         return lp->lp_rtr_refcount != 0;
517 }
518
519 static inline void
520 lnet_ni_addref_locked(lnet_ni_t *ni)
521 {
522         LASSERT (ni->ni_refcount > 0);
523         ni->ni_refcount++;
524 }
525
526 static inline void
527 lnet_ni_addref(lnet_ni_t *ni)
528 {
529         LNET_LOCK();
530         lnet_ni_addref_locked(ni);
531         LNET_UNLOCK();
532 }
533
534 static inline void
535 lnet_ni_decref_locked(lnet_ni_t *ni)
536 {
537         LASSERT (ni->ni_refcount > 0);
538         ni->ni_refcount--;
539         if (ni->ni_refcount == 0)
540                 cfs_list_add_tail(&ni->ni_list, &the_lnet.ln_zombie_nis);
541 }
542
543 static inline void
544 lnet_ni_decref(lnet_ni_t *ni)
545 {
546         LNET_LOCK();
547         lnet_ni_decref_locked(ni);
548         LNET_UNLOCK();
549 }
550
551 static inline cfs_list_t *
552 lnet_nid2peerhash (lnet_nid_t nid)
553 {
554         unsigned int idx = LNET_NIDADDR(nid) % LNET_PEER_HASHSIZE;
555
556         return &the_lnet.ln_peer_hash[idx];
557 }
558
559 extern lnd_t the_lolnd;
560
561 #ifndef __KERNEL__
562 /* unconditional registration */
563 #define LNET_REGISTER_ULND(lnd)                 \
564 do {                                            \
565         extern lnd_t lnd;                       \
566                                                 \
567         lnet_register_lnd(&(lnd));              \
568 } while (0)
569
570 /* conditional registration */
571 #define LNET_REGISTER_ULND_IF_PRESENT(lnd)                              \
572 do {                                                                    \
573         extern lnd_t lnd __attribute__ ((weak, alias("the_lolnd")));    \
574                                                                         \
575         if (&(lnd) != &the_lolnd)                                       \
576                 lnet_register_lnd(&(lnd));                              \
577 } while (0)
578 #endif
579
580 #ifdef CRAY_XT3
581 inline static void
582 lnet_set_msg_uid(lnet_ni_t *ni, lnet_msg_t *msg, lnet_uid_t uid)
583 {
584         LASSERT (msg->msg_ev.uid == LNET_UID_ANY);
585         msg->msg_ev.uid = uid;
586 }
587 #endif
588
589 extern lnet_ni_t *lnet_nid2ni_locked (lnet_nid_t nid);
590 extern lnet_ni_t *lnet_net2ni_locked (__u32 net);
591 static inline lnet_ni_t *
592 lnet_net2ni (__u32 net)
593 {
594         lnet_ni_t *ni;
595
596         LNET_LOCK();
597         ni = lnet_net2ni_locked(net);
598         LNET_UNLOCK();
599
600         return ni;
601 }
602
603 int lnet_notify(lnet_ni_t *ni, lnet_nid_t peer, int alive, cfs_time_t when);
604 void lnet_notify_locked(lnet_peer_t *lp, int notifylnd, int alive, cfs_time_t when);
605 int lnet_add_route(__u32 net, unsigned int hops, lnet_nid_t gateway_nid);
606 int lnet_check_routes(void);
607 int lnet_del_route(__u32 net, lnet_nid_t gw_nid);
608 void lnet_destroy_routes(void);
609 int lnet_get_route(int idx, __u32 *net, __u32 *hops,
610                    lnet_nid_t *gateway, __u32 *alive);
611 void lnet_proc_init(void);
612 void lnet_proc_fini(void);
613 void lnet_init_rtrpools(void);
614 int  lnet_alloc_rtrpools(int im_a_router);
615 void lnet_free_rtrpools(void);
616 lnet_remotenet_t *lnet_find_net_locked (__u32 net);
617
618 int lnet_islocalnid(lnet_nid_t nid);
619 int lnet_islocalnet(__u32 net);
620
621 void lnet_build_unlink_event(lnet_libmd_t *md, lnet_event_t *ev);
622 void lnet_enq_event_locked(lnet_eq_t *eq, lnet_event_t *ev);
623 void lnet_prep_send(lnet_msg_t *msg, int type, lnet_process_id_t target,
624                     unsigned int offset, unsigned int len);
625 int lnet_send(lnet_nid_t nid, lnet_msg_t *msg);
626 void lnet_return_credits_locked (lnet_msg_t *msg);
627 void lnet_match_blocked_msg(lnet_libmd_t *md);
628 int lnet_parse (lnet_ni_t *ni, lnet_hdr_t *hdr,
629                 lnet_nid_t fromnid, void *private, int rdma_req);
630 void lnet_recv(lnet_ni_t *ni, void *private, lnet_msg_t *msg, int delayed,
631                unsigned int offset, unsigned int mlen, unsigned int rlen);
632 lnet_msg_t *lnet_create_reply_msg (lnet_ni_t *ni, lnet_msg_t *get_msg);
633 void lnet_set_reply_msg_len(lnet_ni_t *ni, lnet_msg_t *msg, unsigned int len);
634 void lnet_finalize(lnet_ni_t *ni, lnet_msg_t *msg, int rc);
635
636 char *lnet_msgtyp2str (int type);
637 void lnet_print_hdr (lnet_hdr_t * hdr);
638 int lnet_fail_nid(lnet_nid_t nid, unsigned int threshold);
639
640 unsigned int lnet_iov_nob (unsigned int niov, struct iovec *iov);
641 int lnet_extract_iov (int dst_niov, struct iovec *dst,
642                       int src_niov, struct iovec *src,
643                       unsigned int offset, unsigned int len);
644
645 unsigned int lnet_kiov_nob (unsigned int niov, lnet_kiov_t *iov);
646 int lnet_extract_kiov (int dst_niov, lnet_kiov_t *dst,
647                       int src_niov, lnet_kiov_t *src,
648                       unsigned int offset, unsigned int len);
649
650 void lnet_copy_iov2iov (unsigned int ndiov, struct iovec *diov,
651                         unsigned int doffset,
652                         unsigned int nsiov, struct iovec *siov,
653                         unsigned int soffset, unsigned int nob);
654 void lnet_copy_kiov2iov (unsigned int niov, struct iovec *iov,
655                          unsigned int iovoffset,
656                          unsigned int nkiov, lnet_kiov_t *kiov,
657                          unsigned int kiovoffset, unsigned int nob);
658 void lnet_copy_iov2kiov (unsigned int nkiov, lnet_kiov_t *kiov,
659                          unsigned int kiovoffset,
660                          unsigned int niov, struct iovec *iov,
661                          unsigned int iovoffset, unsigned int nob);
662 void lnet_copy_kiov2kiov (unsigned int ndkiov, lnet_kiov_t *dkiov,
663                           unsigned int doffset,
664                           unsigned int nskiov, lnet_kiov_t *skiov,
665                           unsigned int soffset, unsigned int nob);
666
667 static inline void
668 lnet_copy_iov2flat(int dlen, void *dest, unsigned int doffset,
669                    unsigned int nsiov, struct iovec *siov, unsigned int soffset,
670                    unsigned int nob)
671 {
672         struct iovec diov = {/*.iov_base = */ dest, /*.iov_len = */ dlen};
673
674         lnet_copy_iov2iov(1, &diov, doffset,
675                           nsiov, siov, soffset, nob);
676 }
677
678 static inline void
679 lnet_copy_kiov2flat(int dlen, void *dest, unsigned int doffset,
680                     unsigned int nsiov, lnet_kiov_t *skiov, unsigned int soffset,
681                     unsigned int nob)
682 {
683         struct iovec diov = {/* .iov_base = */ dest, /* .iov_len = */ dlen};
684
685         lnet_copy_kiov2iov(1, &diov, doffset,
686                            nsiov, skiov, soffset, nob);
687 }
688
689 static inline void
690 lnet_copy_flat2iov(unsigned int ndiov, struct iovec *diov, unsigned int doffset,
691                    int slen, void *src, unsigned int soffset, unsigned int nob)
692 {
693         struct iovec siov = {/*.iov_base = */ src, /*.iov_len = */slen};
694         lnet_copy_iov2iov(ndiov, diov, doffset,
695                           1, &siov, soffset, nob);
696 }
697
698 static inline void
699 lnet_copy_flat2kiov(unsigned int ndiov, lnet_kiov_t *dkiov, unsigned int doffset,
700                     int slen, void *src, unsigned int soffset, unsigned int nob)
701 {
702         struct iovec siov = {/* .iov_base = */ src, /* .iov_len = */ slen};
703         lnet_copy_iov2kiov(ndiov, dkiov, doffset,
704                            1, &siov, soffset, nob);
705 }
706
707 void lnet_me_unlink(lnet_me_t *me);
708
709 void lnet_md_unlink(lnet_libmd_t *md);
710 void lnet_md_deconstruct(lnet_libmd_t *lmd, lnet_md_t *umd);
711
712 void lnet_register_lnd(lnd_t *lnd);
713 void lnet_unregister_lnd(lnd_t *lnd);
714 int lnet_set_ip_niaddr (lnet_ni_t *ni);
715
716 #ifdef __KERNEL__
717 int lnet_connect(cfs_socket_t **sockp, lnet_nid_t peer_nid,
718                  __u32 local_ip, __u32 peer_ip, int peer_port);
719 void lnet_connect_console_error(int rc, lnet_nid_t peer_nid,
720                                 __u32 peer_ip, int port);
721 int lnet_count_acceptor_nis(void);
722 int lnet_acceptor_timeout(void);
723 int lnet_acceptor_port(void);
724 #else
725 void lnet_router_checker(void);
726 #endif
727
728 #ifdef HAVE_LIBPTHREAD
729 int lnet_count_acceptor_nis(void);
730 int lnet_acceptor_port(void);
731 #endif
732
733 int lnet_acceptor_start(void);
734 void lnet_acceptor_stop(void);
735
736 void lnet_get_tunables(void);
737 int lnet_peers_start_down(void);
738 int lnet_peer_buffer_credits(lnet_ni_t *ni);
739
740 int lnet_router_checker_start(void);
741 void lnet_router_checker_stop(void);
742 void lnet_swap_pinginfo(lnet_ping_info_t *info);
743 int lnet_router_down_ni(lnet_peer_t *rtr, __u32 net);
744
745 int lnet_ping_target_init(void);
746 void lnet_ping_target_fini(void);
747 int lnet_ping(lnet_process_id_t id, int timeout_ms,
748               lnet_process_id_t *ids, int n_ids);
749
750 int lnet_parse_ip2nets (char **networksp, char *ip2nets);
751 int lnet_parse_routes (char *route_str, int *im_a_router);
752 int lnet_parse_networks (cfs_list_t *nilist, char *networks);
753
754 int lnet_nid2peer_locked(lnet_peer_t **lpp, lnet_nid_t nid);
755 lnet_peer_t *lnet_find_peer_locked (lnet_nid_t nid);
756 void lnet_clear_peer_table(void);
757 void lnet_destroy_peer_table(void);
758 int lnet_create_peer_table(void);
759 void lnet_debug_peer(lnet_nid_t nid);
760
761 #ifndef __KERNEL__
762 static inline int
763 lnet_parse_int_tunable(int *value, char *name)
764 {
765         char    *env = getenv(name);
766         char    *end;
767
768         if (env == NULL)
769                 return 0;
770
771         *value = strtoull(env, &end, 0);
772         if (*end == 0)
773                 return 0;
774
775         CERROR("Can't parse tunable %s=%s\n", name, env);
776         return -EINVAL;
777 }
778 #endif
779
780 #endif