Whamcloud - gitweb
Fix compiler warnings.
[fs/lustre-release.git] / lnet / ulnds / socklnd / usocklnd.h
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * Copyright (C) 2001, 2002 Cluster File Systems, Inc.
5  *   Author: Maxim Patlasov <maxim@clusterfs.com>
6  *
7  *   This file is part of the Lustre file system, http://www.lustre.org
8  *   Lustre is a trademark of Cluster File Systems, Inc.
9  *
10  */
11 #ifndef _GNU_SOURCE
12 #define _GNU_SOURCE
13 #endif
14 #include <pthread.h>
15 #include <poll.h>
16 #include <lnet/lib-lnet.h>
17 #include <lnet/socklnd.h>
18
19 typedef struct {
20         struct list_head tx_list;    /* neccessary to form tx list */
21         lnet_msg_t      *tx_lnetmsg; /* lnet message for lnet_finalize() */
22         ksock_msg_t      tx_msg;     /* buffer for wire header of ksock msg */
23         int              tx_resid;   /* # of residual bytes */
24         int              tx_nob;     /* # of packet bytes */
25         int              tx_size;    /* size of this descriptor */
26         struct iovec    *tx_iov;     /* points to tx_iova[i] */
27         int              tx_niov;    /* # of packet iovec frags */
28         struct iovec     tx_iova[1]; /* iov for header */
29 } usock_tx_t;
30
31 struct usock_peer_s;
32
33 typedef struct {
34         int                  uc_fd;          /* socket */
35         int                  uc_type;        /* conn type */
36         int                  uc_activeflag;  /* active side of connection? */
37         int                  uc_flip;        /* is peer other endian? */
38         int                  uc_state;       /* connection state */
39         struct usock_peer_s *uc_peer;        /* owning peer */
40         lnet_process_id_t    uc_peerid;      /* id of remote peer */
41         int                  uc_pt_idx;      /* index in ud_pollthreads[] of
42                                               * owning poll thread */
43         lnet_ni_t            *uc_ni;         /* parent NI while accepting */
44         struct usock_preq_s  *uc_preq;       /* preallocated request */
45         __u32                 uc_peer_ip;    /* IP address of the peer */
46         __u16                 uc_peer_port;  /* port of the peer */
47         struct list_head      uc_stale_list; /* orphaned connections */
48         
49         /* Receive state */
50         int                uc_rx_state;      /* message or hello state */
51         ksock_hello_msg_t *uc_rx_hello;      /* hello buffer */
52         struct iovec      *uc_rx_iov;        /* points to uc_rx_iova[i] */
53         struct iovec       uc_rx_iova[LNET_MAX_IOV]; /* message frags */
54         int                uc_rx_niov;       /* # frags */
55         int                uc_rx_nob_left;   /* # bytes to next hdr/body */
56         int                uc_rx_nob_wanted; /* # of bytes actually wanted */
57         void              *uc_rx_lnetmsg;    /* LNET message being received */
58         cfs_time_t         uc_rx_deadline;   /* when to time out */
59         int                uc_rx_flag;       /* deadline valid? */
60         ksock_msg_t        uc_rx_msg;        /* message buffer */
61
62         /* Send state */
63         struct list_head   uc_tx_list;       /* pending txs */
64         struct list_head   uc_zcack_list;    /* pending zc_acks */
65         cfs_time_t         uc_tx_deadline;   /* when to time out */
66         int                uc_tx_flag;       /* deadline valid? */
67         int                uc_sending;       /* send op is in progress */
68         usock_tx_t        *uc_tx_hello;      /* fake tx with hello */
69         
70         cfs_atomic_t       uc_refcount;      /* # of users */
71         pthread_mutex_t    uc_lock;          /* serialize */
72         int                uc_errored;       /* a flag for lnet_notify() */ 
73 } usock_conn_t;
74
75 /* Allowable conn states are: */
76 #define UC_CONNECTING 1
77 #define UC_SENDING_HELLO 2
78 #define UC_RECEIVING_HELLO 3
79 #define UC_READY 4
80 #define UC_DEAD 5
81
82 /* Allowable RX states are: */
83 #define UC_RX_HELLO_MAGIC 1
84 #define UC_RX_HELLO_VERSION 2
85 #define UC_RX_HELLO_BODY 3
86 #define UC_RX_HELLO_IPS 4
87 #define UC_RX_KSM_HEADER 5
88 #define UC_RX_LNET_HEADER 6
89 #define UC_RX_PARSE 7
90 #define UC_RX_PARSE_WAIT 8
91 #define UC_RX_LNET_PAYLOAD 9
92 #define UC_RX_SKIPPING 10
93
94 #define N_CONN_TYPES 3 /* CONTROL, BULK_IN and BULK_OUT */
95
96 typedef struct usock_peer_s {
97         struct list_head  up_list;         /* neccessary to form peer list */
98         lnet_process_id_t up_peerid;       /* id of remote peer */
99         usock_conn_t     *up_conns[N_CONN_TYPES]; /* conns that connect us
100                                                    * us with the peer */
101         lnet_ni_t        *up_ni;           /* pointer to parent NI */
102         __u64             up_incarnation;  /* peer's incarnation */
103         int               up_incrn_is_set; /* 0 if peer's incarnation
104                                             * hasn't been set so far */
105         cfs_atomic_t      up_refcount;     /* # of users */
106         pthread_mutex_t   up_lock;         /* serialize */
107         int               up_errored;      /* a flag for lnet_notify() */ 
108         cfs_time_t        up_last_alive;   /* when the peer was last alive */
109 } usock_peer_t;
110
111 typedef struct {
112         int               upt_notifier_fd;       /* notifier fd for writing */
113         struct pollfd    *upt_pollfd;            /* poll fds */
114         int               upt_nfds;              /* active poll fds */
115         int               upt_npollfd;           /* allocated poll fds */
116         usock_conn_t    **upt_idx2conn;          /* conns corresponding to
117                                                   * upt_pollfd[idx] */
118         int              *upt_skip;              /* skip chain */
119         int              *upt_fd2idx;            /* index into upt_pollfd[]
120                                                   * by fd */
121         int               upt_nfd2idx;           /* # of allocated elements
122                                                   * of upt_fd2idx[] */
123         struct list_head  upt_stale_list;        /* list of orphaned conns */
124         struct list_head  upt_pollrequests;      /* list of poll requests */
125         pthread_mutex_t   upt_pollrequests_lock; /* serialize */
126         int               upt_errno;             /* non-zero if errored */
127         struct cfs_completion upt_completion;    /* wait/signal facility for
128                                                   * syncronizing shutdown */
129 } usock_pollthread_t;
130
131 /* Number of elements in upt_pollfd[], upt_idx2conn[] and upt_fd2idx[]
132  * at initialization time. Will be resized on demand */
133 #define UPT_START_SIZ 32
134
135 /* # peer lists */
136 #define UD_PEER_HASH_SIZE  101
137
138 typedef struct {
139         int                 ud_state;          /* initialization state */
140         int                 ud_npollthreads;   /* # of poll threads */
141         usock_pollthread_t *ud_pollthreads;    /* their state */
142         int                 ud_shutdown;       /* shutdown flag */
143         int                 ud_nets_count;     /* # of instances */
144         struct list_head    ud_peers[UD_PEER_HASH_SIZE]; /* peer hash table */
145         pthread_rwlock_t    ud_peers_lock;     /* serialize */
146 } usock_data_t;
147
148 extern usock_data_t usock_data;
149
150 /* ud_state allowed values */
151 #define UD_STATE_INIT_NOTHING 0
152 #define UD_STATE_INITIALIZED 1
153
154 typedef struct {
155         int             un_peercount;   /* # of peers */
156         int             un_shutdown;    /* shutdown flag */
157         __u64           un_incarnation; /* my epoch */
158         pthread_cond_t  un_cond;        /* condvar to wait for notifications */
159         pthread_mutex_t un_lock;        /* a lock to protect un_cond */
160 } usock_net_t;
161         
162 typedef struct {
163         int ut_poll_timeout;  /* the third arg for poll(2) (seconds) */
164         int ut_timeout;       /* "stuck" socket timeout (seconds) */
165         int ut_npollthreads;  /* number of poll thread to spawn */
166         int ut_fair_limit;    /* how many packets can we receive or transmit
167                                * without calling poll(2) */
168         int ut_min_bulk;      /* smallest "large" message */
169         int ut_txcredits;     /* # concurrent sends */
170         int ut_peertxcredits; /* # concurrent sends to 1 peer */
171         int ut_socknagle;     /* Is Nagle alg on ? */
172         int ut_sockbufsiz;    /* size of socket buffers */
173 } usock_tunables_t;
174
175 extern usock_tunables_t usock_tuns;
176
177 typedef struct usock_preq_s {
178         int              upr_type;  /* type of requested action */
179         short            upr_value; /* bitmask of POLLIN and POLLOUT bits */
180         usock_conn_t *   upr_conn;  /* a conn for the sake of which
181                                      * action will be performed */
182         struct list_head upr_list;  /* neccessary to form list */
183 } usock_pollrequest_t;
184
185 /* Allowable poll request types are: */
186 #define POLL_ADD_REQUEST 1
187 #define POLL_DEL_REQUEST 2
188 #define POLL_RX_SET_REQUEST 3
189 #define POLL_TX_SET_REQUEST 4
190 #define POLL_SET_REQUEST 5
191
192 typedef struct {
193         struct list_head zc_list;   /* neccessary to form zc_ack list */
194         __u64            zc_cookie; /* zero-copy cookie */
195 } usock_zc_ack_t;
196
197 static inline void
198 usocklnd_conn_addref(usock_conn_t *conn)
199 {
200         LASSERT (cfs_atomic_read(&conn->uc_refcount) > 0);
201         cfs_atomic_inc(&conn->uc_refcount);
202 }
203
204 void usocklnd_destroy_conn(usock_conn_t *conn);
205
206 static inline void
207 usocklnd_conn_decref(usock_conn_t *conn)
208 {
209         LASSERT (cfs_atomic_read(&conn->uc_refcount) > 0);
210         if (cfs_atomic_dec_and_test(&conn->uc_refcount))
211                 usocklnd_destroy_conn(conn);
212 }
213
214 static inline void
215 usocklnd_peer_addref(usock_peer_t *peer)
216 {
217         LASSERT (cfs_atomic_read(&peer->up_refcount) > 0);
218         cfs_atomic_inc(&peer->up_refcount);
219 }
220
221 void usocklnd_destroy_peer(usock_peer_t *peer);
222
223 static inline void
224 usocklnd_peer_decref(usock_peer_t *peer)
225 {
226         LASSERT (cfs_atomic_read(&peer->up_refcount) > 0);
227         if (cfs_atomic_dec_and_test(&peer->up_refcount))
228                 usocklnd_destroy_peer(peer);
229 }
230
231 static inline int
232 usocklnd_ip2pt_idx(__u32 ip) {
233         return ip % usock_data.ud_npollthreads;
234 }
235
236 static inline struct list_head *
237 usocklnd_nid2peerlist(lnet_nid_t nid)
238 {
239         unsigned int hash = ((unsigned int)nid) % UD_PEER_HASH_SIZE;
240
241         return &usock_data.ud_peers[hash];
242 }
243
244 int usocklnd_startup(lnet_ni_t *ni);
245 void usocklnd_shutdown(lnet_ni_t *ni);
246 int usocklnd_send(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg);
247 int usocklnd_recv(lnet_ni_t *ni, void *private, lnet_msg_t *msg, int delayed,
248                   unsigned int niov, struct iovec *iov, lnet_kiov_t *kiov,
249                   unsigned int offset, unsigned int mlen, unsigned int rlen);
250 int usocklnd_accept(lnet_ni_t *ni, int sock_fd);
251
252 int usocklnd_poll_thread(void *arg);
253 int usocklnd_add_pollrequest(usock_conn_t *conn, int type, short value);
254 void usocklnd_add_killrequest(usock_conn_t *conn);
255 int usocklnd_process_pollrequest(usock_pollrequest_t *pr,
256                                  usock_pollthread_t *pt_data);
257 void usocklnd_execute_handlers(usock_pollthread_t *pt_data);
258 int usocklnd_calculate_chunk_size(int num);
259 void usocklnd_wakeup_pollthread(int i);
260
261 int usocklnd_notifier_handler(int fd);
262 void usocklnd_exception_handler(usock_conn_t *conn);
263 int usocklnd_read_handler(usock_conn_t *conn);
264 int usocklnd_read_msg(usock_conn_t *conn, int *cont_flag);
265 int usocklnd_handle_zc_req(usock_peer_t *peer, __u64 cookie);
266 int usocklnd_read_hello(usock_conn_t *conn, int *cont_flag);
267 int usocklnd_activeconn_hellorecv(usock_conn_t *conn);
268 int usocklnd_passiveconn_hellorecv(usock_conn_t *conn);
269 int usocklnd_write_handler(usock_conn_t *conn);
270 usock_tx_t * usocklnd_try_piggyback(struct list_head *tx_list_p,
271                                     struct list_head *zcack_list_p);
272 int usocklnd_activeconn_hellosent(usock_conn_t *conn);
273 int usocklnd_passiveconn_hellosent(usock_conn_t *conn);
274 int usocklnd_send_tx(usock_conn_t *conn, usock_tx_t *tx);
275 int usocklnd_read_data(usock_conn_t *conn);
276
277 void usocklnd_release_poll_states(int n);
278 int usocklnd_base_startup();
279 void usocklnd_base_shutdown(int n);
280 __u64 usocklnd_new_incarnation();
281 void usocklnd_del_all_peers(lnet_ni_t *ni);
282 void usocklnd_del_peer_and_conns(usock_peer_t *peer);
283 void usocklnd_del_conns_locked(usock_peer_t *peer);
284
285 int usocklnd_conn_timed_out(usock_conn_t *conn, cfs_time_t current_time);
286 void usocklnd_conn_kill(usock_conn_t *conn);
287 void usocklnd_conn_kill_locked(usock_conn_t *conn);
288 usock_conn_t *usocklnd_conn_allocate();
289 void usocklnd_conn_free(usock_conn_t *conn);
290 void usocklnd_tear_peer_conn(usock_conn_t *conn);
291 void usocklnd_check_peer_stale(lnet_ni_t *ni, lnet_process_id_t id);
292 int usocklnd_create_passive_conn(lnet_ni_t *ni, int fd, usock_conn_t **connp);
293 int usocklnd_create_active_conn(usock_peer_t *peer, int type,
294                                 usock_conn_t **connp);
295 int usocklnd_connect_srv_mode(int *fdp, __u32 dst_ip, __u16 dst_port);
296 int usocklnd_connect_cli_mode(int *fdp, __u32 dst_ip, __u16 dst_port);
297 int usocklnd_set_sock_options(int fd);
298 void usocklnd_init_msg(ksock_msg_t *msg, int type);
299 usock_tx_t *usocklnd_create_noop_tx(__u64 cookie);
300 usock_tx_t *usocklnd_create_tx(lnet_msg_t *lntmsg);
301 void usocklnd_init_hello_msg(ksock_hello_msg_t *hello,
302                              lnet_ni_t *ni, int type, lnet_nid_t peer_nid);
303 usock_tx_t *usocklnd_create_hello_tx(lnet_ni_t *ni,
304                                      int type, lnet_nid_t peer_nid);
305 usock_tx_t *usocklnd_create_cr_hello_tx(lnet_ni_t *ni,
306                                         int type, lnet_nid_t peer_nid);
307 void usocklnd_destroy_tx(lnet_ni_t *ni, usock_tx_t *tx);
308 void usocklnd_destroy_txlist(lnet_ni_t *ni, struct list_head *txlist);
309 void usocklnd_destroy_zcack_list(struct list_head *zcack_list);
310 void usocklnd_destroy_peer (usock_peer_t *peer);
311 int usocklnd_get_conn_type(lnet_msg_t *lntmsg);
312 int usocklnd_type2idx(int type);
313 usock_peer_t *usocklnd_find_peer_locked(lnet_ni_t *ni, lnet_process_id_t id);
314 int usocklnd_create_peer(lnet_ni_t *ni, lnet_process_id_t id,
315                          usock_peer_t **peerp);
316 int usocklnd_find_or_create_peer(lnet_ni_t *ni, lnet_process_id_t id,
317                                  usock_peer_t **peerp);
318 int usocklnd_find_or_create_conn(usock_peer_t *peer, int type,
319                                  usock_conn_t **connp,
320                                  usock_tx_t *tx, usock_zc_ack_t *zc_ack,
321                                  int *send_immediately_flag);                                 
322 void usocklnd_link_conn_to_peer(usock_conn_t *conn, usock_peer_t *peer, int idx);
323 int usocklnd_invert_type(int type);
324 void usocklnd_conn_new_state(usock_conn_t *conn, int new_state);
325 void usocklnd_cleanup_stale_conns(usock_peer_t *peer, __u64 incrn,
326                                   usock_conn_t *skip_conn);
327
328 void usocklnd_rx_hellomagic_state_transition(usock_conn_t *conn);
329 void usocklnd_rx_helloversion_state_transition(usock_conn_t *conn);
330 void usocklnd_rx_hellobody_state_transition(usock_conn_t *conn);
331 void usocklnd_rx_helloIPs_state_transition(usock_conn_t *conn);
332 void usocklnd_rx_lnethdr_state_transition(usock_conn_t *conn);
333 void usocklnd_rx_ksmhdr_state_transition(usock_conn_t *conn);
334 void usocklnd_rx_skipping_state_transition(usock_conn_t *conn);