xref: /titanic_41/usr/src/uts/common/sys/multidata_impl.h (revision bdb9230ac765cb7af3fc1f4119caf2c5720dceb3)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #ifndef _SYS_MULTIDATA_IMPL_H
28 #define	_SYS_MULTIDATA_IMPL_H
29 
30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 #ifdef	__cplusplus
33 extern "C" {
34 #endif
35 
36 /*
37  * Multidata: implementation-private data structure and declarations.
38  */
39 
40 /*
41  * Structure used for insque/remque circular list operations.
42  */
43 typedef struct ql_s {
44 	struct ql_s *ql_next;	/* pointer to next list element */
45 	struct ql_s *ql_prev;	/* pointer to previous list element */
46 } ql_t;
47 
48 #define	QL_INIT(q) {				\
49 	((ql_t *)(q))->ql_next = (ql_t *)(q);	\
50 	((ql_t *)(q))->ql_prev = (ql_t *)(q);	\
51 }
52 
53 typedef struct pdesc_slab_s pdesc_slab_t;
54 
55 /*
56  * Attribute hash bucket structure.
57  */
58 typedef struct patbkt_s {
59 	kmutex_t pbkt_lock;	/* per-bucket lock */
60 	ql_t	pbkt_pattr_q;	/* list of attributes */
61 	uint_t	pbkt_tbl_sz;	/* table size (if this is first bucket) */
62 } patbkt_t;
63 
64 /*
65  * Attribute structure.
66  */
67 #define	PATTR_MAGIC	0x50615472	/* "PaTr" */
68 
69 struct pattr_s {
70 	pattr_t *pat_next;	/* pointer to next attribute in bucket */
71 	pattr_t *pat_prev;	/* pointer to previous attribute in bucket */
72 
73 	uint_t pat_magic;	/* set to PATTR_MAGIC */
74 
75 	kmutex_t *pat_lock;	/* pointer to per-bucket lock */
76 	multidata_t *pat_mmd;	/* back pointer to Multidata */
77 	uint_t	pat_buflen;	/* length of this structure + attribute */
78 	uint_t	pat_type;	/* type of encapsulated attribute */
79 	uint_t	pat_flags;	/* misc. flags */
80 };
81 
82 /*
83  * Values for pat_flags.
84  */
85 #define	PATTR_REM_DEFER	0x1	/* entry is marked unusable but still exists */
86 #define	PATTR_PERSIST	0x2	/* entry can't be removed */
87 
88 #define	Q2PATTR(p)	\
89 	((pattr_t *)((caddr_t)(p) - offsetof(pattr_t, pat_next)))
90 
91 /*
92  * Packet descriptor structure.
93  */
94 #define	PDESC_MAGIC	0x506b5464	/* "PkTd" */
95 
96 struct pdesc_s {
97 	pdesc_t	*pd_next;	/* pointer to next descriptor */
98 	pdesc_t	*pd_prev;	/* pointer to previous descriptor */
99 
100 	uint_t pd_magic;	/* set to PDESC_MAGIC */
101 
102 	pdesc_slab_t *pd_slab;	/* back pointer to descriptor slab */
103 	patbkt_t *pd_pattbl;	/* hash table of local attributes */
104 
105 	pdescinfo_t pd_pdi;	/* embedded descriptor info structure */
106 
107 #define	pd_flags	pd_pdi.flags
108 };
109 
110 /*
111  * Additional internal flags for pd_flags (see multidata.h for the rest).
112  */
113 #define	PDESC_REM_DEFER	0x1000	/* entry is marked unusable but still exists */
114 #define	PDESC_HAS_REF	(PDESC_HBUF_REF | PDESC_PBUF_REF)
115 
116 #define	Q2PD(p)		\
117 	((pdesc_t *)((caddr_t)(p) - offsetof(pdesc_t, pd_next)))
118 
119 #define	PDI_COPY(pd_src, pd_dst) {				\
120 	(pd_dst)->flags = (pd_src)->flags & PDESC_HAS_REF;	\
121 	if ((pd_dst)->flags & PDESC_HBUF_REF) {			\
122 		(pd_dst)->hdr_base = (pd_src)->hdr_base;	\
123 		(pd_dst)->hdr_rptr = (pd_src)->hdr_rptr;	\
124 		(pd_dst)->hdr_wptr = (pd_src)->hdr_wptr;	\
125 		(pd_dst)->hdr_lim = (pd_src)->hdr_lim;		\
126 	} else {						\
127 		(pd_dst)->hdr_base = NULL;			\
128 		(pd_dst)->hdr_rptr = NULL;			\
129 		(pd_dst)->hdr_wptr = NULL;			\
130 		(pd_dst)->hdr_lim = NULL;			\
131 	}							\
132 								\
133 	if ((pd_dst)->flags & PDESC_PBUF_REF) {			\
134 		int i;						\
135 								\
136 		(pd_dst)->pld_cnt = (pd_src)->pld_cnt;		\
137 		for (i = 0; i < (pd_dst)->pld_cnt; i++) {	\
138 			(pd_dst)->pld_ary[i].pld_pbuf_idx =	\
139 			    (pd_src)->pld_ary[i].pld_pbuf_idx;	\
140 			(pd_dst)->pld_ary[i].pld_rptr =		\
141 			    (pd_src)->pld_ary[i].pld_rptr;	\
142 			(pd_dst)->pld_ary[i].pld_wptr =		\
143 			    (pd_src)->pld_ary[i].pld_wptr;	\
144 		}						\
145 	} else {						\
146 		(pd_dst)->pld_cnt = 0;				\
147 	}							\
148 }
149 
150 /*
151  * Packet descriptor slab structure.
152  */
153 struct pdesc_slab_s {
154 	pdesc_slab_t *pds_next;	/* pointer to next descriptor slab */
155 	pdesc_slab_t *pds_prev;	/* pointer to previous descriptor slab */
156 
157 	multidata_t *pds_mmd;	/* back pointer to Multidata */
158 	uint_t	pds_used;	/* always-increasing index to array */
159 	uint_t	pds_sz;		/* size of descriptor array */
160 
161 	pdesc_t	pds_free_desc[1]; /* array of available descriptors */
162 };
163 
164 #define	Q2PDSLAB(p)	\
165 	((pdesc_slab_t *)((caddr_t)(p) - offsetof(pdesc_slab_t, pds_next)))
166 
167 #define	PDESC_SLAB_SIZE(npd)  \
168 	((size_t)(&((pdesc_slab_t *)0)->pds_free_desc[npd]))
169 
170 /*
171  * Multidata metadata structure.
172  */
173 #define	MULTIDATA_MAGIC	0x4d645461	/* "MdTa" */
174 
175 struct multidata_s {
176 	uint_t	mmd_magic;	/* set to MULTIDATA_MAGIC */
177 
178 	dblk_t	*mmd_dp;	/* back pointer to wrapper dblk structure */
179 	mblk_t	*mmd_hbuf;	/* pointer to header buffer mblk */
180 
181 	patbkt_t *mmd_pattbl;	/* hash table of global attributes */
182 
183 	kmutex_t mmd_pd_slab_lock; /* lock to protect the following items */
184 	uint_t	mmd_pbuf_cnt;	/* number of data buffer */
185 	mblk_t	*mmd_pbuf[MULTIDATA_MAX_PBUFS];	/* data buffer mblk(s) */
186 	ql_t	mmd_pd_slab_q;	/* list of packet descriptor slabs */
187 	ql_t	mmd_pd_q;	/* list of packet descriptors */
188 	uint_t	mmd_slab_cnt;	/* number of packet descriptor slabs */
189 	uint_t	mmd_pd_cnt;	/* number of in-use packet desciptors */
190 	uint_t	mmd_hbuf_ref;	/* descriptors referring to header buffer */
191 	uint_t	mmd_pbuf_ref;	/* descriptors referring to payload buffer(s) */
192 };
193 
194 #ifdef _KERNEL
195 
196 extern void mmd_init(void);
197 extern mblk_t *mmd_copy(mblk_t *, int);
198 
199 #endif /* _KERNEL */
200 
201 #ifdef	__cplusplus
202 }
203 #endif
204 
205 #endif	/* _SYS_MULTIDATA_IMPL_H */
206