sad_conf.c (50110644) sad_conf.c (f4b3ec61)
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 (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 5 unchanged lines hidden (view full) ---

14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
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 (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 5 unchanged lines hidden (view full) ---

14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26#pragma ident "%Z%%M% %I% %E% SMI"
27
28/*
29 * Config dependent data structures for the Streams Administrative Driver
30 * (or "Ballad of the SAD Cafe").
31 */
32#include <sys/types.h>
33#include <sys/conf.h>
34#include <sys/stream.h>
35#include <sys/strsubr.h>
36#include <sys/sad.h>
37#include <sys/kmem.h>
38#include <sys/sysmacros.h>
39
23 * Use is subject to license terms.
24 */
25
26#pragma ident "%Z%%M% %I% %E% SMI"
27
28/*
29 * Config dependent data structures for the Streams Administrative Driver
30 * (or "Ballad of the SAD Cafe").
31 */
32#include <sys/types.h>
33#include <sys/conf.h>
34#include <sys/stream.h>
35#include <sys/strsubr.h>
36#include <sys/sad.h>
37#include <sys/kmem.h>
38#include <sys/sysmacros.h>
39
40struct saddev *saddev; /* sad device array */
41int sadcnt = 16; /* number of sad devices */
42
43/*
44 * Currently we store all the sad data in a hash table keyed by major
45 * number. This is far from ideal. It means that if a single device
46 * starts using lots of SAP_ONE entries all its entries will hash
47 * to the same bucket and we'll get very long chains for that bucket.
48 *
49 * Unfortunately, it's not possible to hash by a different key or to easily
50 * break up our one hash into seperate hashs. The reason is because

--- 13 unchanged lines hidden (view full) ---

64 * nodes indexed by minor numbers. perhaps two separate tables,
65 * one for each type of autopush nodes.
66 *
67 * Note that regardless of how the data is stored there can't be any overlap
68 * stored between autopush nodes. For example, if there is a SAP_ALL node
69 * for a given major number then there can't be any SAP_RANGE or SAP_ONE
70 * nodes for that same major number.
71 */
40/*
41 * Currently we store all the sad data in a hash table keyed by major
42 * number. This is far from ideal. It means that if a single device
43 * starts using lots of SAP_ONE entries all its entries will hash
44 * to the same bucket and we'll get very long chains for that bucket.
45 *
46 * Unfortunately, it's not possible to hash by a different key or to easily
47 * break up our one hash into seperate hashs. The reason is because

--- 13 unchanged lines hidden (view full) ---

61 * nodes indexed by minor numbers. perhaps two separate tables,
62 * one for each type of autopush nodes.
63 *
64 * Note that regardless of how the data is stored there can't be any overlap
65 * stored between autopush nodes. For example, if there is a SAP_ALL node
66 * for a given major number then there can't be any SAP_RANGE or SAP_ONE
67 * nodes for that same major number.
68 */
72kmutex_t sad_lock; /* protects sad_hash */
73static mod_hash_t *sad_hash;
74static size_t sad_hash_nchains = 127;
75
76/*
77 * Private Internal Interfaces
78 */
79/*ARGSUSED*/
80static uint_t
81sad_hash_alg(void *hash_data, mod_hash_key_t key)
82{

--- 119 unchanged lines hidden (view full) ---

202 struct autopush *ap_new;
203
204 ap_new = kmem_zalloc(sizeof (struct autopush), KM_SLEEP);
205 ap_new->ap_cnt = 1;
206 return (ap_new);
207}
208
209void
69
70/*
71 * Private Internal Interfaces
72 */
73/*ARGSUSED*/
74static uint_t
75sad_hash_alg(void *hash_data, mod_hash_key_t key)
76{

--- 119 unchanged lines hidden (view full) ---

196 struct autopush *ap_new;
197
198 ap_new = kmem_zalloc(sizeof (struct autopush), KM_SLEEP);
199 ap_new->ap_cnt = 1;
200 return (ap_new);
201}
202
203void
210sad_ap_rele(struct autopush *ap)
204sad_ap_rele(struct autopush *ap, str_stack_t *ss)
211{
205{
212 mutex_enter(&sad_lock);
206 mutex_enter(&ss->ss_sad_lock);
213 ASSERT(ap->ap_cnt > 0);
214 if (--(ap->ap_cnt) == 0) {
207 ASSERT(ap->ap_cnt > 0);
208 if (--(ap->ap_cnt) == 0) {
215 mutex_exit(&sad_lock);
209 mutex_exit(&ss->ss_sad_lock);
216 kmem_free(ap, sizeof (struct autopush));
217 } else {
210 kmem_free(ap, sizeof (struct autopush));
211 } else {
218 mutex_exit(&sad_lock);
212 mutex_exit(&ss->ss_sad_lock);
219 }
220}
221
222void
213 }
214}
215
216void
223sad_ap_insert(struct autopush *ap)
217sad_ap_insert(struct autopush *ap, str_stack_t *ss)
224{
218{
225 ASSERT(MUTEX_HELD(&sad_lock));
219 ASSERT(MUTEX_HELD(&ss->ss_sad_lock));
226 ASSERT(sad_apc_verify(&ap->ap_common) == 0);
220 ASSERT(sad_apc_verify(&ap->ap_common) == 0);
227 ASSERT(sad_ap_find(&ap->ap_common) == NULL);
228 (void) mod_hash_insert(sad_hash, &ap->ap_common, ap);
221 ASSERT(sad_ap_find(&ap->ap_common, ss) == NULL);
222 (void) mod_hash_insert(ss->ss_sad_hash, &ap->ap_common, ap);
229}
230
231void
223}
224
225void
232sad_ap_remove(struct autopush *ap)
226sad_ap_remove(struct autopush *ap, str_stack_t *ss)
233{
234 struct autopush *ap_removed = NULL;
235
227{
228 struct autopush *ap_removed = NULL;
229
236 ASSERT(MUTEX_HELD(&sad_lock));
237 (void) mod_hash_remove(sad_hash, &ap->ap_common,
230 ASSERT(MUTEX_HELD(&ss->ss_sad_lock));
231 (void) mod_hash_remove(ss->ss_sad_hash, &ap->ap_common,
238 (mod_hash_val_t *)&ap_removed);
239 ASSERT(ap == ap_removed);
240}
241
242struct autopush *
232 (mod_hash_val_t *)&ap_removed);
233 ASSERT(ap == ap_removed);
234}
235
236struct autopush *
243sad_ap_find(struct apcommon *apc)
237sad_ap_find(struct apcommon *apc, str_stack_t *ss)
244{
245 struct autopush *ap_result = NULL;
246
238{
239 struct autopush *ap_result = NULL;
240
247 ASSERT(MUTEX_HELD(&sad_lock));
241 ASSERT(MUTEX_HELD(&ss->ss_sad_lock));
248 ASSERT(sad_apc_verify(apc) == 0);
249
242 ASSERT(sad_apc_verify(apc) == 0);
243
250 (void) mod_hash_find(sad_hash, apc, (mod_hash_val_t *)&ap_result);
244 (void) mod_hash_find(ss->ss_sad_hash, apc,
245 (mod_hash_val_t *)&ap_result);
251 if (ap_result != NULL)
252 ap_result->ap_cnt++;
253 return (ap_result);
254}
255
256struct autopush *
246 if (ap_result != NULL)
247 ap_result->ap_cnt++;
248 return (ap_result);
249}
250
251struct autopush *
257sad_ap_find_by_dev(dev_t dev)
252sad_ap_find_by_dev(dev_t dev, str_stack_t *ss)
258{
259 struct apcommon apc;
260 struct autopush *ap_result;
261
253{
254 struct apcommon apc;
255 struct autopush *ap_result;
256
262 ASSERT(MUTEX_NOT_HELD(&sad_lock));
257 ASSERT(MUTEX_NOT_HELD(&ss->ss_sad_lock));
263
264 /* prepare an apcommon structure to search with */
265 apc.apc_cmd = SAP_ONE;
266 apc.apc_major = getmajor(dev);
267 apc.apc_minor = getminor(dev);
268
269 /*
270 * the following values must be set but initialized to have a
271 * valid apcommon struct, but since we're only using this
272 * structure to do a query the values are never actually used.
273 */
274 apc.apc_npush = 1;
275 apc.apc_lastminor = 0;
276
258
259 /* prepare an apcommon structure to search with */
260 apc.apc_cmd = SAP_ONE;
261 apc.apc_major = getmajor(dev);
262 apc.apc_minor = getminor(dev);
263
264 /*
265 * the following values must be set but initialized to have a
266 * valid apcommon struct, but since we're only using this
267 * structure to do a query the values are never actually used.
268 */
269 apc.apc_npush = 1;
270 apc.apc_lastminor = 0;
271
277 mutex_enter(&sad_lock);
278 ap_result = sad_ap_find(&apc);
279 mutex_exit(&sad_lock);
272 mutex_enter(&ss->ss_sad_lock);
273 ap_result = sad_ap_find(&apc, ss);
274 mutex_exit(&ss->ss_sad_lock);
280 return (ap_result);
281}
282
283void
275 return (ap_result);
276}
277
278void
284sad_initspace(void)
279sad_initspace(str_stack_t *ss)
285{
280{
286 saddev = kmem_zalloc(sadcnt * sizeof (struct saddev), KM_SLEEP);
287 sad_hash = mod_hash_create_extended("sad_hash",
288 sad_hash_nchains, mod_hash_null_keydtor, mod_hash_null_valdtor,
281 mutex_init(&ss->ss_sad_lock, NULL, MUTEX_DEFAULT, NULL);
282 ss->ss_sad_hash_nchains = 127;
283 ss->ss_sadcnt = 16;
284
285 ss->ss_saddev = kmem_zalloc(ss->ss_sadcnt * sizeof (struct saddev),
286 KM_SLEEP);
287 ss->ss_sad_hash = mod_hash_create_extended("sad_hash",
288 ss->ss_sad_hash_nchains, mod_hash_null_keydtor,
289 mod_hash_null_valdtor,
289 sad_hash_alg, NULL, sad_hash_keycmp, KM_SLEEP);
290}
290 sad_hash_alg, NULL, sad_hash_keycmp, KM_SLEEP);
291}
292
293void
294sad_freespace(str_stack_t *ss)
295{
296 kmem_free(ss->ss_saddev, ss->ss_sadcnt * sizeof (struct saddev));
297 ss->ss_saddev = NULL;
298
299 mod_hash_destroy_hash(ss->ss_sad_hash);
300 ss->ss_sad_hash = NULL;
301
302 mutex_destroy(&ss->ss_sad_lock);
303}