kernel -- vm_object locking: DEBUG_LOCKS check for hold_wait vs hold deadlock
[dragonfly.git] / sys / vm / vm_object.h
CommitLineData
984263bc
MD
1/*
2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * The Mach Operating System project at Carnegie-Mellon University.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
984263bc
MD
16 * 4. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 * from: @(#)vm_object.h 8.3 (Berkeley) 1/12/94
33 *
34 *
35 * Copyright (c) 1987, 1990 Carnegie-Mellon University.
36 * All rights reserved.
37 *
38 * Authors: Avadis Tevanian, Jr., Michael Wayne Young
39 *
40 * Permission to use, copy, modify and distribute this software and
41 * its documentation is hereby granted, provided that both the copyright
42 * notice and this permission notice appear in all copies of the
43 * software, derivative works or modified versions, and any portions
44 * thereof, and that both notices appear in supporting documentation.
45 *
46 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
47 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
48 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
49 *
50 * Carnegie Mellon requests users of this software to return to
51 *
52 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
53 * School of Computer Science
54 * Carnegie Mellon University
55 * Pittsburgh PA 15213-3890
56 *
57 * any improvements or extensions that they make and grant Carnegie the
58 * rights to redistribute these changes.
59 *
60 * $FreeBSD: src/sys/vm/vm_object.h,v 1.63.2.3 2003/05/26 19:17:56 alc Exp $
61 */
62
63/*
64 * Virtual memory object module definitions.
65 */
66
1bd40720
MD
67#ifndef _VM_VM_OBJECT_H_
68#define _VM_VM_OBJECT_H_
984263bc 69
1bd40720
MD
70#ifndef _SYS_TYPES_H_
71#include <sys/types.h>
72#endif
73#if defined(_KERNEL) && !defined(_SYS_SYSTM_H_)
74#include <sys/systm.h>
75#endif
76#ifndef _SYS_QUEUE_H_
984263bc 77#include <sys/queue.h>
1bd40720 78#endif
96adc753
MD
79#ifndef _SYS_TREE_H_
80#include <sys/tree.h>
81#endif
2de4f77e
MD
82#ifndef _SYS_THREAD_H_
83#include <sys/thread.h>
84#endif
984263bc 85#include <machine/atomic.h>
1bd40720
MD
86#ifndef _VM_VM_H_
87#include <vm/vm.h>
88#endif
1f804340
MD
89#ifndef _VM_VM_PAGE_H_
90#include <vm/vm_page.h>
91#endif
1bd40720 92
2d6c1ebb 93#ifdef _KERNEL
1bd40720 94
e32ad78d
VS
95#ifndef _SYS_THREAD_H
96#include <sys/thread.h>
97#endif
98
1bd40720 99#ifndef _SYS_THREAD2_H_
2d6c1ebb
MD
100#include <sys/thread2.h>
101#endif
984263bc 102
1bd40720
MD
103#endif
104
96adc753
MD
105struct swblock;
106struct swblock_rb_tree;
107int rb_swblock_compare(struct swblock *, struct swblock *);
108
109RB_PROTOTYPE2(swblock_rb_tree, swblock, swb_entry, rb_swblock_compare,
110 vm_pindex_t);
111
d1060ff0
HP
112enum obj_type {
113 OBJT_DEFAULT,
114 OBJT_SWAP, /* object backed by swap blocks */
115 OBJT_VNODE, /* object backed by file pages (vnode) */
116 OBJT_DEVICE, /* object backed by device pages */
117 OBJT_PHYS, /* object backed by physical pages */
00a3fdca
MD
118 OBJT_DEAD, /* dead object */
119 OBJT_MARKER /* marker object */
d1060ff0 120};
984263bc
MD
121typedef u_char objtype_t;
122
123/*
377d4740
MD
124 * vm_object A VM object which represents an arbitrarily sized
125 * data store.
2de4f77e
MD
126 *
127 * Locking requirements: vmobj_token for ref_count and object_list, and
128 * vm_token for everything else.
377d4740 129 */
984263bc 130struct vm_object {
2de4f77e 131 TAILQ_ENTRY(vm_object) object_list; /* vmobj_token */
984263bc
MD
132 LIST_HEAD(, vm_object) shadow_head; /* objects that this is a shadow for */
133 LIST_ENTRY(vm_object) shadow_list; /* chain of shadow objects */
1f804340 134 RB_HEAD(vm_page_rb_tree, vm_page) rb_memq; /* resident pages */
984263bc 135 int generation; /* generation ID */
aecf2182 136 vm_pindex_t size; /* Object size */
2de4f77e 137 int ref_count; /* vmobj_token */
984263bc 138 int shadow_count; /* how many objects that this is a shadow for */
984263bc
MD
139 objtype_t type; /* type of pager */
140 u_short flags; /* see below */
141 u_short pg_color; /* color of first page in obj */
82246426 142 int paging_in_progress; /* Paging (in or out) so don't collapse or destroy */
984263bc 143 int resident_page_count; /* number of resident pages */
50a55c46 144 u_int agg_pv_list_count; /* aggregate pv list count */
984263bc
MD
145 struct vm_object *backing_object; /* object that I'm a shadow of */
146 vm_ooffset_t backing_object_offset;/* Offset in backing object */
984263bc 147 void *handle;
e1c14c82 148 int hold_count; /* refcount for object liveness */
e32ad78d 149
cb443cbb
VS
150#if defined(DEBUG_LOCKS)
151 /*
152 * Record threads holding a vm_object
153 */
154
155#define VMOBJ_DEBUG_ARRAY_SIZE (32)
156 u_int debug_hold_bitmap;
157 thread_t debug_hold_thrs[VMOBJ_DEBUG_ARRAY_SIZE];
158
159#endif
160
984263bc
MD
161 union {
162 /*
984263bc
MD
163 * Device pager
164 *
165 * devp_pglist - list of allocated pages
166 */
167 struct {
168 TAILQ_HEAD(, vm_page) devp_pglist;
169 } devp;
984263bc 170 } un_pager;
96adc753
MD
171
172 /*
173 * OBJT_SWAP and OBJT_VNODE VM objects may have swap backing
174 * store. For vnodes the swap backing store acts as a fast
175 * data cache but the vnode contains the official data.
176 */
177 RB_HEAD(swblock_rb_tree, swblock) swblock_root;
178 int swblock_count;
984263bc
MD
179};
180
181/*
182 * Flags
183 */
184#define OBJ_ACTIVE 0x0004 /* active objects */
185#define OBJ_DEAD 0x0008 /* dead objects (during rundown) */
186#define OBJ_NOSPLIT 0x0010 /* dont split this object */
187#define OBJ_PIPWNT 0x0040 /* paging in progress wanted */
188#define OBJ_WRITEABLE 0x0080 /* object has been made writable */
189#define OBJ_MIGHTBEDIRTY 0x0100 /* object might be dirty */
190#define OBJ_CLEANING 0x0200
9e12ff11 191#define OBJ_DEADWNT 0x1000 /* waiting because object is dead */
984263bc 192#define OBJ_ONEMAPPING 0x2000 /* One USE (a single, non-forked) mapping flag */
2bc7505b 193#define OBJ_NOMSYNC 0x4000 /* disable msync() system call */
984263bc
MD
194
195#define IDX_TO_OFF(idx) (((vm_ooffset_t)(idx)) << PAGE_SHIFT)
196#define OFF_TO_IDX(off) ((vm_pindex_t)(((vm_ooffset_t)(off)) >> PAGE_SHIFT))
197
198#ifdef _KERNEL
199
200#define OBJPC_SYNC 0x1 /* sync I/O */
201#define OBJPC_INVAL 0x2 /* invalidate */
202#define OBJPC_NOSYNC 0x4 /* skip if PG_NOSYNC */
203
204TAILQ_HEAD(object_q, vm_object);
205
206extern struct object_q vm_object_list; /* list of allocated objects */
207
208 /* lock for object list and count */
209
c439ad8f 210extern struct vm_object kernel_object; /* the single kernel object */
984263bc
MD
211
212#endif /* _KERNEL */
213
214#ifdef _KERNEL
215
216static __inline void
217vm_object_set_flag(vm_object_t object, u_int bits)
218{
219 atomic_set_short(&object->flags, bits);
220}
221
222static __inline void
223vm_object_clear_flag(vm_object_t object, u_int bits)
224{
225 atomic_clear_short(&object->flags, bits);
226}
227
228static __inline void
229vm_object_pip_add(vm_object_t object, int i)
230{
82246426 231 atomic_add_int(&object->paging_in_progress, i);
984263bc
MD
232}
233
234static __inline void
235vm_object_pip_subtract(vm_object_t object, int i)
236{
82246426 237 atomic_subtract_int(&object->paging_in_progress, i);
984263bc
MD
238}
239
240static __inline void
e1c14c82 241vm_object_pip_wakeupn(vm_object_t object, int i)
984263bc 242{
e1c14c82
VS
243 if (i)
244 atomic_subtract_int(&object->paging_in_progress, i);
984263bc
MD
245 if ((object->flags & OBJ_PIPWNT) && object->paging_in_progress == 0) {
246 vm_object_clear_flag(object, OBJ_PIPWNT);
247 wakeup(object);
248 }
249}
250
251static __inline void
e1c14c82 252vm_object_pip_wakeup(vm_object_t object)
984263bc 253{
e1c14c82 254 vm_object_pip_wakeupn(object, 1);
984263bc
MD
255}
256
257static __inline void
258vm_object_pip_sleep(vm_object_t object, char *waitid)
259{
260 if (object->paging_in_progress) {
cdd46d2e 261 crit_enter();
984263bc
MD
262 if (object->paging_in_progress) {
263 vm_object_set_flag(object, OBJ_PIPWNT);
377d4740 264 tsleep(object, 0, waitid, 0);
984263bc 265 }
cdd46d2e 266 crit_exit();
984263bc
MD
267 }
268}
269
270static __inline void
271vm_object_pip_wait(vm_object_t object, char *waitid)
272{
273 while (object->paging_in_progress)
274 vm_object_pip_sleep(object, waitid);
275}
276
aecf2182
MD
277vm_object_t vm_object_allocate (objtype_t, vm_pindex_t);
278void _vm_object_allocate (objtype_t, vm_pindex_t, vm_object_t);
1388df65
RG
279boolean_t vm_object_coalesce (vm_object_t, vm_pindex_t, vm_size_t, vm_size_t);
280void vm_object_collapse (vm_object_t);
281void vm_object_deallocate (vm_object_t);
2de4f77e 282void vm_object_deallocate_locked (vm_object_t);
1388df65 283void vm_object_terminate (vm_object_t);
1388df65
RG
284void vm_object_set_writeable_dirty (vm_object_t);
285void vm_object_init (void);
286void vm_object_page_clean (vm_object_t, vm_pindex_t, vm_pindex_t, boolean_t);
287void vm_object_page_remove (vm_object_t, vm_pindex_t, vm_pindex_t, boolean_t);
288void vm_object_pmap_copy (vm_object_t, vm_pindex_t, vm_pindex_t);
289void vm_object_pmap_copy_1 (vm_object_t, vm_pindex_t, vm_pindex_t);
290void vm_object_pmap_remove (vm_object_t, vm_pindex_t, vm_pindex_t);
291void vm_object_reference (vm_object_t);
2de4f77e 292void vm_object_reference_locked (vm_object_t);
1388df65
RG
293void vm_object_shadow (vm_object_t *, vm_ooffset_t *, vm_size_t);
294void vm_object_madvise (vm_object_t, vm_pindex_t, int, int);
295void vm_object_init2 (void);
aa542ad5 296vm_page_t vm_fault_object_page(vm_object_t, vm_ooffset_t, vm_prot_t, int, int *);
9e12ff11
MD
297void vm_object_dead_sleep(vm_object_t, const char *);
298void vm_object_dead_wakeup(vm_object_t);
e32ad78d
VS
299void vm_object_lock(vm_object_t);
300void vm_object_unlock(vm_object_t);
e1c14c82
VS
301void vm_object_hold(vm_object_t);
302void vm_object_drop(vm_object_t);
9e12ff11 303
984263bc
MD
304#endif /* _KERNEL */
305
1bd40720 306#endif /* _VM_VM_OBJECT_H_ */