xref: /netbsd-src/sys/sys/vmem_impl.h (revision bf9518a62c087d6477d3b1e32480e0f0444d2dfe)
1*bf9518a6Sthorpej /*	$NetBSD: vmem_impl.h,v 1.8 2023/12/03 19:34:08 thorpej Exp $	*/
2cca299e0Spara 
3cca299e0Spara /*-
4cca299e0Spara  * Copyright (c)2006 YAMAMOTO Takashi,
5cca299e0Spara  * All rights reserved.
6cca299e0Spara  *
7cca299e0Spara  * Redistribution and use in source and binary forms, with or without
8cca299e0Spara  * modification, are permitted provided that the following conditions
9cca299e0Spara  * are met:
10cca299e0Spara  * 1. Redistributions of source code must retain the above copyright
11cca299e0Spara  *    notice, this list of conditions and the following disclaimer.
12cca299e0Spara  * 2. Redistributions in binary form must reproduce the above copyright
13cca299e0Spara  *    notice, this list of conditions and the following disclaimer in the
14cca299e0Spara  *    documentation and/or other materials provided with the distribution.
15cca299e0Spara  *
16cca299e0Spara  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17cca299e0Spara  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18cca299e0Spara  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19cca299e0Spara  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20cca299e0Spara  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21cca299e0Spara  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22cca299e0Spara  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23cca299e0Spara  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24cca299e0Spara  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25cca299e0Spara  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26cca299e0Spara  * SUCH DAMAGE.
27cca299e0Spara  */
28cca299e0Spara 
29cca299e0Spara /*
30cca299e0Spara  * Data structures private to vmem.
31cca299e0Spara  */
32cca299e0Spara 
33cca299e0Spara #ifndef _SYS_VMEM_IMPL_H_
34cca299e0Spara #define	_SYS_VMEM_IMPL_H_
35cca299e0Spara 
36cca299e0Spara #include <sys/types.h>
37cca299e0Spara 
38cca299e0Spara #if defined(_KERNEL)
3919d40baaSpara #define	QCACHE
408635cb3dSthorpej #include <sys/pool.h>
41cca299e0Spara #include <sys/vmem.h>
42cca299e0Spara 
43cca299e0Spara #define	LOCK_DECL(name)		\
44cca299e0Spara     kmutex_t name; char lockpad[COHERENCY_UNIT - sizeof(kmutex_t)]
45cca299e0Spara 
46cca299e0Spara #define CONDVAR_DECL(name)	\
47cca299e0Spara     kcondvar_t name
48cca299e0Spara 
49cca299e0Spara #else /* defined(_KERNEL) */
50cca299e0Spara #include <stdio.h>
51cca299e0Spara #include <errno.h>
52cca299e0Spara #include <assert.h>
53cca299e0Spara #include <stdlib.h>
54cca299e0Spara #include <string.h>
55cca299e0Spara 
56cca299e0Spara #include "vmem.h"
57cca299e0Spara 
58cca299e0Spara #define	LOCK_DECL(name)		/* nothing */
59cca299e0Spara #define	CONDVAR_DECL(name)	/* nothing */
60cca299e0Spara #endif /* defined(_KERNEL) */
61cca299e0Spara 
62cca299e0Spara #define	VMEM_MAXORDER		(sizeof(vmem_size_t) * CHAR_BIT)
63cca299e0Spara 
64cca299e0Spara typedef struct vmem_btag bt_t;
65cca299e0Spara 
66471b216bSchristos TAILQ_HEAD(vmem_seglist, vmem_btag);
67cca299e0Spara LIST_HEAD(vmem_freelist, vmem_btag);
68cca299e0Spara LIST_HEAD(vmem_hashlist, vmem_btag);
69cca299e0Spara 
70cca299e0Spara #if defined(QCACHE)
7119d40baaSpara #define	VMEM_QCACHE_IDX_MAX	16
72cca299e0Spara 
73cca299e0Spara #define	QC_NAME_MAX	16
74cca299e0Spara 
75cca299e0Spara struct qcache {
76cca299e0Spara 	pool_cache_t qc_cache;
77cca299e0Spara 	vmem_t *qc_vmem;
78cca299e0Spara 	char qc_name[QC_NAME_MAX];
79cca299e0Spara };
80cca299e0Spara typedef struct qcache qcache_t;
81cca299e0Spara #define	QC_POOL_TO_QCACHE(pool)	((qcache_t *)(pool->pr_qcache))
82cca299e0Spara #endif /* defined(QCACHE) */
83cca299e0Spara 
84cca299e0Spara #define	VMEM_NAME_MAX	16
85cca299e0Spara 
86cca299e0Spara /* vmem arena */
87cca299e0Spara struct vmem {
88cca299e0Spara 	CONDVAR_DECL(vm_cv);
89cca299e0Spara 	LOCK_DECL(vm_lock);
90cca299e0Spara 	vm_flag_t vm_flags;
91cca299e0Spara 	vmem_import_t *vm_importfn;
92cca299e0Spara 	vmem_release_t *vm_releasefn;
93cca299e0Spara 	size_t vm_nfreetags;
94cca299e0Spara 	LIST_HEAD(, vmem_btag) vm_freetags;
95cca299e0Spara 	void *vm_arg;
96cca299e0Spara 	struct vmem_seglist vm_seglist;
97cca299e0Spara 	struct vmem_freelist vm_freelist[VMEM_MAXORDER];
98cca299e0Spara 	size_t vm_hashsize;
99576fda24Sad 	size_t vm_hashmask;
100cca299e0Spara 	size_t vm_nbusytag;
101576fda24Sad 	size_t vm_maxbusytag;
102cca299e0Spara 	struct vmem_hashlist *vm_hashlist;
103cca299e0Spara 	struct vmem_hashlist vm_hash0;
104cca299e0Spara 	size_t vm_quantum_mask;
105cca299e0Spara 	int vm_quantum_shift;
106cca299e0Spara 	size_t vm_size;
107cca299e0Spara 	size_t vm_inuse;
108cca299e0Spara 	char vm_name[VMEM_NAME_MAX+1];
109cca299e0Spara 	LIST_ENTRY(vmem) vm_alllist;
110cca299e0Spara 
111cca299e0Spara #if defined(QCACHE)
112cca299e0Spara 	/* quantum cache */
113cca299e0Spara 	size_t vm_qcache_max;
114cca299e0Spara 	struct pool_allocator vm_qcache_allocator;
115cca299e0Spara 	qcache_t vm_qcache_store[VMEM_QCACHE_IDX_MAX];
116cca299e0Spara 	qcache_t *vm_qcache[VMEM_QCACHE_IDX_MAX];
117cca299e0Spara #endif /* defined(QCACHE) */
118cca299e0Spara };
119cca299e0Spara 
120cca299e0Spara /* boundary tag */
121cca299e0Spara struct vmem_btag {
122471b216bSchristos 	TAILQ_ENTRY(vmem_btag) bt_seglist;
123cca299e0Spara 	union {
124cca299e0Spara 		LIST_ENTRY(vmem_btag) u_freelist; /* BT_TYPE_FREE */
125cca299e0Spara 		LIST_ENTRY(vmem_btag) u_hashlist; /* BT_TYPE_BUSY */
126cca299e0Spara 	} bt_u;
127cca299e0Spara #define	bt_hashlist	bt_u.u_hashlist
128cca299e0Spara #define	bt_freelist	bt_u.u_freelist
129cca299e0Spara 	vmem_addr_t bt_start;
130cca299e0Spara 	vmem_size_t bt_size;
13106f1a2daSthorpej 	short bt_type;
13206f1a2daSthorpej 	short bt_flags;
133cca299e0Spara };
134cca299e0Spara 
135cca299e0Spara #define	BT_TYPE_SPAN		1
136cca299e0Spara #define	BT_TYPE_SPAN_STATIC	2
137cca299e0Spara #define	BT_TYPE_FREE		3
138cca299e0Spara #define	BT_TYPE_BUSY		4
139cca299e0Spara #define	BT_ISSPAN_P(bt)	((bt)->bt_type <= BT_TYPE_SPAN_STATIC)
140cca299e0Spara 
141*bf9518a6Sthorpej #define	BT_F_PRIVATE		0x0001
142*bf9518a6Sthorpej 
143cca299e0Spara #define	BT_END(bt)	((bt)->bt_start + (bt)->bt_size - 1)
144cca299e0Spara 
145*bf9518a6Sthorpej /*
146*bf9518a6Sthorpej  * Provide an estimated number of boundary tags needed for a given
147*bf9518a6Sthorpej  * number of allocations from the vmem arena.  This estimate is
148*bf9518a6Sthorpej  * based on 2 boundary tags per allocation (see vmem_xalloc()) and
149*bf9518a6Sthorpej  * 2 boundary tags per added span (one to describe the span, one to
150*bf9518a6Sthorpej  * describe the span's free space; see vmem_add1()).
151*bf9518a6Sthorpej  */
152*bf9518a6Sthorpej #define	VMEM_EST_BTCOUNT(ns, na)	(((ns) * 2) + ((na) * 2))
153*bf9518a6Sthorpej 
154bbb1b1e0Sthorpej vmem_t *	vmem_init(vmem_t *, const char *, vmem_addr_t, vmem_size_t,
155bbb1b1e0Sthorpej 		    vmem_size_t, vmem_import_t *, vmem_release_t *, vmem_t *,
156bbb1b1e0Sthorpej 		    vmem_size_t, vm_flag_t, int);
157*bf9518a6Sthorpej void		vmem_add_bts(vmem_t *, struct vmem_btag *, unsigned int);
158bbb1b1e0Sthorpej 
159cca299e0Spara #endif /* !_SYS_VMEM_IMPL_H_ */
160