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