summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys/multidata_impl.h
blob: 05589c6f0334a6ff69bbbe7c155986d0c70c5c56 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef _SYS_MULTIDATA_IMPL_H
#define	_SYS_MULTIDATA_IMPL_H

#pragma ident	"%Z%%M%	%I%	%E% SMI"

#ifdef	__cplusplus
extern "C" {
#endif

/*
 * Multidata: implementation-private data structure and declarations.
 */

/*
 * Structure used for insque/remque circular list operations.
 */
typedef struct ql_s {
	struct ql_s *ql_next;	/* pointer to next list element */
	struct ql_s *ql_prev;	/* pointer to previous list element */
} ql_t;

#define	QL_INIT(q) {				\
	((ql_t *)(q))->ql_next = (ql_t *)(q);	\
	((ql_t *)(q))->ql_prev = (ql_t *)(q);	\
}

typedef struct pdesc_slab_s pdesc_slab_t;

/*
 * Attribute hash bucket structure.
 */
typedef struct patbkt_s {
	kmutex_t pbkt_lock;	/* per-bucket lock */
	ql_t	pbkt_pattr_q;	/* list of attributes */
	uint_t	pbkt_tbl_sz;	/* table size (if this is first bucket) */
} patbkt_t;

/*
 * Attribute structure.
 */
#define	PATTR_MAGIC	0x50615472	/* "PaTr" */

struct pattr_s {
	pattr_t *pat_next;	/* pointer to next attribute in bucket */
	pattr_t *pat_prev;	/* pointer to previous attribute in bucket */

	uint_t pat_magic;	/* set to PATTR_MAGIC */

	kmutex_t *pat_lock;	/* pointer to per-bucket lock */
	multidata_t *pat_mmd;	/* back pointer to Multidata */
	uint_t	pat_buflen;	/* length of this structure + attribute */
	uint_t	pat_type;	/* type of encapsulated attribute */
	uint_t	pat_flags;	/* misc. flags */
};

/*
 * Values for pat_flags.
 */
#define	PATTR_REM_DEFER	0x1	/* entry is marked unusable but still exists */
#define	PATTR_PERSIST	0x2	/* entry can't be removed */

#define	Q2PATTR(p)	\
	((pattr_t *)((caddr_t)(p) - offsetof(pattr_t, pat_next)))

/*
 * Packet descriptor structure.
 */
#define	PDESC_MAGIC	0x506b5464	/* "PkTd" */

struct pdesc_s {
	pdesc_t	*pd_next;	/* pointer to next descriptor */
	pdesc_t	*pd_prev;	/* pointer to previous descriptor */

	uint_t pd_magic;	/* set to PDESC_MAGIC */

	pdesc_slab_t *pd_slab;	/* back pointer to descriptor slab */
	patbkt_t *pd_pattbl;	/* hash table of local attributes */

	pdescinfo_t pd_pdi;	/* embedded descriptor info structure */

#define	pd_flags	pd_pdi.flags
};

/*
 * Additional internal flags for pd_flags (see multidata.h for the rest).
 */
#define	PDESC_REM_DEFER	0x1000	/* entry is marked unusable but still exists */
#define	PDESC_HAS_REF	(PDESC_HBUF_REF | PDESC_PBUF_REF)

#define	Q2PD(p)		\
	((pdesc_t *)((caddr_t)(p) - offsetof(pdesc_t, pd_next)))

#define	PDI_COPY(pd_src, pd_dst) {				\
	(pd_dst)->flags = (pd_src)->flags & PDESC_HAS_REF;	\
	if ((pd_dst)->flags & PDESC_HBUF_REF) {			\
		(pd_dst)->hdr_base = (pd_src)->hdr_base;	\
		(pd_dst)->hdr_rptr = (pd_src)->hdr_rptr;	\
		(pd_dst)->hdr_wptr = (pd_src)->hdr_wptr;	\
		(pd_dst)->hdr_lim = (pd_src)->hdr_lim;		\
	} else {						\
		(pd_dst)->hdr_base = NULL;			\
		(pd_dst)->hdr_rptr = NULL;			\
		(pd_dst)->hdr_wptr = NULL;			\
		(pd_dst)->hdr_lim = NULL;			\
	}							\
								\
	if ((pd_dst)->flags & PDESC_PBUF_REF) {			\
		int i;						\
								\
		(pd_dst)->pld_cnt = (pd_src)->pld_cnt;		\
		for (i = 0; i < (pd_dst)->pld_cnt; i++) {	\
			(pd_dst)->pld_ary[i].pld_pbuf_idx =	\
			    (pd_src)->pld_ary[i].pld_pbuf_idx;	\
			(pd_dst)->pld_ary[i].pld_rptr =		\
			    (pd_src)->pld_ary[i].pld_rptr;	\
			(pd_dst)->pld_ary[i].pld_wptr =		\
			    (pd_src)->pld_ary[i].pld_wptr;	\
		}						\
	} else {						\
		(pd_dst)->pld_cnt = 0;				\
	}							\
}

/*
 * Packet descriptor slab structure.
 */
struct pdesc_slab_s {
	pdesc_slab_t *pds_next;	/* pointer to next descriptor slab */
	pdesc_slab_t *pds_prev;	/* pointer to previous descriptor slab */

	multidata_t *pds_mmd;	/* back pointer to Multidata */
	uint_t	pds_used;	/* always-increasing index to array */
	uint_t	pds_sz;		/* size of descriptor array */

	pdesc_t	pds_free_desc[1]; /* array of available descriptors */
};

#define	Q2PDSLAB(p)	\
	((pdesc_slab_t *)((caddr_t)(p) - offsetof(pdesc_slab_t, pds_next)))

#define	PDESC_SLAB_SIZE(npd)  \
	((size_t)(&((pdesc_slab_t *)0)->pds_free_desc[npd]))

/*
 * Multidata metadata structure.
 */
#define	MULTIDATA_MAGIC	0x4d645461	/* "MdTa" */

struct multidata_s {
	uint_t	mmd_magic;	/* set to MULTIDATA_MAGIC */

	dblk_t	*mmd_dp;	/* back pointer to wrapper dblk structure */
	mblk_t	*mmd_hbuf;	/* pointer to header buffer mblk */

	patbkt_t *mmd_pattbl;	/* hash table of global attributes */

	kmutex_t mmd_pd_slab_lock; /* lock to protect the following items */
	uint_t	mmd_pbuf_cnt;	/* number of data buffer */
	mblk_t	*mmd_pbuf[MULTIDATA_MAX_PBUFS];	/* data buffer mblk(s) */
	ql_t	mmd_pd_slab_q;	/* list of packet descriptor slabs */
	ql_t	mmd_pd_q;	/* list of packet descriptors */
	uint_t	mmd_slab_cnt;	/* number of packet descriptor slabs */
	uint_t	mmd_pd_cnt;	/* number of in-use packet desciptors */
	uint_t	mmd_hbuf_ref;	/* descriptors referring to header buffer */
	uint_t	mmd_pbuf_ref;	/* descriptors referring to payload buffer(s) */
};

#ifdef _KERNEL

extern void mmd_init(void);
extern mblk_t *mmd_copy(mblk_t *, int);

#endif /* _KERNEL */

#ifdef	__cplusplus
}
#endif

#endif	/* _SYS_MULTIDATA_IMPL_H */