1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2001 Cluster File Systems, Inc. <braam@clusterfs.com>
6 * This file is part of Lustre, http://www.lustre.org.
8 * Lustre is free software; you can redistribute it and/or
9 * modify it under the terms of version 2 of the GNU General Public
10 * License as published by the Free Software Foundation.
12 * Lustre is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Lustre; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * Basic library routines.
28 # define EXPORT_SYMTAB
31 #include <qsnet/kernel.h>
32 #undef printf /* nasty QSW #define */
34 #include <linux/config.h>
35 #include <linux/module.h>
38 # include <elan/epcomms.h>
40 # include <elan3/elanregs.h>
41 # include <elan3/elandev.h>
42 # include <elan3/elanvp.h>
43 # include <elan3/elan3mmu.h>
44 # include <elan3/elanctxt.h>
45 # include <elan3/elandebug.h>
46 # include <elan3/urom_addrs.h>
47 # include <elan3/busops.h>
48 # include <elan3/kcomm.h>
51 #include <linux/kernel.h>
53 #include <linux/string.h>
54 #include <linux/stat.h>
55 #include <linux/errno.h>
56 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
57 #include <linux/locks.h> /* wait_on_buffer */
59 #include <linux/buffer_head.h> /* wait_on_buffer */
61 #include <linux/unistd.h>
63 #include <linux/uio.h>
65 #include <asm/system.h>
66 #include <asm/uaccess.h>
69 #include <linux/file.h>
70 #include <linux/stat.h>
71 #include <linux/list.h>
72 #include <linux/sysctl.h>
73 #include <asm/segment.h>
75 #define DEBUG_SUBSYSTEM S_QSWNAL
77 #include <linux/kp30.h>
78 #include <linux/kpr.h>
79 #include <portals/p30.h>
80 #include <portals/lib-p30.h>
81 #include <portals/nal.h>
83 #define KQSW_CHECKSUM 0
85 typedef unsigned long kqsw_csum_t;
86 #define KQSW_CSUM_SIZE (2 * sizeof (kqsw_csum_t))
88 #define KQSW_CSUM_SIZE 0
90 #define KQSW_HDR_SIZE (sizeof (ptl_hdr_t) + KQSW_CSUM_SIZE)
93 * Performance Tuning defines
94 * NB no mention of PAGE_SIZE for interoperability
96 #define KQSW_MAXPAYLOAD PTL_MTU
97 #define KQSW_SMALLPAYLOAD ((4<<10) - KQSW_HDR_SIZE) /* small/large ep receiver breakpoint */
99 #define KQSW_TX_MAXCONTIG (1<<10) /* largest payload that gets made contiguous on transmit */
101 #define KQSW_NTXMSGS 8 /* # normal transmit messages */
102 #define KQSW_NNBLK_TXMSGS 512 /* # reserved transmit messages if can't block */
104 #define KQSW_NRXMSGS_LARGE 64 /* # large receive buffers */
105 #define KQSW_EP_ENVELOPES_LARGE 256 /* # large ep envelopes */
107 #define KQSW_NRXMSGS_SMALL 256 /* # small receive buffers */
108 #define KQSW_EP_ENVELOPES_SMALL 2048 /* # small ep envelopes */
110 #define KQSW_RESCHED 100 /* # busy loops that forces scheduler to yield */
112 #define KQSW_OPTIMIZED_GETS 1 /* optimize gets >= this size */
113 #define KQSW_OPTIMIZED_PUTS (32<<10) /* optimize puts >= this size */
114 #define KQSW_COPY_SMALL_FWD 0 /* copy small fwd messages to pre-mapped buffer? */
120 #define KQSW_TX_BUFFER_SIZE (KQSW_HDR_SIZE + KQSW_TX_MAXCONTIG)
121 /* The pre-allocated tx buffer (hdr + small payload) */
123 #define KQSW_NTXMSGPAGES (btopr(KQSW_TX_BUFFER_SIZE) + 1 + btopr(KQSW_MAXPAYLOAD) + 1)
124 /* Reserve elan address space for pre-allocated and pre-mapped transmit
125 * buffer and a full payload too. Extra pages allow for page alignment */
127 #define KQSW_NRXMSGPAGES_SMALL (btopr(KQSW_HDR_SIZE + KQSW_SMALLPAYLOAD))
128 /* receive hdr/payload always contiguous and page aligned */
129 #define KQSW_NRXMSGBYTES_SMALL (KQSW_NRXMSGPAGES_SMALL * PAGE_SIZE)
131 #define KQSW_NRXMSGPAGES_LARGE (btopr(KQSW_HDR_SIZE + KQSW_MAXPAYLOAD))
132 /* receive hdr/payload always contiguous and page aligned */
133 #define KQSW_NRXMSGBYTES_LARGE (KQSW_NRXMSGPAGES_LARGE * PAGE_SIZE)
134 /* biggest complete packet we can receive (or transmit) */
136 /* Remote memory descriptor */
139 __u32 kqrmd_nfrag; /* # frags */
141 EP_NMD kqrmd_frag[0]; /* actual frags */
143 EP_IOVEC kqrmd_frag[0]; /* actual frags */
145 } kqswnal_remotemd_t;
147 typedef struct kqswnal_rx
149 struct list_head krx_list; /* enqueue -> thread */
150 struct kqswnal_rx *krx_alloclist; /* stack in kqn_rxds */
151 EP_RCVR *krx_eprx; /* port to post receives to */
152 EP_RXD *krx_rxd; /* receive descriptor (for repost) */
154 EP_NMD krx_elanbuffer; /* contiguous Elan buffer */
156 E3_Addr krx_elanbuffer; /* contiguous Elan buffer */
158 int krx_npages; /* # pages in receive buffer */
159 int krx_nob; /* Number Of Bytes received into buffer */
160 int krx_rpc_reply_needed; /* peer waiting for EKC RPC reply */
161 int krx_rpc_reply_status; /* what status to send */
162 int krx_state; /* what this RX is doing */
163 atomic_t krx_refcount; /* how to tell when rpc is done */
164 kpr_fwd_desc_t krx_fwd; /* embedded forwarding descriptor */
165 ptl_kiov_t krx_kiov[KQSW_NRXMSGPAGES_LARGE]; /* buffer frags */
168 #define KRX_POSTED 1 /* receiving */
169 #define KRX_PARSE 2 /* ready to be parsed */
170 #define KRX_COMPLETING 3 /* waiting to be completed */
173 typedef struct kqswnal_tx
175 struct list_head ktx_list; /* enqueue idle/active */
176 struct list_head ktx_delayed_list; /* enqueue delayedtxds */
177 struct kqswnal_tx *ktx_alloclist; /* stack in kqn_txds */
178 unsigned int ktx_isnblk:1; /* reserved descriptor? */
179 unsigned int ktx_state:7; /* What I'm doing */
180 unsigned int ktx_firsttmpfrag:1; /* ktx_frags[0] is in my ebuffer ? 0 : 1 */
181 uint32_t ktx_basepage; /* page offset in reserved elan tx vaddrs for mapping pages */
182 int ktx_npages; /* pages reserved for mapping messages */
183 int ktx_nmappedpages; /* # pages mapped for current message */
184 int ktx_port; /* destination ep port */
185 ptl_nid_t ktx_nid; /* destination node */
186 void *ktx_args[3]; /* completion passthru */
187 char *ktx_buffer; /* pre-allocated contiguous buffer for hdr + small payloads */
188 unsigned long ktx_launchtime; /* when (in jiffies) the transmit was launched */
190 /* debug/info fields */
191 pid_t ktx_launcher; /* pid of launching process */
193 int ktx_nfrag; /* # message frags */
195 int ktx_rail; /* preferred rail */
196 EP_NMD ktx_ebuffer; /* elan mapping of ktx_buffer */
197 EP_NMD ktx_frags[EP_MAXFRAG];/* elan mapping of msg frags */
199 E3_Addr ktx_ebuffer; /* elan address of ktx_buffer */
200 EP_IOVEC ktx_frags[EP_MAXFRAG];/* msg frags (elan vaddrs) */
204 #define KTX_IDLE 0 /* on kqn_(nblk_)idletxds */
205 #define KTX_FORWARDING 1 /* sending a forwarded packet */
206 #define KTX_SENDING 2 /* normal send */
207 #define KTX_GETTING 3 /* sending optimised get */
208 #define KTX_PUTTING 4 /* sending optimised put */
209 #define KTX_RDMAING 5 /* handling optimised put/get */
213 /* dynamic tunables... */
214 int kqn_optimized_puts; /* optimized PUTs? */
215 int kqn_optimized_gets; /* optimized GETs? */
217 struct ctl_table_header *kqn_sysctl; /* sysctl interface */
219 } kqswnal_tunables_t;
223 char kqn_init; /* what's been initialised */
224 char kqn_shuttingdown; /* I'm trying to shut down */
225 atomic_t kqn_nthreads; /* # threads running */
227 kqswnal_rx_t *kqn_rxds; /* stack of all the receive descriptors */
228 kqswnal_tx_t *kqn_txds; /* stack of all the transmit descriptors */
230 struct list_head kqn_idletxds; /* transmit descriptors free to use */
231 struct list_head kqn_nblk_idletxds; /* reserved free transmit descriptors */
232 struct list_head kqn_activetxds; /* transmit descriptors being used */
233 spinlock_t kqn_idletxd_lock; /* serialise idle txd access */
234 wait_queue_head_t kqn_idletxd_waitq; /* sender blocks here waiting for idle txd */
235 struct list_head kqn_idletxd_fwdq; /* forwarded packets block here waiting for idle txd */
236 atomic_t kqn_pending_txs; /* # transmits being prepped */
238 spinlock_t kqn_sched_lock; /* serialise packet schedulers */
239 wait_queue_head_t kqn_sched_waitq; /* scheduler blocks here */
241 struct list_head kqn_readyrxds; /* rxds full of data */
242 struct list_head kqn_delayedfwds; /* delayed forwards */
243 struct list_head kqn_delayedtxds; /* delayed transmits */
246 EP_SYS *kqn_ep; /* elan system */
247 EP_NMH *kqn_ep_tx_nmh; /* elan reserved tx vaddrs */
248 EP_NMH *kqn_ep_rx_nmh; /* elan reserved rx vaddrs */
250 EP_DEV *kqn_ep; /* elan device */
251 ELAN3_DMA_HANDLE *kqn_eptxdmahandle; /* elan reserved tx vaddrs */
252 ELAN3_DMA_HANDLE *kqn_eprxdmahandle; /* elan reserved rx vaddrs */
254 EP_XMTR *kqn_eptx; /* elan transmitter */
255 EP_RCVR *kqn_eprx_small; /* elan receiver (small messages) */
256 EP_RCVR *kqn_eprx_large; /* elan receiver (large messages) */
257 kpr_router_t kqn_router; /* connection to Kernel Portals Router module */
259 ptl_nid_t kqn_nid_offset; /* this cluster's NID offset */
260 int kqn_nnodes; /* this cluster's size */
261 int kqn_elanid; /* this nodes's elan ID */
263 EP_STATUSBLK kqn_rpc_success; /* preset RPC reply status blocks */
264 EP_STATUSBLK kqn_rpc_failed;
268 #define KQN_INIT_NOTHING 0 /* MUST BE ZERO so zeroed state is initialised OK */
269 #define KQN_INIT_DATA 1
270 #define KQN_INIT_LIB 2
271 #define KQN_INIT_ALL 3
273 extern lib_nal_t kqswnal_lib;
274 extern nal_t kqswnal_api;
275 extern kqswnal_tunables_t kqswnal_tunables;
276 extern kqswnal_data_t kqswnal_data;
278 extern int kqswnal_thread_start (int (*fn)(void *arg), void *arg);
279 extern void kqswnal_rxhandler(EP_RXD *rxd);
280 extern int kqswnal_scheduler (void *);
281 extern void kqswnal_fwd_packet (void *arg, kpr_fwd_desc_t *fwd);
282 extern void kqswnal_rx_done (kqswnal_rx_t *krx);
284 static inline ptl_nid_t
285 kqswnal_elanid2nid (int elanid)
287 return (kqswnal_data.kqn_nid_offset + elanid);
291 kqswnal_nid2elanid (ptl_nid_t nid)
293 /* not in this cluster? */
294 if (nid < kqswnal_data.kqn_nid_offset ||
295 nid >= kqswnal_data.kqn_nid_offset + kqswnal_data.kqn_nnodes)
298 return (nid - kqswnal_data.kqn_nid_offset);
301 static inline ptl_nid_t
302 kqswnal_rx_nid(kqswnal_rx_t *krx)
304 return (kqswnal_elanid2nid(ep_rxd_node(krx->krx_rxd)));
308 kqswnal_pages_spanned (void *base, int nob)
310 unsigned long first_page = ((unsigned long)base) >> PAGE_SHIFT;
311 unsigned long last_page = (((unsigned long)base) + (nob - 1)) >> PAGE_SHIFT;
313 LASSERT (last_page >= first_page); /* can't wrap address space */
314 return (last_page - first_page + 1);
318 static inline kqsw_csum_t kqsw_csum (kqsw_csum_t sum, void *base, int nob)
320 unsigned char *ptr = (unsigned char *)base;
329 static inline void kqswnal_rx_decref (kqswnal_rx_t *krx)
331 LASSERT (atomic_read (&krx->krx_refcount) > 0);
332 if (atomic_dec_and_test (&krx->krx_refcount))
333 kqswnal_rx_done(krx);
337 # ifndef EP_RAILMASK_ALL
338 # error "old (unsupported) version of EKC headers"
341 /* multirail defines these in <elan/epcomms.h> */
342 #define EP_MSG_SVC_PORTALS_SMALL (0x10) /* Portals over elan port number (large payloads) */
343 #define EP_MSG_SVC_PORTALS_LARGE (0x11) /* Portals over elan port number (small payloads) */
344 /* NB small/large message sizes are GLOBAL constants */
346 /* A minimal attempt to minimise inline #ifdeffing */
348 #define EP_SUCCESS ESUCCESS
349 #define EP_ENOMEM ENOMEM
351 static inline EP_XMTR *
352 ep_alloc_xmtr(EP_DEV *e)
354 return (ep_alloc_large_xmtr(e));
357 static inline EP_RCVR *
358 ep_alloc_rcvr(EP_DEV *e, int svc, int nenv)
360 return (ep_install_large_rcvr(e, svc, nenv));
364 ep_free_xmtr(EP_XMTR *x)
366 ep_free_large_xmtr(x);
370 ep_free_rcvr(EP_RCVR *r)
372 ep_remove_large_rcvr(r);
376 #endif /* _QSWNAL_H */