xref: /titanic_50/usr/src/uts/sun4u/starfire/sys/idn_smr.h (revision e0731422366620894c16c1ee6515551c5f00733d)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate /*
237c478bd9Sstevel@tonic-gate  * Copyright (c) 1999 by Sun Microsystems, Inc.
247c478bd9Sstevel@tonic-gate  * All rights reserved.
257c478bd9Sstevel@tonic-gate  *
267c478bd9Sstevel@tonic-gate  * Inter-Domain Network - SMR support.
277c478bd9Sstevel@tonic-gate  */
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #ifndef	_SYS_IDN_SMR_H
307c478bd9Sstevel@tonic-gate #define	_SYS_IDN_SMR_H
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h>
337c478bd9Sstevel@tonic-gate 
347c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
357c478bd9Sstevel@tonic-gate extern "C" {
367c478bd9Sstevel@tonic-gate #endif
377c478bd9Sstevel@tonic-gate 
387c478bd9Sstevel@tonic-gate typedef uint_t	smr_offset_t;
397c478bd9Sstevel@tonic-gate 
407c478bd9Sstevel@tonic-gate #define	IDN_NIL_SMROFFSET		((smr_offset_t)-1)
417c478bd9Sstevel@tonic-gate 
427c478bd9Sstevel@tonic-gate /*
437c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
447c478bd9Sstevel@tonic-gate  * Data in the SMR is automatically aligned on 64 byte boundaries due
457c478bd9Sstevel@tonic-gate  * to the large IDN_SMR_BUFSIZE, however the streams buffers may not be
467c478bd9Sstevel@tonic-gate  * so we bump them in order to allow us to align appropriately and thus
477c478bd9Sstevel@tonic-gate  * maximize bcopy performance.
487c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
497c478bd9Sstevel@tonic-gate  */
507c478bd9Sstevel@tonic-gate #define	IDN_ALIGNSIZE		64
517c478bd9Sstevel@tonic-gate /*
527c478bd9Sstevel@tonic-gate  * Align the pointer "p" to the same relative offset as the reference
537c478bd9Sstevel@tonic-gate  * pointer "r" within IDN_ALIGNSIZE bytes.
547c478bd9Sstevel@tonic-gate  */
557c478bd9Sstevel@tonic-gate #define	IDN_ALIGNPTR(p, r)	((uintptr_t)(p) + (((uintptr_t)(r) - \
567c478bd9Sstevel@tonic-gate 					(uintptr_t)(p)) & \
577c478bd9Sstevel@tonic-gate 					(uintptr_t)(IDN_ALIGNSIZE - 1)))
587c478bd9Sstevel@tonic-gate 
597c478bd9Sstevel@tonic-gate #define	IDN_OFFSET2ADDR(off)	((caddr_t)((uintptr_t)(off) + \
607c478bd9Sstevel@tonic-gate 					(uintptr_t)idn.smr.vaddr))
617c478bd9Sstevel@tonic-gate #define	IDN_ADDR2OFFSET(va)	((smr_offset_t)((caddr_t)(va) - idn.smr.vaddr))
627c478bd9Sstevel@tonic-gate #define	IDN_BUF2DATA(b, o)	((caddr_t)((uintptr_t)(b) + (uintptr_t)(o)))
637c478bd9Sstevel@tonic-gate #define	IDN_BUF2HDR(b)		((smr_pkthdr_t *)(b))
647c478bd9Sstevel@tonic-gate 
65*e0731422SRichard Lowe #define	IDN_CKSUM_PKT_COUNT	(offsetof(smr_pkthdr_t, b_cksum) / 2)
66*e0731422SRichard Lowe 
677c478bd9Sstevel@tonic-gate #define	IDN_CKSUM_PKT(h)	\
687c478bd9Sstevel@tonic-gate 		(IDN_CHECKSUM ? \
697c478bd9Sstevel@tonic-gate 		idn_cksum((ushort_t *)(h), IDN_CKSUM_PKT_COUNT) : 0)
707c478bd9Sstevel@tonic-gate 
717c478bd9Sstevel@tonic-gate typedef struct smr_pkthdr {
727c478bd9Sstevel@tonic-gate 	uint_t		b_netaddr;
737c478bd9Sstevel@tonic-gate 	uint_t		b_netports;
747c478bd9Sstevel@tonic-gate 	smr_offset_t	b_offset;
757c478bd9Sstevel@tonic-gate 	int		b_length;
767c478bd9Sstevel@tonic-gate 
777c478bd9Sstevel@tonic-gate 	ushort_t	b_rawio;
787c478bd9Sstevel@tonic-gate 	ushort_t	b_cksum;
797c478bd9Sstevel@tonic-gate 	smr_offset_t	b_next;		/* used during reclamation */
807c478bd9Sstevel@tonic-gate } smr_pkthdr_t;
817c478bd9Sstevel@tonic-gate 
827c478bd9Sstevel@tonic-gate /*
837c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
847c478bd9Sstevel@tonic-gate  * IDN Slab related definitions.
857c478bd9Sstevel@tonic-gate  *
867c478bd9Sstevel@tonic-gate  * Domains are allocated SMR buffers in slabs.  Slaves keep track of
877c478bd9Sstevel@tonic-gate  * their own slabs in their respective idn_domain entry.  The Master
887c478bd9Sstevel@tonic-gate  * keeps track of slave slabs via their respective idn_domain entry.
897c478bd9Sstevel@tonic-gate  * The global slab pools representing all of the SMR and managed by
907c478bd9Sstevel@tonic-gate  * the master are maintained in the idn_global structure.
917c478bd9Sstevel@tonic-gate  *
927c478bd9Sstevel@tonic-gate  * The minimum number of slabs is chosen so that there is at least
937c478bd9Sstevel@tonic-gate  * one slab available for every possible domain that might be attached.
947c478bd9Sstevel@tonic-gate  *
957c478bd9Sstevel@tonic-gate  * NOTE: idn_slab_bufcount * idn_smr_bufsize should be on a 64-byte
967c478bd9Sstevel@tonic-gate  *	 (IDN_ALIGNSIZE) boundary for maximum bcopy performance.
977c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
987c478bd9Sstevel@tonic-gate  */
997c478bd9Sstevel@tonic-gate #define	IDN_SLAB_BUFCOUNT	idn_slab_bufcount
1007c478bd9Sstevel@tonic-gate #define	IDN_SLAB_SIZE		(IDN_SLAB_BUFCOUNT * IDN_SMR_BUFSIZE)
1017c478bd9Sstevel@tonic-gate #define	IDN_SLAB_MAXNUM		(idn.slabpool->ntotslabs)
1027c478bd9Sstevel@tonic-gate #define	IDN_SLAB_MINPERPOOL	3
1037c478bd9Sstevel@tonic-gate #define	IDN_SLAB_MINTOTAL	idn_slab_mintotal
1047c478bd9Sstevel@tonic-gate #define	IDN_SLAB_PREALLOC	idn_slab_prealloc
1057c478bd9Sstevel@tonic-gate 
1067c478bd9Sstevel@tonic-gate /*
1077c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
1087c478bd9Sstevel@tonic-gate  * Maximum number of slabs per domain the master will
1097c478bd9Sstevel@tonic-gate  * allow to be allocated.  Further requests simply result
1107c478bd9Sstevel@tonic-gate  * in a failed allocation.
1117c478bd9Sstevel@tonic-gate  * Nominal value is 1/6 of the total available (~10).
1127c478bd9Sstevel@tonic-gate  * Maximum number of bufs a domain can expect based on
1137c478bd9Sstevel@tonic-gate  * IDN_SLAB_MAXPERDOMAIN.
1147c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
1157c478bd9Sstevel@tonic-gate  */
1167c478bd9Sstevel@tonic-gate #define	IDN_SLAB_MAXPERDOMAIN	idn_slab_maxperdomain
1177c478bd9Sstevel@tonic-gate #define	IDN_BUF_MAXPERDOMAIN	(IDN_SLAB_MAXPERDOMAIN * IDN_SLAB_BUFCOUNT)
1187c478bd9Sstevel@tonic-gate /*
1197c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
1207c478bd9Sstevel@tonic-gate  * If the total number of available slabs managed by the master
1217c478bd9Sstevel@tonic-gate  * goes below this minimum total threshold, then the master kicks
1227c478bd9Sstevel@tonic-gate  * off a reap request to all domains to check for free slabs and
1237c478bd9Sstevel@tonic-gate  * to give them up.  For performance reasons, domains do not
1247c478bd9Sstevel@tonic-gate  * automatically flush out free slabs.  They rely on the master
1257c478bd9Sstevel@tonic-gate  * to tell them to look for some.
1267c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
1277c478bd9Sstevel@tonic-gate  */
1287c478bd9Sstevel@tonic-gate #define	IDN_SLAB_THRESHOLD	MIN(MAX_DOMAINS, \
1297c478bd9Sstevel@tonic-gate 					(IDN_SLAB_MINTOTAL + \
1307c478bd9Sstevel@tonic-gate 					(IDN_SLAB_MINTOTAL / 5)))
1317c478bd9Sstevel@tonic-gate #define	IDN_REAP_INTERVAL	(2 * hz)
1327c478bd9Sstevel@tonic-gate 
1337c478bd9Sstevel@tonic-gate #define	SMR_SLABPOOL_HASH(d)		((d) % idn.slabpool->npools)
1347c478bd9Sstevel@tonic-gate #define	SMR_SLABPOOL_HASHSTEP(p)	(((p)+4) % idn.slabpool->npools)
1357c478bd9Sstevel@tonic-gate #define	SMR_SLAB_HASH(p, d) \
1367c478bd9Sstevel@tonic-gate 				((d) % idn.slabpool->pool[p].nslabs)
1377c478bd9Sstevel@tonic-gate #define	SMR_SLAB_HASHSTEP(p, s) \
1387c478bd9Sstevel@tonic-gate 				(((s)+1) % idn.slabpool->pool[p].nslabs)
1397c478bd9Sstevel@tonic-gate 
1407c478bd9Sstevel@tonic-gate /*
1417c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
1427c478bd9Sstevel@tonic-gate  * There is one smr_slabbuf for each buffer in the respective slab.
1437c478bd9Sstevel@tonic-gate  *
1447c478bd9Sstevel@tonic-gate  * sb_domid	Domainid currently owning respective buffer.
1457c478bd9Sstevel@tonic-gate  *		Local domains use this field to determine what buffers
1467c478bd9Sstevel@tonic-gate  *		are outstanding at which domains.  The master uses this
1477c478bd9Sstevel@tonic-gate  *		field to know which domain owns given slab.
1487c478bd9Sstevel@tonic-gate  * sb_bufp	Actual pointer to (VA) buffer.
1497c478bd9Sstevel@tonic-gate  * sb_next	Used to manage free and in-use lists.
1507c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
1517c478bd9Sstevel@tonic-gate  */
1527c478bd9Sstevel@tonic-gate typedef struct smr_slabbuf {
1537c478bd9Sstevel@tonic-gate 	int		sb_domid;
1547c478bd9Sstevel@tonic-gate 	caddr_t		sb_bufp;
1557c478bd9Sstevel@tonic-gate 	struct smr_slabbuf	*sb_next;
1567c478bd9Sstevel@tonic-gate } smr_slabbuf_t;
1577c478bd9Sstevel@tonic-gate 
1587c478bd9Sstevel@tonic-gate /*
1597c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
1607c478bd9Sstevel@tonic-gate  * There is one smr_slab per slab of buffers.
1617c478bd9Sstevel@tonic-gate  *
1627c478bd9Sstevel@tonic-gate  * sl_next	List of slabs allocated to same requester.
1637c478bd9Sstevel@tonic-gate  * sl_start	Base virtual address (SMR) of slab.
1647c478bd9Sstevel@tonic-gate  * sl_end	Points to byte immediately following end of slab.
1657c478bd9Sstevel@tonic-gate  * sl_lock	Atomic lock used to manage free/inuse lists.
1667c478bd9Sstevel@tonic-gate  * sl_domid	Used by Master to indicate which slave owns
1677c478bd9Sstevel@tonic-gate  *		respective slab.
1687c478bd9Sstevel@tonic-gate  * sl_free	Freelist of available buffers.
1697c478bd9Sstevel@tonic-gate  * sl_inuse	List of buffers currently allocated and in-use.
1707c478bd9Sstevel@tonic-gate  * sl_head	Pointer to memory allocated to hold smr_slabbuf_t's.
1717c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
1727c478bd9Sstevel@tonic-gate  */
1737c478bd9Sstevel@tonic-gate typedef struct smr_slab {
1747c478bd9Sstevel@tonic-gate 	struct smr_slab	*sl_next;
1757c478bd9Sstevel@tonic-gate 	caddr_t		sl_start,
1767c478bd9Sstevel@tonic-gate 			sl_end;
1777c478bd9Sstevel@tonic-gate 	lock_t		sl_lock;
1787c478bd9Sstevel@tonic-gate 
1797c478bd9Sstevel@tonic-gate 	union {
1807c478bd9Sstevel@tonic-gate 		int	_sl_domid;
1817c478bd9Sstevel@tonic-gate 		struct {
1827c478bd9Sstevel@tonic-gate 			smr_slabbuf_t	*_sl_free;
1837c478bd9Sstevel@tonic-gate 			smr_slabbuf_t	*_sl_inuse;
1847c478bd9Sstevel@tonic-gate 			smr_slabbuf_t	*_sl_head;
1857c478bd9Sstevel@tonic-gate 		} _s;
1867c478bd9Sstevel@tonic-gate 	} _u;
1877c478bd9Sstevel@tonic-gate } smr_slab_t;
1887c478bd9Sstevel@tonic-gate 
1897c478bd9Sstevel@tonic-gate #define	sl_domid	_u._sl_domid
1907c478bd9Sstevel@tonic-gate #define	sl_free		_u._s._sl_free
1917c478bd9Sstevel@tonic-gate #define	sl_inuse	_u._s._sl_inuse
1927c478bd9Sstevel@tonic-gate #define	sl_head		_u._s._sl_head
1937c478bd9Sstevel@tonic-gate 
1947c478bd9Sstevel@tonic-gate /*
1957c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
1967c478bd9Sstevel@tonic-gate  * io/idn_smr.c
1977c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
1987c478bd9Sstevel@tonic-gate  */
1997c478bd9Sstevel@tonic-gate extern void	smr_slab_reap(int domid, int *nslabs);
2007c478bd9Sstevel@tonic-gate extern int	smr_slab_alloc(int domid, smr_slab_t **spp);
2017c478bd9Sstevel@tonic-gate extern void 	smr_slab_free(int domid, smr_slab_t *sp);
2027c478bd9Sstevel@tonic-gate extern void	smr_slab_garbage_collection(smr_slab_t *sp);
2037c478bd9Sstevel@tonic-gate extern int	smr_slab_busy(smr_slab_t *sp);
2047c478bd9Sstevel@tonic-gate extern int 	smr_buf_alloc(int domid, uint_t len, caddr_t *bufpp);
2057c478bd9Sstevel@tonic-gate extern int 	smr_buf_free(int domid, caddr_t bufp, uint_t len);
2067c478bd9Sstevel@tonic-gate extern int	smr_buf_free_locked(int domid, caddr_t bufp, uint_t len);
2077c478bd9Sstevel@tonic-gate extern int 	smr_buf_free_all(int domid);
2087c478bd9Sstevel@tonic-gate extern int 	smr_buf_reclaim(int domid, int nbufs);
2097c478bd9Sstevel@tonic-gate extern int 	smr_slaballoc_put(int domid, smr_slab_t *sp, int forceflag,
2107c478bd9Sstevel@tonic-gate 					int serrno);
2117c478bd9Sstevel@tonic-gate extern void	smr_alloc_buflist(smr_slab_t *sp);
2127c478bd9Sstevel@tonic-gate extern void	smr_free_buflist(smr_slab_t *sp);
2137c478bd9Sstevel@tonic-gate extern int	smr_slabwaiter_init();
2147c478bd9Sstevel@tonic-gate extern void	smr_slabwaiter_deinit();
2157c478bd9Sstevel@tonic-gate extern int	smr_slabwaiter_abort(int domid, int serrno);
2167c478bd9Sstevel@tonic-gate extern smr_slab_t *smr_slaballoc_get(int domid, caddr_t bufp,
2177c478bd9Sstevel@tonic-gate 					caddr_t ebufp);
2187c478bd9Sstevel@tonic-gate extern int	smr_slabpool_init(size_t reserved_size,
2197c478bd9Sstevel@tonic-gate 					caddr_t *reserved_area);
2207c478bd9Sstevel@tonic-gate extern void 	smr_slabpool_deinit();
2217c478bd9Sstevel@tonic-gate extern void	smr_remap(struct as *as, register caddr_t vaddr,
2227c478bd9Sstevel@tonic-gate 					register pfn_t new_pfn, uint_t mblen);
2237c478bd9Sstevel@tonic-gate 
2247c478bd9Sstevel@tonic-gate extern int	idn_slab_prealloc;
2257c478bd9Sstevel@tonic-gate 
2267c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
2277c478bd9Sstevel@tonic-gate }
2287c478bd9Sstevel@tonic-gate #endif
2297c478bd9Sstevel@tonic-gate 
2307c478bd9Sstevel@tonic-gate #endif /* _SYS_IDN_SMR_H */
231