Whamcloud - gitweb
b211d6c6006c8f46f6b3cec0da78440a5d0c5213
[fs/lustre-release.git] / lnet / klnds / toelnd / toenal.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: Zach Brown <zab@zabbo.net>
6  *   Author: Peter J. Braam <braam@clusterfs.com>
7  *   Author: Phil Schwan <phil@clusterfs.com>
8  *   Author: Eric Barton <eric@bartonsoftware.com>
9  *   Author: Kedar Sovani <kedar@calsoftinc.com>
10  *   Author: Amey Inamdar <amey@calsoftinc.com>
11  *
12  *   This file is part of Portals, http://www.sf.net/projects/lustre/
13  *
14  *   Portals is free software; you can redistribute it and/or
15  *   modify it under the terms of version 2 of the GNU General Public
16  *   License as published by the Free Software Foundation.
17  *
18  *   Portals is distributed in the hope that it will be useful,
19  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
20  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  *   GNU General Public License for more details.
22  *
23  *   You should have received a copy of the GNU General Public License
24  *   along with Portals; if not, write to the Free Software
25  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26  *
27  */
28
29 #define DEBUG_PORTAL_ALLOC
30 #ifndef EXPORT_SYMTAB
31 # define EXPORT_SYMTAB
32 #endif
33
34 #include <linux/config.h>
35 #include <linux/module.h>
36 #include <linux/kernel.h>
37 #include <linux/mm.h>
38 #include <linux/string.h>
39 #include <linux/stat.h>
40 #include <linux/errno.h>
41 #include <linux/smp_lock.h>
42 #include <linux/unistd.h>
43 #include <net/tcp.h>
44 #include <linux/uio.h>
45 #include <linux/sched.h> 
46
47 #include <asm/system.h>
48 #include <asm/uaccess.h>
49
50 #include <linux/fs.h>
51 #include <linux/file.h>
52 #include <linux/stat.h>
53 #include <linux/list.h>
54 #include <asm/uaccess.h>
55 #include <asm/segment.h>
56
57 #define DEBUG_SUBSYSTEM S_SOCKNAL
58
59 #include <linux/kp30.h>
60 #include <portals/p30.h>
61 #include <portals/lib-p30.h>
62
63 #define SOCKNAL_NLTXS           128             /* # normal transmit messages */
64 #define SOCKNAL_NNBLK_LTXS      128             /* # transmit messages reserved if can't block */
65
66 #define SOCKNAL_SMALL_FWD_NMSGS 128             /* # small messages I can be forwarding at any time */
67 #define SOCKNAL_LARGE_FWD_NMSGS 32              /* # large messages I can be forwarding at any time */
68
69 #define SOCKNAL_SMALL_FWD_PAGES 1               /* # pages in a small message fwd buffer */
70
71 #define SOCKNAL_LARGE_FWD_PAGES (PAGE_ALIGN (sizeof (ptl_hdr_t) + PTL_MTU) >> PAGE_SHIFT)
72                                                 /* # pages in a large message fwd buffer */
73
74 #define SOCKNAL_RESCHED         100             /* # scheduler loops before reschedule */
75
76 #define SOCKNAL_TX_LOW_WATER(sk) (((sk)->sndbuf*8)/10)
77
78 #define TOENAL_N_SCHED 1
79
80 typedef struct                                  /* pool of forwarding buffers */
81 {
82         struct list_head  fmp_idle_fmbs;        /* buffers waiting for a connection */
83         struct list_head  fmp_blocked_conns;    /* connections waiting for a buffer */
84 } ksock_fmb_pool_t;
85
86 typedef struct {
87         int               ksnd_init;            /* initialisation state */
88         
89         struct list_head  ksnd_socklist;        /* all my connections */
90         rwlock_t          ksnd_socklist_lock;   /* stabilise add/find/remove */
91
92
93         ptl_nid_t         ksnd_mynid;
94         nal_cb_t         *ksnd_nal_cb;
95         spinlock_t        ksnd_nal_cb_lock;     /* lib cli/sti lock */
96
97         atomic_t          ksnd_nthreads;        /* # live threads */
98         int               ksnd_shuttingdown;    /* tell threads to exit */
99         
100         kpr_router_t      ksnd_router;          /* THE router */
101
102         spinlock_t        ksnd_sched_lock;      /* serialise packet scheduling */
103         wait_queue_head_t ksnd_sched_waitq;     /* where scheduler(s) wait */
104
105         struct list_head  ksnd_rx_conns;        /* conn waiting to be read */
106         struct list_head  ksnd_tx_conns;        /* conn waiting to be written */
107         
108         void             *ksnd_fmbs;            /* all the pre-allocated FMBs */
109         ksock_fmb_pool_t  ksnd_small_fmp;       /* small message forwarding buffers */
110         ksock_fmb_pool_t  ksnd_large_fmp;       /* large message forwarding buffers */
111
112         void             *ksnd_ltxs;            /* all the pre-allocated LTXs */
113         struct list_head  ksnd_idle_ltx_list;   /* where to get an idle LTX */
114         struct list_head  ksnd_idle_nblk_ltx_list; /* where to get an idle LTX if you can't block */
115         wait_queue_head_t ksnd_idle_ltx_waitq;  /* where to block for an idle LTX */
116
117         struct list_head  ksnd_reaper_list;     /* conn waiting to be reaped */
118         wait_queue_head_t ksnd_reaper_waitq;    /* reaper sleeps here */
119         spinlock_t        ksnd_reaper_lock;     /* serialise */
120         
121         struct task_struct *ksnd_pollthread_tsk;/* task_struct for the poll thread */
122         poll_table          ksnd_pwait;         /* poll wait table for the socket */
123         int                 ksnd_slistchange;   /* informs the pollthread that
124                                                  * the socklist has changed */  
125 } ksock_nal_data_t;
126
127 #define SOCKNAL_INIT_NOTHING    0
128 #define SOCKNAL_INIT_DATA       1
129 #define SOCKNAL_INIT_PTL        2
130 #define SOCKNAL_INIT_ALL        3
131
132 typedef struct                                  /* transmit packet */
133 {
134         struct list_head        tx_list;       /* queue on conn for transmission etc */
135         char                    tx_isfwd;      /* forwarding / sourced here */
136         int                     tx_nob;        /* # packet bytes */
137         int                     tx_niov;       /* # packet frags */
138         struct iovec           *tx_iov;        /* packet frags */
139 } ksock_tx_t;
140
141 typedef struct                                  /* locally transmitted packet */
142 {
143         ksock_tx_t              ltx_tx;         /* send info */
144         struct list_head       *ltx_idle;       /* where to put when idle */
145         void                   *ltx_private;    /* lib_finalize() callback arg */
146         void                   *ltx_cookie;     /* lib_finalize() callback arg */
147         struct iovec            ltx_iov[1 + PTL_MD_MAX_IOV]; /* msg frags */
148         ptl_hdr_t               ltx_hdr;        /* buffer for packet header */
149 } ksock_ltx_t;
150
151 #define KSOCK_TX_2_KPR_FWD_DESC(ptr)    list_entry (ptr, kpr_fwd_desc_t, kprfd_scratch)
152 /* forwarded packets (router->socknal) embedded in kpr_fwd_desc_t::kprfd_scratch */
153
154 #define KSOCK_TX_2_KSOCK_LTX(ptr)       list_entry (ptr, ksock_ltx_t, ltx_tx)
155 /* local packets (lib->socknal) embedded in ksock_ltx_t::ltx_tx */
156
157 /* NB list_entry() is used here as convenient macro for calculating a
158  * pointer to a struct from the addres of a member.
159  */
160
161 typedef struct                                  /* Kernel portals Socket Forwarding message buffer */
162 {                                               /* (socknal->router) */
163         struct list_head        fmb_list;       /* queue idle */
164         kpr_fwd_desc_t          fmb_fwd;        /* router's descriptor */
165         int                     fmb_npages;     /* # pages allocated */
166         ksock_fmb_pool_t       *fmb_pool;       /* owning pool */
167         struct page            *fmb_pages[SOCKNAL_LARGE_FWD_PAGES];
168         struct iovec            fmb_iov[SOCKNAL_LARGE_FWD_PAGES];
169 } ksock_fmb_t;
170
171 #define SOCKNAL_RX_HEADER       1               /* reading header */
172 #define SOCKNAL_RX_BODY         2               /* reading body (to deliver here) */
173 #define SOCKNAL_RX_BODY_FWD     3               /* reading body (to forward) */
174 #define SOCKNAL_RX_SLOP         4               /* skipping body */
175 #define SOCKNAL_RX_GET_FMB      5               /* scheduled for forwarding */
176 #define SOCKNAL_RX_FMB_SLEEP    6               /* blocked waiting for a fwd desc */
177
178 typedef struct 
179
180         struct list_head    ksnc_list;          /* stash on global socket list */
181         struct file        *ksnc_file;          /* socket filp */
182         struct socket      *ksnc_sock;          /* socket */
183         ptl_nid_t           ksnc_peernid;       /* who's on the other end */
184         atomic_t            ksnc_refcount;      /* # users */
185         
186         /* READER */
187         struct list_head    ksnc_rx_list;       /* where I enq waiting input or a forwarding descriptor */
188         unsigned long       ksnc_rx_ready;      /* data ready to read */
189         int                 ksnc_rx_scheduled;  /* being progressed */
190         int                 ksnc_rx_state;      /* what is being read */
191         int                 ksnc_rx_nob_left;   /* # bytes to next hdr/body  */
192         int                 ksnc_rx_nob_wanted; /* bytes actually wanted */
193         int                 ksnc_rx_niov;       /* # frags */
194         struct iovec        ksnc_rx_iov[1 + PTL_MD_MAX_IOV]; /* the frags */
195
196         void               *ksnc_cookie;        /* rx lib_finalize passthru arg */
197         ptl_hdr_t           ksnc_hdr;           /* where I read headers into */
198
199         /* WRITER */
200         struct list_head    ksnc_tx_list;       /* where I enq waiting for output space */
201         struct list_head    ksnc_tx_queue;      /* packets waiting to be sent */
202         unsigned long       ksnc_tx_ready;      /* write space */
203         int                 ksnc_tx_scheduled;  /* being progressed */
204         
205 } ksock_conn_t;
206
207 extern int ktoenal_add_sock (ptl_nid_t nid, int fd);
208 extern int ktoenal_close_sock(ptl_nid_t nid);
209 extern int ktoenal_set_mynid(ptl_nid_t nid);
210 extern int ktoenal_push_sock(ptl_nid_t nid);
211 extern ksock_conn_t *ktoenal_get_conn (ptl_nid_t nid);
212 extern void _ktoenal_put_conn (ksock_conn_t *conn);
213 extern void ktoenal_close_conn (ksock_conn_t *conn);
214
215 static inline void
216 ktoenal_put_conn (ksock_conn_t *conn)
217 {
218         CDEBUG (D_OTHER, "putting conn[%p] -> "LPX64" (%d)\n", 
219                 conn, conn->ksnc_peernid, atomic_read (&conn->ksnc_refcount));
220         
221         if (atomic_dec_and_test (&conn->ksnc_refcount))
222                 _ktoenal_put_conn (conn);
223 }
224
225 extern int ktoenal_thread_start (int (*fn)(void *arg), void *arg);
226 extern int ktoenal_new_packet (ksock_conn_t *conn, int skip);
227 extern void ktoenal_fwd_packet (void *arg, kpr_fwd_desc_t *fwd);
228 extern int ktoenal_scheduler (void *arg);
229 extern int ktoenal_reaper (void *arg);
230 extern int ktoenal_pollthread (void *arg);
231 extern void ktoenal_data_ready(ksock_conn_t *conn);
232 extern void ktoenal_write_space(ksock_conn_t *conn);
233
234
235 extern nal_cb_t         ktoenal_lib;
236 extern ksock_nal_data_t ktoenal_data;