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 */
|