Whamcloud - gitweb
b=16098
[fs/lustre-release.git] / lnet / klnds / viblnd / viblnd.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 [sun.com URL with a
20  * copy of GPLv2].
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  2008 Sun Microsystems, Inc. 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/klnds/viblnd/viblnd.h
37  *
38  * Author: Eric Barton <eric@bartonsoftware.com>
39  * Author: Frank Zago <fzago@systemfabricworks.com>
40  */
41
42 #ifndef EXPORT_SYMTAB
43 # define EXPORT_SYMTAB
44 #endif
45 #ifndef AUTOCONF_INCLUDED
46 #include <linux/config.h>
47 #endif
48 #include <linux/module.h>
49 #include <linux/kernel.h>
50 #include <linux/mm.h>
51 #include <linux/string.h>
52 #include <linux/stat.h>
53 #include <linux/errno.h>
54 #include <linux/smp_lock.h>
55 #include <linux/unistd.h>
56 #include <linux/uio.h>
57
58 #include <asm/system.h>
59 #include <asm/uaccess.h>
60 #include <asm/io.h>
61
62 #include <linux/init.h>
63 #include <linux/fs.h>
64 #include <linux/file.h>
65 #include <linux/stat.h>
66 #include <linux/list.h>
67 #include <linux/kmod.h>
68 #include <linux/sysctl.h>
69 #include <linux/random.h>
70
71 #include <net/sock.h>
72 #include <linux/in.h>
73
74 #define DEBUG_SUBSYSTEM S_LND
75
76 #include <libcfs/libcfs.h>
77 #include <lnet/lnet.h>
78 #include <lnet/lib-lnet.h>
79
80 /* CPU_{L,B}E #defines needed by Voltaire headers */
81 #include <asm/byteorder.h>
82 #ifdef __BIG_ENDIAN__
83 #define CPU_BE 1
84 #define CPU_LE 0
85 #endif
86 #ifdef __LITTLE_ENDIAN__
87 #define CPU_BE 0
88 #define CPU_LE 1
89 #endif
90
91 #include <vverbs.h>
92 #include <ib-cm.h>
93 #include <ibat.h>
94
95 /* GCC 3.2.2, miscompiles this driver.  
96  * See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=9853. */
97 #define GCC_VERSION ((__GNUC__*100 + __GNUC_MINOR__)*100 + __GNUC_PATCHLEVEL__)
98 #if (GCC_VERSION >= 30000) && (GCC_VERSION < 30203)
99 # error Invalid GCC version. Must use GCC < 3.0.0 || GCC >= 3.2.3
100 #endif
101
102 #ifdef CONFIG_SMP
103 # define IBNAL_N_SCHED      num_online_cpus()   /* # schedulers */
104 #else
105 # define IBNAL_N_SCHED      1                   /* # schedulers */
106 #endif
107
108 #define IBNAL_USE_FMR  1
109
110 /* tunables fixed at compile time */
111 #define IBNAL_PEER_HASH_SIZE         101        /* # peer lists */
112 #define IBNAL_RESCHED                100        /* # scheduler loops before reschedule */
113 #define IBNAL_MSG_QUEUE_SIZE         8          /* # messages/RDMAs in-flight */
114 #define IBNAL_CREDIT_HIGHWATER       7          /* when eagerly to return credits */
115 #define IBNAL_MSG_SIZE              (4<<10)     /* max size of queued messages (inc hdr) */
116
117 /* constants derived from sdp-connection.c */
118 #define IBNAL_QKEY               0
119 #define IBNAL_PKEY               0xffff
120 #define IBNAL_PKEY_IDX           0
121 #define IBNAL_SGID_IDX           0
122 #define IBNAL_SERVICE_LEVEL      0
123 #define IBNAL_STATIC_RATE        0
124 #define IBNAL_EE_FLOW_CNT        1
125 #define IBNAL_LOCAL_SUB          1
126 #define IBNAL_TRAFFIC_CLASS      0
127 #define IBNAL_SOURCE_PATH_BIT    0
128 #define IBNAL_OUS_DST_RD         1
129 #define IBNAL_IB_MTU             vv_mtu_1024
130
131 /* constants derived from sdp-hca-params.h */
132 #define PATH_RATE_2_5GB           2
133 #define MLX_IPD_1x                1
134 #define MLX_IPD_4x                0
135 #define IBNAL_R_2_STATIC_RATE(r)  ((r) == PATH_RATE_2_5GB ? MLX_IPD_1x : MLX_IPD_4x)
136
137 /* other low-level IB constants */
138 #define IBNAL_PKT_LIFETIME        5
139 #define IBNAL_ARB_INITIATOR_DEPTH 0
140 #define IBNAL_ARB_RESP_RES        0
141 #define IBNAL_FAILOVER_ACCEPTED   0
142
143 /************************/
144 /* derived constants... */
145
146 /* TX messages (shared by all connections) */
147 #define IBNAL_TX_MSGS()       (*kibnal_tunables.kib_ntx)
148 #define IBNAL_TX_MSG_BYTES()  (IBNAL_TX_MSGS() * IBNAL_MSG_SIZE)
149 #define IBNAL_TX_MSG_PAGES()  ((IBNAL_TX_MSG_BYTES() + PAGE_SIZE - 1)/PAGE_SIZE)
150
151 #if IBNAL_USE_FMR
152 # define IBNAL_MAX_RDMA_FRAGS 1
153 # define IBNAL_CONCURRENT_SENDS IBNAL_RX_MSGS
154 #else
155 # define IBNAL_MAX_RDMA_FRAGS LNET_MAX_IOV
156 # define IBNAL_CONCURRENT_SENDS IBNAL_MSG_QUEUE_SIZE
157 #endif
158
159 /* RX messages (per connection) */
160 #define IBNAL_RX_MSGS         (IBNAL_MSG_QUEUE_SIZE*2)
161 #define IBNAL_RX_MSG_BYTES    (IBNAL_RX_MSGS * IBNAL_MSG_SIZE)
162 #define IBNAL_RX_MSG_PAGES    ((IBNAL_RX_MSG_BYTES + PAGE_SIZE - 1)/PAGE_SIZE)
163
164 #define IBNAL_CQ_ENTRIES()    (IBNAL_TX_MSGS() * (1 + IBNAL_MAX_RDMA_FRAGS) +           \
165                                IBNAL_RX_MSGS * *kibnal_tunables.kib_concurrent_peers)
166
167 typedef struct
168 {
169         unsigned int     *kib_service_number;   /* IB service number */
170         int              *kib_min_reconnect_interval; /* first failed connection retry... */
171         int              *kib_max_reconnect_interval; /* ...exponentially increasing to this */
172         int              *kib_concurrent_peers; /* max # nodes all talking to me */
173         int              *kib_cksum;            /* checksum kib_msg_t? */
174         int              *kib_timeout;          /* comms timeout (seconds) */
175         int              *kib_ntx;              /* # tx descs */
176         int              *kib_credits;          /* # concurrent sends */
177         int              *kib_peercredits;      /* # concurrent sends to 1 peer */
178         int              *kib_arp_retries;      /* # times to retry ARP */
179         char            **kib_hca_basename;     /* HCA base name */
180         char            **kib_ipif_basename;    /* IPoIB interface base name */
181         int              *kib_local_ack_timeout; /* IB RC QP ack timeout... */
182         int              *kib_retry_cnt;        /* ...and retry */
183         int              *kib_rnr_cnt;          /* RNR retries... */
184         int              *kib_rnr_nak_timer;    /* ...and interval */
185         int              *kib_keepalive;        /* keepalive interval */
186         int              *kib_concurrent_sends; /* send work queue sizing */
187 #if IBNAL_USE_FMR
188         int              *kib_fmr_remaps;       /* # FMR maps before unmap required */
189 #endif
190 #if defined(CONFIG_SYSCTL) && !CFS_SYSFS_MODULE_PARM
191         cfs_sysctl_table_header_t *kib_sysctl;  /* sysctl interface */
192 #endif
193 } kib_tunables_t;
194
195 typedef struct
196 {
197         int               ibp_npages;           /* # pages */
198         struct page      *ibp_pages[0];
199 } kib_pages_t;
200
201 #if IBNAL_USE_FMR
202 typedef struct
203 {
204         vv_fmr_h_t        md_fmrhandle;         /* FMR handle */
205         int               md_fmrcount;          /* # mappings left */
206         int               md_active;            /* mapping in use? */
207         __u32             md_lkey;              /* local key */
208         __u32             md_rkey;              /* remote key */
209         __u64             md_addr;              /* IO VM address */
210 } kib_md_t;
211 #endif
212
213 typedef struct
214 {
215         int               kib_init;             /* initialisation state */
216         __u64             kib_incarnation;      /* which one am I */
217         int               kib_shutdown;         /* shut down? */
218         atomic_t          kib_nthreads;         /* # live threads */
219         lnet_ni_t        *kib_ni;               /* _the_ nal instance */
220
221         vv_gid_t          kib_port_gid;         /* device/port GID */
222         vv_p_key_t        kib_port_pkey;        /* device/port pkey */
223         
224         cm_cep_handle_t   kib_listen_handle;    /* IB listen handle */
225
226         rwlock_t          kib_global_lock;      /* stabilize peer/conn ops */
227         int               kib_ready;            /* CQ callback fired */
228         int               kib_checking_cq;      /* a scheduler is checking the CQ */
229         
230         struct list_head *kib_peers;            /* hash table of all my known peers */
231         int               kib_peer_hash_size;   /* size of kib_peers */
232         atomic_t          kib_npeers;           /* # peers extant */
233         atomic_t          kib_nconns;           /* # connections extant */
234
235         void             *kib_connd;            /* the connd task (serialisation assertions) */
236         struct list_head  kib_connd_peers;      /* peers wanting to get connected */
237         struct list_head  kib_connd_pcreqs;     /* passive connection requests */
238         struct list_head  kib_connd_conns;      /* connections to setup/teardown */
239         struct list_head  kib_connd_zombies;    /* connections with zero refcount */
240         wait_queue_head_t kib_connd_waitq;      /* connection daemon sleeps here */
241         spinlock_t        kib_connd_lock;       /* serialise */
242
243         wait_queue_head_t kib_sched_waitq;      /* schedulers sleep here */
244         spinlock_t        kib_sched_lock;       /* serialise */
245
246         struct kib_tx    *kib_tx_descs;         /* all the tx descriptors */
247         kib_pages_t      *kib_tx_pages;         /* premapped tx msg pages */
248
249         struct list_head  kib_idle_txs;         /* idle tx descriptors */
250         __u64             kib_next_tx_cookie;   /* RDMA completion cookie */
251         spinlock_t        kib_tx_lock;          /* serialise */
252
253         vv_hca_h_t        kib_hca;              /* The HCA */
254         vv_hca_attrib_t   kib_hca_attrs;        /* its properties */
255         int               kib_port;             /* port on the device */
256         vv_port_attrib_t  kib_port_attr;        /* its properties */
257
258         vv_pd_h_t         kib_pd;               /* protection domain */
259         vv_cq_h_t         kib_cq;               /* completion queue */
260
261 } kib_data_t;
262
263 #define IBNAL_INIT_NOTHING         0
264 #define IBNAL_INIT_DATA            1
265 #define IBNAL_INIT_LIB             2
266 #define IBNAL_INIT_HCA             3
267 #define IBNAL_INIT_ASYNC           4
268 #define IBNAL_INIT_PD              5
269 #define IBNAL_INIT_TXD             6
270 #define IBNAL_INIT_CQ              7
271 #define IBNAL_INIT_ALL             8
272
273 #include "viblnd_wire.h"
274
275 /***********************************************************************/
276
277 typedef struct kib_rx                           /* receive message */
278 {
279         struct list_head          rx_list;      /* queue for attention */
280         struct kib_conn          *rx_conn;      /* owning conn */
281         int                       rx_nob;       /* # bytes received (-1 while posted) */
282         vv_l_key_t                rx_lkey;      /* local key */
283         kib_msg_t                *rx_msg;       /* pre-mapped buffer (host vaddr) */
284         vv_wr_t                   rx_wrq;       /* receive work item */
285         vv_scatgat_t              rx_gl;        /* and its memory */
286 } kib_rx_t;
287
288 typedef struct kib_tx                           /* transmit message */
289 {
290         struct list_head          tx_list;      /* queue on idle_txs ibc_tx_queue etc. */
291         struct kib_conn          *tx_conn;      /* owning conn */
292         int                       tx_sending;   /* # tx callbacks outstanding */
293         int                       tx_queued;    /* queued for sending */
294         int                       tx_waiting;   /* waiting for peer */
295         int                       tx_status;    /* completion status */
296         unsigned long             tx_deadline;  /* completion deadline */
297         __u64                     tx_cookie;    /* completion cookie */
298         lnet_msg_t               *tx_lntmsg[2]; /* lnet msgs to finalize on completion */
299         vv_l_key_t                tx_lkey;      /* local key for message buffer */
300         kib_msg_t                *tx_msg;       /* message buffer (host vaddr) */
301         int                       tx_nwrq;      /* # send work items */
302 #if IBNAL_USE_FMR
303         vv_wr_t                   tx_wrq[2];    /* send work items... */
304         vv_scatgat_t              tx_gl[2];     /* ...and their memory */
305         kib_rdma_desc_t           tx_rd[1];     /* rdma descriptor */
306         kib_md_t                  tx_md;        /* FMR mapping descriptor */
307         __u64                    *tx_pages;     /* page phys addrs */
308 #else
309         vv_wr_t                  *tx_wrq;       /* send work items... */
310         vv_scatgat_t             *tx_gl;        /* ...and their memory */
311         kib_rdma_desc_t          *tx_rd;        /* rdma descriptor (src buffers) */
312 #endif
313 } kib_tx_t;
314
315 /* Passive connection request (listener callback) queued for handling by connd */
316 typedef struct kib_pcreq
317 {
318         struct list_head  pcr_list;             /* queue for handling by connd */
319         cm_cep_handle_t   pcr_cep;              /* listening handle */
320         cm_request_data_t pcr_cmreq;            /* request data */
321 } kib_pcreq_t;
322
323 typedef struct kib_connvars
324 {
325         /* connection-in-progress variables */
326         __u32               cv_port;
327         __u32               cv_pkey_index;
328         __u32               cv_rnr_count;
329         __u32               cv_sgid_index;
330         __u32               cv_remote_qpn;
331         __u32               cv_local_qpn;
332         __u32               cv_rxpsn;
333         __u32               cv_txpsn;
334         ib_path_record_v2_t cv_path;
335         ibat_arp_data_t     cv_arp;
336         ibat_stat_t         cv_arprc;
337         cm_conn_data_t      cv_conndata;
338 } kib_connvars_t;
339
340 typedef struct kib_conn
341 {
342         struct kib_peer    *ibc_peer;           /* owning peer */
343         struct list_head    ibc_list;           /* stash on peer's conn list */
344         __u64               ibc_incarnation;    /* which instance of the peer */
345         __u64               ibc_txseq;          /* tx sequence number */
346         __u64               ibc_rxseq;          /* rx sequence number */
347         __u32               ibc_version;        /* peer protocol version */
348         atomic_t            ibc_refcount;       /* # users */
349         int                 ibc_state;          /* what's happening */
350         int                 ibc_nsends_posted;  /* # uncompleted sends */
351         int                 ibc_credits;        /* # credits I have */
352         int                 ibc_outstanding_credits; /* # credits to return */
353         int                 ibc_reserved_credits; /* # credits for ACK/DONE msgs */
354         int                 ibc_disconnect;     /* some disconnect callback fired */
355         int                 ibc_comms_error;    /* set on comms error */
356         unsigned long       ibc_last_send;      /* time of last send */
357         struct list_head    ibc_early_rxs;      /* rxs completed before ESTABLISHED */
358         struct list_head    ibc_tx_queue_nocred; /* sends that don't need a cred */
359         struct list_head    ibc_tx_queue_rsrvd; /* sends that need a reserved cred */
360         struct list_head    ibc_tx_queue;       /* send queue */
361         struct list_head    ibc_active_txs;     /* active tx awaiting completion */
362         spinlock_t          ibc_lock;           /* serialise */
363         kib_rx_t           *ibc_rxs;            /* the rx descs */
364         kib_pages_t        *ibc_rx_pages;       /* premapped rx msg pages */
365         vv_qp_h_t           ibc_qp;             /* queue pair */
366         cm_cep_handle_t     ibc_cep;            /* connection endpoint */
367         kib_connvars_t     *ibc_connvars;       /* in-progress connection state */
368 } kib_conn_t;
369
370 #define IBNAL_CONN_INIT_NOTHING       0         /* incomplete init */
371 #define IBNAL_CONN_INIT_QP            1         /* QP allocated */
372 #define IBNAL_CONN_INIT               2         /* completed init */
373 #define IBNAL_CONN_ACTIVE_ARP         3         /* active arping */
374 #define IBNAL_CONN_ACTIVE_CONNECT     4         /* active sending req */
375 #define IBNAL_CONN_ACTIVE_CHECK_REPLY 5         /* active checking reply */
376 #define IBNAL_CONN_ACTIVE_RTU         6         /* active sending rtu */
377 #define IBNAL_CONN_PASSIVE_WAIT       7         /* passive waiting for rtu */
378 #define IBNAL_CONN_ESTABLISHED        8         /* connection established */
379 #define IBNAL_CONN_DISCONNECT1        9         /* disconnect phase 1 */
380 #define IBNAL_CONN_DISCONNECT2        10        /* disconnect phase 2 */
381 #define IBNAL_CONN_DISCONNECTED       11        /* disconnect complete */
382
383 typedef struct kib_peer
384 {
385         struct list_head    ibp_list;           /* stash on global peer list */
386         struct list_head    ibp_connd_list;     /* schedule on kib_connd_peers */
387         lnet_nid_t          ibp_nid;            /* who's on the other end(s) */
388         __u32               ibp_ip;             /* IP to query for peer conn params */
389         int                 ibp_port;           /* port to qery for peer conn params */
390         __u64               ibp_incarnation;    /* peer's incarnation */
391         atomic_t            ibp_refcount;       /* # users */
392         int                 ibp_persistence;    /* "known" peer refs */
393         struct list_head    ibp_conns;          /* all active connections */
394         struct list_head    ibp_tx_queue;       /* msgs waiting for a conn */
395         int                 ibp_connecting;     /* current active connection attempts */
396         int                 ibp_accepting;      /* current passive connection attempts */
397         int                 ibp_arp_count;      /* # arp attempts */
398         unsigned long       ibp_reconnect_time; /* when reconnect may be attempted */
399         unsigned long       ibp_reconnect_interval; /* exponential backoff */
400         int                 ibp_error;          /* errno on closing this peer */
401         cfs_time_t          ibp_last_alive;     /* when (in jiffies) I was last alive */
402 } kib_peer_t;
403
404
405 extern kib_data_t      kibnal_data;
406 extern kib_tunables_t  kibnal_tunables;
407
408 int kibnal_startup (lnet_ni_t *ni);
409 void kibnal_shutdown (lnet_ni_t *ni);
410 int kibnal_ctl(lnet_ni_t *ni, unsigned int cmd, void *arg);
411 int kibnal_send (lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg);
412 extern int kibnal_eager_recv (lnet_ni_t *ni, void *private,
413                               lnet_msg_t *lntmsg, void **new_private);
414 int kibnal_recv(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg, 
415                 int delayed, unsigned int niov, 
416                 struct iovec *iov, lnet_kiov_t *kiov,
417                 unsigned int offset, unsigned int mlen, unsigned int rlen);
418 extern void kibnal_init_msg(kib_msg_t *msg, int type, int body_nob);
419 extern void kibnal_pack_msg(kib_msg_t *msg, __u32 version, int credits,
420                             lnet_nid_t dstnid, __u64 dststamp, __u64 seq);
421 extern int  kibnal_unpack_msg(kib_msg_t *msg, __u32 expected_version, int nob);
422 extern int  kibnal_create_peer(kib_peer_t **peerp, lnet_nid_t nid);
423 extern void kibnal_destroy_peer(kib_peer_t *peer);
424 extern int  kibnal_add_persistent_peer (lnet_nid_t nid, __u32 ip);
425 extern int  kibnal_del_peer(lnet_nid_t nid);
426 extern kib_peer_t *kibnal_find_peer_locked(lnet_nid_t nid);
427 extern void kibnal_unlink_peer_locked(kib_peer_t *peer);
428 extern void kibnal_peer_alive(kib_peer_t *peer);
429 extern int  kibnal_close_stale_conns_locked(kib_peer_t *peer,
430                                             __u64 incarnation);
431 extern kib_conn_t *kibnal_create_conn(cm_cep_handle_t cep);
432 extern void kibnal_listen_callback(cm_cep_handle_t cep, cm_conn_data_t *info, void *arg);
433
434 extern int  kibnal_alloc_pages(kib_pages_t **pp, int npages, int access);
435 extern void kibnal_free_pages(kib_pages_t *p);
436
437 extern void kibnal_check_sends(kib_conn_t *conn);
438 extern void kibnal_close_conn_locked(kib_conn_t *conn, int error);
439 extern void kibnal_destroy_conn(kib_conn_t *conn);
440 extern int  kibnal_thread_start(int (*fn)(void *arg), void *arg);
441 extern int  kibnal_scheduler(void *arg);
442 extern int  kibnal_connd(void *arg);
443 extern void kibnal_init_tx_msg(kib_tx_t *tx, int type, int body_nob);
444 extern void kibnal_close_conn(kib_conn_t *conn, int why);
445 extern int  kibnal_set_qp_state(kib_conn_t *conn, vv_qp_state_t new_state);
446 extern void kibnal_async_callback(vv_event_record_t ev);
447 extern void kibnal_cq_callback(unsigned long context);
448 extern void kibnal_passive_connreq(kib_pcreq_t *pcr, int reject);
449 extern void kibnal_txlist_done (struct list_head *txlist, int status);
450 extern void kibnal_queue_tx(kib_tx_t *tx, kib_conn_t *conn);
451 extern int  kibnal_init_rdma(kib_tx_t *tx, int type, int nob,
452                              kib_rdma_desc_t *dstrd, __u64 dstcookie);
453 extern int  kibnal_tunables_init(void);
454 extern void kibnal_tunables_fini(void);
455
456 #define kibnal_conn_addref(conn)                                \
457 do {                                                            \
458         CDEBUG(D_NET, "conn[%p] (%d)++\n",                      \
459                (conn), atomic_read(&(conn)->ibc_refcount));     \
460         LASSERT(atomic_read(&(conn)->ibc_refcount) > 0);        \
461         atomic_inc(&(conn)->ibc_refcount);                      \
462 } while (0)
463
464 #define kibnal_conn_decref(conn)                                              \
465 do {                                                                          \
466         unsigned long   flags;                                                \
467                                                                               \
468         CDEBUG(D_NET, "conn[%p] (%d)--\n",                                    \
469                (conn), atomic_read(&(conn)->ibc_refcount));                   \
470         LASSERT(atomic_read(&(conn)->ibc_refcount) > 0);                      \
471         if (atomic_dec_and_test(&(conn)->ibc_refcount)) {                     \
472                 spin_lock_irqsave(&kibnal_data.kib_connd_lock, flags);        \
473                 list_add_tail(&(conn)->ibc_list,                              \
474                               &kibnal_data.kib_connd_zombies);                \
475                 wake_up(&kibnal_data.kib_connd_waitq);                        \
476                 spin_unlock_irqrestore(&kibnal_data.kib_connd_lock, flags);   \
477         }                                                                     \
478 } while (0)
479
480 #define kibnal_peer_addref(peer)                                \
481 do {                                                            \
482         CDEBUG(D_NET, "peer[%p] -> %s (%d)++\n",                \
483                (peer), libcfs_nid2str((peer)->ibp_nid),         \
484                atomic_read (&(peer)->ibp_refcount));            \
485         LASSERT(atomic_read(&(peer)->ibp_refcount) > 0);        \
486         atomic_inc(&(peer)->ibp_refcount);                      \
487 } while (0)
488
489 #define kibnal_peer_decref(peer)                                \
490 do {                                                            \
491         CDEBUG(D_NET, "peer[%p] -> %s (%d)--\n",                \
492                (peer), libcfs_nid2str((peer)->ibp_nid),         \
493                atomic_read (&(peer)->ibp_refcount));            \
494         LASSERT(atomic_read(&(peer)->ibp_refcount) > 0);        \
495         if (atomic_dec_and_test(&(peer)->ibp_refcount))         \
496                 kibnal_destroy_peer(peer);                      \
497 } while (0)
498
499 static inline struct list_head *
500 kibnal_nid2peerlist (lnet_nid_t nid)
501 {
502         unsigned int hash = ((unsigned int)nid) % kibnal_data.kib_peer_hash_size;
503
504         return (&kibnal_data.kib_peers [hash]);
505 }
506
507 static inline int
508 kibnal_peer_active (kib_peer_t *peer)
509 {
510         /* Am I in the peer hash table? */
511         return (!list_empty(&peer->ibp_list));
512 }
513
514 static inline void
515 kibnal_queue_tx_locked (kib_tx_t *tx, kib_conn_t *conn)
516 {
517         struct list_head  *q;
518         
519         LASSERT (tx->tx_nwrq > 0);              /* work items set up */
520         LASSERT (!tx->tx_queued);               /* not queued for sending already */
521
522         tx->tx_queued = 1;
523         tx->tx_deadline = jiffies + (*kibnal_tunables.kib_timeout * HZ);
524
525         if (tx->tx_conn == NULL) {
526                 kibnal_conn_addref(conn);
527                 tx->tx_conn = conn;
528                 LASSERT (tx->tx_msg->ibm_type != IBNAL_MSG_PUT_DONE);
529         } else {
530                 LASSERT (tx->tx_conn == conn);
531                 LASSERT (tx->tx_msg->ibm_type == IBNAL_MSG_PUT_DONE);
532         }
533
534         if (conn->ibc_version == IBNAL_MSG_VERSION_RDMAREPLYNOTRSRVD) {
535                 /* All messages have simple credit control */
536                 q = &conn->ibc_tx_queue;
537         } else {
538                 LASSERT (conn->ibc_version == IBNAL_MSG_VERSION);
539                 
540                 switch (tx->tx_msg->ibm_type) {
541                 case IBNAL_MSG_PUT_REQ:
542                 case IBNAL_MSG_GET_REQ:
543                         /* RDMA request: reserve a buffer for the RDMA reply
544                          * before sending */
545                         q = &conn->ibc_tx_queue_rsrvd;
546                         break;
547
548                 case IBNAL_MSG_PUT_NAK:
549                 case IBNAL_MSG_PUT_ACK:
550                 case IBNAL_MSG_PUT_DONE:
551                 case IBNAL_MSG_GET_DONE:
552                         /* RDMA reply/completion: no credits; peer has reserved
553                          * a reply buffer */
554                         q = &conn->ibc_tx_queue_nocred;
555                         break;
556                 
557                 case IBNAL_MSG_NOOP:
558                 case IBNAL_MSG_IMMEDIATE:
559                         /* Otherwise: consume a credit before sending */
560                         q = &conn->ibc_tx_queue;
561                         break;
562                 
563                 default:
564                         LBUG();
565                         q = NULL;
566                 }
567         }
568         
569         list_add_tail(&tx->tx_list, q);
570 }
571
572 static inline int
573 kibnal_send_keepalive(kib_conn_t *conn) 
574 {
575         return (*kibnal_tunables.kib_keepalive > 0) &&
576                 time_after(jiffies, conn->ibc_last_send +
577                            *kibnal_tunables.kib_keepalive*HZ);
578 }
579
580 #ifndef IBNAL_VOIDSTAR_SGADDR
581 # define IBNAL_VOIDSTAR_SGADDR 0
582 #endif
583
584 #if IBNAL_VOIDSTAR_SGADDR
585 # if defined(CONFIG_HIGHMEM)
586 #  if defined(CONFIG_X86) && defined(CONFIG_HIGHMEM4G)
587    /* truncation to void* doesn't matter if 0 <= physmem < 4G
588     * so allow x86 with 32 bit phys addrs */
589 #  elif defined(CONFIG_IA64)
590    /* OK anyway on 64-bit arch */
591 #  else
592 #   error "Can't support HIGHMEM when vv_scatgat_t::v_address is void *"
593 #  endif
594 # endif
595 # define KIBNAL_ADDR2SG(a)       ((void *)((unsigned long)(a)))
596 # define KIBNAL_SG2ADDR(a)       ((__u64)((unsigned long)(a)))
597 static inline __u64 kibnal_addr2net (__u64 addr)
598 {
599         void        *netaddr;
600         vv_return_t  vvrc = vv_va2advertise_addr(kibnal_data.kib_hca, 
601                                                  KIBNAL_ADDR2SG(addr),
602                                                  &netaddr);
603         LASSERT (vvrc == vv_return_ok);
604         return KIBNAL_SG2ADDR(netaddr);
605 }
606 #else
607 # define KIBNAL_ADDR2SG(a)       a
608 # define KIBNAL_SG2ADDR(a)       a
609 static inline __u64 kibnal_addr2net (__u64 addr)
610 {
611         __u64        netaddr;
612         vv_return_t  vvrc = vv_va2advertise_addr(kibnal_data.kib_hca, 
613                                                  addr,
614                                                  &netaddr);
615         LASSERT (vvrc == vv_return_ok);
616         return netaddr;
617 }
618 #endif
619
620 /* CAVEAT EMPTOR: We rely on tx/rx descriptor alignment to allow us to use the
621  * lowest 2 bits of the work request id to stash the work item type (the op
622  * field is not valid when the wc completes in error). */
623
624 #define IBNAL_WID_TX    0
625 #define IBNAL_WID_RX    1
626 #define IBNAL_WID_RDMA  2
627 #define IBNAL_WID_MASK  3UL
628
629 static inline vv_wr_id_t
630 kibnal_ptr2wreqid (void *ptr, int type)
631 {
632         unsigned long lptr = (unsigned long)ptr;
633
634         LASSERT ((lptr & IBNAL_WID_MASK) == 0);
635         LASSERT ((type & ~IBNAL_WID_MASK) == 0);
636         return (vv_wr_id_t)(lptr | type);
637 }
638
639 static inline void *
640 kibnal_wreqid2ptr (vv_wr_id_t wreqid)
641 {
642         return (void *)(((unsigned long)wreqid) & ~IBNAL_WID_MASK);
643 }
644
645 static inline int
646 kibnal_wreqid2type (vv_wr_id_t wreqid)
647 {
648         return (wreqid & IBNAL_WID_MASK);
649 }
650
651 static inline void
652 kibnal_set_conn_state (kib_conn_t *conn, int state)
653 {
654         conn->ibc_state = state;
655         mb();
656 }
657
658 #if IBNAL_USE_FMR
659
660 static inline int
661 kibnal_rd_size (kib_rdma_desc_t *rd) 
662 {
663         return rd->rd_nob;
664 }
665
666 #else
667 static inline __u64
668 kibnal_rf_addr (kib_rdma_frag_t *rf)
669 {
670         return  (((__u64)rf->rf_addr_hi)<<32) | ((__u64)rf->rf_addr_lo);
671 }
672
673 static inline void
674 kibnal_rf_set (kib_rdma_frag_t *rf, __u64 addr, int nob)
675 {
676         rf->rf_addr_lo = addr & 0xffffffff;
677         rf->rf_addr_hi = (addr >> 32) & 0xffffffff;
678         rf->rf_nob = nob;
679 }
680
681 static inline int
682 kibnal_rd_size (kib_rdma_desc_t *rd)
683 {
684         int   i;
685         int   size;
686         
687         for (i = size = 0; i < rd->rd_nfrag; i++)
688                 size += rd->rd_frags[i].rf_nob;
689         
690         return size;
691 }
692 #endif