1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
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>
12 * This file is part of Portals, http://www.sf.net/projects/lustre/
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.
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.
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.
29 #define DEBUG_PORTAL_ALLOC
31 # define EXPORT_SYMTAB
34 #include <linux/config.h>
35 #include <linux/module.h>
36 #include <linux/kernel.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>
44 #include <linux/uio.h>
45 #include <linux/sched.h>
47 #include <asm/system.h>
48 #include <asm/uaccess.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>
57 #define DEBUG_SUBSYSTEM S_SOCKNAL
59 #include <linux/kp30.h>
60 #include <portals/p30.h>
61 #include <portals/lib-p30.h>
63 #define SOCKNAL_NLTXS 128 /* # normal transmit messages */
64 #define SOCKNAL_NNBLK_LTXS 128 /* # transmit messages reserved if can't block */
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 */
69 #define SOCKNAL_SMALL_FWD_PAGES 1 /* # pages in a small message fwd buffer */
71 #define SOCKNAL_LARGE_FWD_PAGES (PAGE_ALIGN (sizeof (ptl_hdr_t) + PTL_MTU) >> PAGE_SHIFT)
72 /* # pages in a large message fwd buffer */
74 #define SOCKNAL_RESCHED 100 /* # scheduler loops before reschedule */
76 #define SOCKNAL_TX_LOW_WATER(sk) (((sk)->sndbuf*8)/10)
78 #define TOENAL_N_SCHED 1
80 typedef struct /* pool of forwarding buffers */
82 struct list_head fmp_idle_fmbs; /* buffers waiting for a connection */
83 struct list_head fmp_blocked_conns; /* connections waiting for a buffer */
87 int ksnd_init; /* initialisation state */
89 struct list_head ksnd_socklist; /* all my connections */
90 rwlock_t ksnd_socklist_lock; /* stabilise add/find/remove */
94 nal_cb_t *ksnd_nal_cb;
95 spinlock_t ksnd_nal_cb_lock; /* lib cli/sti lock */
97 atomic_t ksnd_nthreads; /* # live threads */
98 int ksnd_shuttingdown; /* tell threads to exit */
100 kpr_router_t ksnd_router; /* THE router */
102 spinlock_t ksnd_sched_lock; /* serialise packet scheduling */
103 wait_queue_head_t ksnd_sched_waitq; /* where scheduler(s) wait */
105 struct list_head ksnd_rx_conns; /* conn waiting to be read */
106 struct list_head ksnd_tx_conns; /* conn waiting to be written */
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 */
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 */
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 */
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 */
127 #define SOCKNAL_INIT_NOTHING 0
128 #define SOCKNAL_INIT_DATA 1
129 #define SOCKNAL_INIT_PTL 2
130 #define SOCKNAL_INIT_ALL 3
132 typedef struct /* transmit packet */
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 */
141 typedef struct /* locally transmitted packet */
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 */
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 */
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 */
157 /* NB list_entry() is used here as convenient macro for calculating a
158 * pointer to a struct from the addres of a member.
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];
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 */
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 */
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 */
196 void *ksnc_cookie; /* rx lib_finalize passthru arg */
197 ptl_hdr_t ksnc_hdr; /* where I read headers into */
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 */
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);
216 ktoenal_put_conn (ksock_conn_t *conn)
218 CDEBUG (D_OTHER, "putting conn[%p] -> "LPX64" (%d)\n",
219 conn, conn->ksnc_peernid, atomic_read (&conn->ksnc_refcount));
221 if (atomic_dec_and_test (&conn->ksnc_refcount))
222 _ktoenal_put_conn (conn);
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);
235 extern nal_cb_t ktoenal_lib;
236 extern ksock_nal_data_t ktoenal_data;