| Commit | Line | Data |
|---|---|---|
| 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 |
105 | struct swblock; |
| 106 | struct swblock_rb_tree; | |
| 107 | int rb_swblock_compare(struct swblock *, struct swblock *); | |
| 108 | ||
| 109 | RB_PROTOTYPE2(swblock_rb_tree, swblock, swb_entry, rb_swblock_compare, | |
| 110 | vm_pindex_t); | |
| 111 | ||
| d1060ff0 HP |
112 | enum 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 |
121 | typedef 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 | 130 | struct 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 | ||
| 204 | TAILQ_HEAD(object_q, vm_object); | |
| 205 | ||
| 206 | extern struct object_q vm_object_list; /* list of allocated objects */ | |
| 207 | ||
| 208 | /* lock for object list and count */ | |
| 209 | ||
| c439ad8f | 210 | extern struct vm_object kernel_object; /* the single kernel object */ |
| 984263bc MD |
211 | |
| 212 | #endif /* _KERNEL */ | |
| 213 | ||
| 214 | #ifdef _KERNEL | |
| 215 | ||
| 216 | static __inline void | |
| 217 | vm_object_set_flag(vm_object_t object, u_int bits) | |
| 218 | { | |
| 219 | atomic_set_short(&object->flags, bits); | |
| 220 | } | |
| 221 | ||
| 222 | static __inline void | |
| 223 | vm_object_clear_flag(vm_object_t object, u_int bits) | |
| 224 | { | |
| 225 | atomic_clear_short(&object->flags, bits); | |
| 226 | } | |
| 227 | ||
| 228 | static __inline void | |
| 229 | vm_object_pip_add(vm_object_t object, int i) | |
| 230 | { | |
| 82246426 | 231 | atomic_add_int(&object->paging_in_progress, i); |
| 984263bc MD |
232 | } |
| 233 | ||
| 234 | static __inline void | |
| 235 | vm_object_pip_subtract(vm_object_t object, int i) | |
| 236 | { | |
| 82246426 | 237 | atomic_subtract_int(&object->paging_in_progress, i); |
| 984263bc MD |
238 | } |
| 239 | ||
| 240 | static __inline void | |
| e1c14c82 | 241 | vm_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 | ||
| 251 | static __inline void | |
| e1c14c82 | 252 | vm_object_pip_wakeup(vm_object_t object) |
| 984263bc | 253 | { |
| e1c14c82 | 254 | vm_object_pip_wakeupn(object, 1); |
| 984263bc MD |
255 | } |
| 256 | ||
| 257 | static __inline void | |
| 258 | vm_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 | ||
| 270 | static __inline void | |
| 271 | vm_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 |
277 | vm_object_t vm_object_allocate (objtype_t, vm_pindex_t); |
| 278 | void _vm_object_allocate (objtype_t, vm_pindex_t, vm_object_t); | |
| 1388df65 RG |
279 | boolean_t vm_object_coalesce (vm_object_t, vm_pindex_t, vm_size_t, vm_size_t); |
| 280 | void vm_object_collapse (vm_object_t); | |
| 281 | void vm_object_deallocate (vm_object_t); | |
| 2de4f77e | 282 | void vm_object_deallocate_locked (vm_object_t); |
| 1388df65 | 283 | void vm_object_terminate (vm_object_t); |
| 1388df65 RG |
284 | void vm_object_set_writeable_dirty (vm_object_t); |
| 285 | void vm_object_init (void); | |
| 286 | void vm_object_page_clean (vm_object_t, vm_pindex_t, vm_pindex_t, boolean_t); | |
| 287 | void vm_object_page_remove (vm_object_t, vm_pindex_t, vm_pindex_t, boolean_t); | |
| 288 | void vm_object_pmap_copy (vm_object_t, vm_pindex_t, vm_pindex_t); | |
| 289 | void vm_object_pmap_copy_1 (vm_object_t, vm_pindex_t, vm_pindex_t); | |
| 290 | void vm_object_pmap_remove (vm_object_t, vm_pindex_t, vm_pindex_t); | |
| 291 | void vm_object_reference (vm_object_t); | |
| 2de4f77e | 292 | void vm_object_reference_locked (vm_object_t); |
| 1388df65 RG |
293 | void vm_object_shadow (vm_object_t *, vm_ooffset_t *, vm_size_t); |
| 294 | void vm_object_madvise (vm_object_t, vm_pindex_t, int, int); | |
| 295 | void vm_object_init2 (void); | |
| aa542ad5 | 296 | vm_page_t vm_fault_object_page(vm_object_t, vm_ooffset_t, vm_prot_t, int, int *); |
| 9e12ff11 MD |
297 | void vm_object_dead_sleep(vm_object_t, const char *); |
| 298 | void vm_object_dead_wakeup(vm_object_t); | |
| e32ad78d VS |
299 | void vm_object_lock(vm_object_t); |
| 300 | void vm_object_unlock(vm_object_t); | |
| e1c14c82 VS |
301 | void vm_object_hold(vm_object_t); |
| 302 | void vm_object_drop(vm_object_t); | |
| 9e12ff11 | 303 | |
| 984263bc MD |
304 | #endif /* _KERNEL */ |
| 305 | ||
| 1bd40720 | 306 | #endif /* _VM_VM_OBJECT_H_ */ |