xref: /onnv-gate/usr/src/uts/sun4u/starfire/sys/idn_smr.h (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright (c) 1999 by Sun Microsystems, Inc.
24*0Sstevel@tonic-gate  * All rights reserved.
25*0Sstevel@tonic-gate  *
26*0Sstevel@tonic-gate  * Inter-Domain Network - SMR support.
27*0Sstevel@tonic-gate  */
28*0Sstevel@tonic-gate 
29*0Sstevel@tonic-gate #ifndef	_SYS_IDN_SMR_H
30*0Sstevel@tonic-gate #define	_SYS_IDN_SMR_H
31*0Sstevel@tonic-gate 
32*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
33*0Sstevel@tonic-gate 
34*0Sstevel@tonic-gate #include <sys/sysmacros.h>
35*0Sstevel@tonic-gate 
36*0Sstevel@tonic-gate #ifdef	__cplusplus
37*0Sstevel@tonic-gate extern "C" {
38*0Sstevel@tonic-gate #endif
39*0Sstevel@tonic-gate 
40*0Sstevel@tonic-gate typedef uint_t	smr_offset_t;
41*0Sstevel@tonic-gate 
42*0Sstevel@tonic-gate #define	IDN_NIL_SMROFFSET		((smr_offset_t)-1)
43*0Sstevel@tonic-gate 
44*0Sstevel@tonic-gate /*
45*0Sstevel@tonic-gate  * ---------------------------------------------------------------------
46*0Sstevel@tonic-gate  * Data in the SMR is automatically aligned on 64 byte boundaries due
47*0Sstevel@tonic-gate  * to the large IDN_SMR_BUFSIZE, however the streams buffers may not be
48*0Sstevel@tonic-gate  * so we bump them in order to allow us to align appropriately and thus
49*0Sstevel@tonic-gate  * maximize bcopy performance.
50*0Sstevel@tonic-gate  * ---------------------------------------------------------------------
51*0Sstevel@tonic-gate  */
52*0Sstevel@tonic-gate #define	IDN_ALIGNSIZE		64
53*0Sstevel@tonic-gate /*
54*0Sstevel@tonic-gate  * Align the pointer "p" to the same relative offset as the reference
55*0Sstevel@tonic-gate  * pointer "r" within IDN_ALIGNSIZE bytes.
56*0Sstevel@tonic-gate  */
57*0Sstevel@tonic-gate #define	IDN_ALIGNPTR(p, r)	((uintptr_t)(p) + (((uintptr_t)(r) - \
58*0Sstevel@tonic-gate 					(uintptr_t)(p)) & \
59*0Sstevel@tonic-gate 					(uintptr_t)(IDN_ALIGNSIZE - 1)))
60*0Sstevel@tonic-gate 
61*0Sstevel@tonic-gate #define	IDN_OFFSET2ADDR(off)	((caddr_t)((uintptr_t)(off) + \
62*0Sstevel@tonic-gate 					(uintptr_t)idn.smr.vaddr))
63*0Sstevel@tonic-gate #define	IDN_ADDR2OFFSET(va)	((smr_offset_t)((caddr_t)(va) - idn.smr.vaddr))
64*0Sstevel@tonic-gate #define	IDN_BUF2DATA(b, o)	((caddr_t)((uintptr_t)(b) + (uintptr_t)(o)))
65*0Sstevel@tonic-gate #define	IDN_BUF2HDR(b)		((smr_pkthdr_t *)(b))
66*0Sstevel@tonic-gate 
67*0Sstevel@tonic-gate #define	IDN_CKSUM_PKT_COUNT	(((int)&((smr_pkthdr_t *)(0))->b_cksum) / 2)
68*0Sstevel@tonic-gate #define	IDN_CKSUM_PKT(h)	\
69*0Sstevel@tonic-gate 		(IDN_CHECKSUM ? \
70*0Sstevel@tonic-gate 		idn_cksum((ushort_t *)(h), IDN_CKSUM_PKT_COUNT) : 0)
71*0Sstevel@tonic-gate 
72*0Sstevel@tonic-gate typedef struct smr_pkthdr {
73*0Sstevel@tonic-gate 	uint_t		b_netaddr;
74*0Sstevel@tonic-gate 	uint_t		b_netports;
75*0Sstevel@tonic-gate 	smr_offset_t	b_offset;
76*0Sstevel@tonic-gate 	int		b_length;
77*0Sstevel@tonic-gate 
78*0Sstevel@tonic-gate 	ushort_t	b_rawio;
79*0Sstevel@tonic-gate 	ushort_t	b_cksum;
80*0Sstevel@tonic-gate 	smr_offset_t	b_next;		/* used during reclamation */
81*0Sstevel@tonic-gate } smr_pkthdr_t;
82*0Sstevel@tonic-gate 
83*0Sstevel@tonic-gate /*
84*0Sstevel@tonic-gate  * ---------------------------------------------------------------------
85*0Sstevel@tonic-gate  * IDN Slab related definitions.
86*0Sstevel@tonic-gate  *
87*0Sstevel@tonic-gate  * Domains are allocated SMR buffers in slabs.  Slaves keep track of
88*0Sstevel@tonic-gate  * their own slabs in their respective idn_domain entry.  The Master
89*0Sstevel@tonic-gate  * keeps track of slave slabs via their respective idn_domain entry.
90*0Sstevel@tonic-gate  * The global slab pools representing all of the SMR and managed by
91*0Sstevel@tonic-gate  * the master are maintained in the idn_global structure.
92*0Sstevel@tonic-gate  *
93*0Sstevel@tonic-gate  * The minimum number of slabs is chosen so that there is at least
94*0Sstevel@tonic-gate  * one slab available for every possible domain that might be attached.
95*0Sstevel@tonic-gate  *
96*0Sstevel@tonic-gate  * NOTE: idn_slab_bufcount * idn_smr_bufsize should be on a 64-byte
97*0Sstevel@tonic-gate  *	 (IDN_ALIGNSIZE) boundary for maximum bcopy performance.
98*0Sstevel@tonic-gate  * ---------------------------------------------------------------------
99*0Sstevel@tonic-gate  */
100*0Sstevel@tonic-gate #define	IDN_SLAB_BUFCOUNT	idn_slab_bufcount
101*0Sstevel@tonic-gate #define	IDN_SLAB_SIZE		(IDN_SLAB_BUFCOUNT * IDN_SMR_BUFSIZE)
102*0Sstevel@tonic-gate #define	IDN_SLAB_MAXNUM		(idn.slabpool->ntotslabs)
103*0Sstevel@tonic-gate #define	IDN_SLAB_MINPERPOOL	3
104*0Sstevel@tonic-gate #define	IDN_SLAB_MINTOTAL	idn_slab_mintotal
105*0Sstevel@tonic-gate #define	IDN_SLAB_PREALLOC	idn_slab_prealloc
106*0Sstevel@tonic-gate 
107*0Sstevel@tonic-gate /*
108*0Sstevel@tonic-gate  * ---------------------------------------------------------------------
109*0Sstevel@tonic-gate  * Maximum number of slabs per domain the master will
110*0Sstevel@tonic-gate  * allow to be allocated.  Further requests simply result
111*0Sstevel@tonic-gate  * in a failed allocation.
112*0Sstevel@tonic-gate  * Nominal value is 1/6 of the total available (~10).
113*0Sstevel@tonic-gate  * Maximum number of bufs a domain can expect based on
114*0Sstevel@tonic-gate  * IDN_SLAB_MAXPERDOMAIN.
115*0Sstevel@tonic-gate  * ---------------------------------------------------------------------
116*0Sstevel@tonic-gate  */
117*0Sstevel@tonic-gate #define	IDN_SLAB_MAXPERDOMAIN	idn_slab_maxperdomain
118*0Sstevel@tonic-gate #define	IDN_BUF_MAXPERDOMAIN	(IDN_SLAB_MAXPERDOMAIN * IDN_SLAB_BUFCOUNT)
119*0Sstevel@tonic-gate /*
120*0Sstevel@tonic-gate  * ---------------------------------------------------------------------
121*0Sstevel@tonic-gate  * If the total number of available slabs managed by the master
122*0Sstevel@tonic-gate  * goes below this minimum total threshold, then the master kicks
123*0Sstevel@tonic-gate  * off a reap request to all domains to check for free slabs and
124*0Sstevel@tonic-gate  * to give them up.  For performance reasons, domains do not
125*0Sstevel@tonic-gate  * automatically flush out free slabs.  They rely on the master
126*0Sstevel@tonic-gate  * to tell them to look for some.
127*0Sstevel@tonic-gate  * ---------------------------------------------------------------------
128*0Sstevel@tonic-gate  */
129*0Sstevel@tonic-gate #define	IDN_SLAB_THRESHOLD	MIN(MAX_DOMAINS, \
130*0Sstevel@tonic-gate 					(IDN_SLAB_MINTOTAL + \
131*0Sstevel@tonic-gate 					(IDN_SLAB_MINTOTAL / 5)))
132*0Sstevel@tonic-gate #define	IDN_REAP_INTERVAL	(2 * hz)
133*0Sstevel@tonic-gate 
134*0Sstevel@tonic-gate #define	SMR_SLABPOOL_HASH(d)		((d) % idn.slabpool->npools)
135*0Sstevel@tonic-gate #define	SMR_SLABPOOL_HASHSTEP(p)	(((p)+4) % idn.slabpool->npools)
136*0Sstevel@tonic-gate #define	SMR_SLAB_HASH(p, d) \
137*0Sstevel@tonic-gate 				((d) % idn.slabpool->pool[p].nslabs)
138*0Sstevel@tonic-gate #define	SMR_SLAB_HASHSTEP(p, s) \
139*0Sstevel@tonic-gate 				(((s)+1) % idn.slabpool->pool[p].nslabs)
140*0Sstevel@tonic-gate 
141*0Sstevel@tonic-gate /*
142*0Sstevel@tonic-gate  * ---------------------------------------------------------------------
143*0Sstevel@tonic-gate  * There is one smr_slabbuf for each buffer in the respective slab.
144*0Sstevel@tonic-gate  *
145*0Sstevel@tonic-gate  * sb_domid	Domainid currently owning respective buffer.
146*0Sstevel@tonic-gate  *		Local domains use this field to determine what buffers
147*0Sstevel@tonic-gate  *		are outstanding at which domains.  The master uses this
148*0Sstevel@tonic-gate  *		field to know which domain owns given slab.
149*0Sstevel@tonic-gate  * sb_bufp	Actual pointer to (VA) buffer.
150*0Sstevel@tonic-gate  * sb_next	Used to manage free and in-use lists.
151*0Sstevel@tonic-gate  * ---------------------------------------------------------------------
152*0Sstevel@tonic-gate  */
153*0Sstevel@tonic-gate typedef struct smr_slabbuf {
154*0Sstevel@tonic-gate 	int		sb_domid;
155*0Sstevel@tonic-gate 	caddr_t		sb_bufp;
156*0Sstevel@tonic-gate 	struct smr_slabbuf	*sb_next;
157*0Sstevel@tonic-gate } smr_slabbuf_t;
158*0Sstevel@tonic-gate 
159*0Sstevel@tonic-gate /*
160*0Sstevel@tonic-gate  * ---------------------------------------------------------------------
161*0Sstevel@tonic-gate  * There is one smr_slab per slab of buffers.
162*0Sstevel@tonic-gate  *
163*0Sstevel@tonic-gate  * sl_next	List of slabs allocated to same requester.
164*0Sstevel@tonic-gate  * sl_start	Base virtual address (SMR) of slab.
165*0Sstevel@tonic-gate  * sl_end	Points to byte immediately following end of slab.
166*0Sstevel@tonic-gate  * sl_lock	Atomic lock used to manage free/inuse lists.
167*0Sstevel@tonic-gate  * sl_domid	Used by Master to indicate which slave owns
168*0Sstevel@tonic-gate  *		respective slab.
169*0Sstevel@tonic-gate  * sl_free	Freelist of available buffers.
170*0Sstevel@tonic-gate  * sl_inuse	List of buffers currently allocated and in-use.
171*0Sstevel@tonic-gate  * sl_head	Pointer to memory allocated to hold smr_slabbuf_t's.
172*0Sstevel@tonic-gate  * ---------------------------------------------------------------------
173*0Sstevel@tonic-gate  */
174*0Sstevel@tonic-gate typedef struct smr_slab {
175*0Sstevel@tonic-gate 	struct smr_slab	*sl_next;
176*0Sstevel@tonic-gate 	caddr_t		sl_start,
177*0Sstevel@tonic-gate 			sl_end;
178*0Sstevel@tonic-gate 	lock_t		sl_lock;
179*0Sstevel@tonic-gate 
180*0Sstevel@tonic-gate 	union {
181*0Sstevel@tonic-gate 		int	_sl_domid;
182*0Sstevel@tonic-gate 		struct {
183*0Sstevel@tonic-gate 			smr_slabbuf_t	*_sl_free;
184*0Sstevel@tonic-gate 			smr_slabbuf_t	*_sl_inuse;
185*0Sstevel@tonic-gate 			smr_slabbuf_t	*_sl_head;
186*0Sstevel@tonic-gate 		} _s;
187*0Sstevel@tonic-gate 	} _u;
188*0Sstevel@tonic-gate } smr_slab_t;
189*0Sstevel@tonic-gate 
190*0Sstevel@tonic-gate #define	sl_domid	_u._sl_domid
191*0Sstevel@tonic-gate #define	sl_free		_u._s._sl_free
192*0Sstevel@tonic-gate #define	sl_inuse	_u._s._sl_inuse
193*0Sstevel@tonic-gate #define	sl_head		_u._s._sl_head
194*0Sstevel@tonic-gate 
195*0Sstevel@tonic-gate /*
196*0Sstevel@tonic-gate  * ---------------------------------------------------------------------
197*0Sstevel@tonic-gate  * io/idn_smr.c
198*0Sstevel@tonic-gate  * ---------------------------------------------------------------------
199*0Sstevel@tonic-gate  */
200*0Sstevel@tonic-gate extern void	smr_slab_reap(int domid, int *nslabs);
201*0Sstevel@tonic-gate extern int	smr_slab_alloc(int domid, smr_slab_t **spp);
202*0Sstevel@tonic-gate extern void 	smr_slab_free(int domid, smr_slab_t *sp);
203*0Sstevel@tonic-gate extern void	smr_slab_garbage_collection(smr_slab_t *sp);
204*0Sstevel@tonic-gate extern int	smr_slab_busy(smr_slab_t *sp);
205*0Sstevel@tonic-gate extern int 	smr_buf_alloc(int domid, uint_t len, caddr_t *bufpp);
206*0Sstevel@tonic-gate extern int 	smr_buf_free(int domid, caddr_t bufp, uint_t len);
207*0Sstevel@tonic-gate extern int	smr_buf_free_locked(int domid, caddr_t bufp, uint_t len);
208*0Sstevel@tonic-gate extern int 	smr_buf_free_all(int domid);
209*0Sstevel@tonic-gate extern int 	smr_buf_reclaim(int domid, int nbufs);
210*0Sstevel@tonic-gate extern int 	smr_slaballoc_put(int domid, smr_slab_t *sp, int forceflag,
211*0Sstevel@tonic-gate 					int serrno);
212*0Sstevel@tonic-gate extern void	smr_alloc_buflist(smr_slab_t *sp);
213*0Sstevel@tonic-gate extern void	smr_free_buflist(smr_slab_t *sp);
214*0Sstevel@tonic-gate extern int	smr_slabwaiter_init();
215*0Sstevel@tonic-gate extern void	smr_slabwaiter_deinit();
216*0Sstevel@tonic-gate extern int	smr_slabwaiter_abort(int domid, int serrno);
217*0Sstevel@tonic-gate extern smr_slab_t *smr_slaballoc_get(int domid, caddr_t bufp,
218*0Sstevel@tonic-gate 					caddr_t ebufp);
219*0Sstevel@tonic-gate extern int	smr_slabpool_init(size_t reserved_size,
220*0Sstevel@tonic-gate 					caddr_t *reserved_area);
221*0Sstevel@tonic-gate extern void 	smr_slabpool_deinit();
222*0Sstevel@tonic-gate extern void	smr_remap(struct as *as, register caddr_t vaddr,
223*0Sstevel@tonic-gate 					register pfn_t new_pfn, uint_t mblen);
224*0Sstevel@tonic-gate 
225*0Sstevel@tonic-gate extern int	idn_slab_prealloc;
226*0Sstevel@tonic-gate 
227*0Sstevel@tonic-gate #ifdef	__cplusplus
228*0Sstevel@tonic-gate }
229*0Sstevel@tonic-gate #endif
230*0Sstevel@tonic-gate 
231*0Sstevel@tonic-gate #endif /* _SYS_IDN_SMR_H */
232