]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - sys/vm/vm_page.h
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / sys / vm / vm_page.h
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.
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_page.h     8.2 (Berkeley) 12/13/93
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$
61  */
62
63 /*
64  *      Resident memory system definitions.
65  */
66
67 #ifndef _VM_PAGE_
68 #define _VM_PAGE_
69
70 #include <vm/pmap.h>
71
72 /*
73  *      Management of resident (logical) pages.
74  *
75  *      A small structure is kept for each resident
76  *      page, indexed by page number.  Each structure
77  *      is an element of several lists:
78  *
79  *              A hash table bucket used to quickly
80  *              perform object/offset lookups
81  *
82  *              A list of all pages for a given object,
83  *              so they can be quickly deactivated at
84  *              time of deallocation.
85  *
86  *              An ordered list of pages due for pageout.
87  *
88  *      In addition, the structure contains the object
89  *      and offset to which this page belongs (for pageout),
90  *      and sundry status bits.
91  *
92  *      Fields in this structure are locked either by the lock on the
93  *      object that the page belongs to (O) or by the lock on the page
94  *      queues (P).
95  *
96  *      The 'valid' and 'dirty' fields are distinct.  A page may have dirty
97  *      bits set without having associated valid bits set.  This is used by
98  *      NFS to implement piecemeal writes.
99  */
100
101 TAILQ_HEAD(pglist, vm_page);
102
103 struct vm_page {
104         TAILQ_ENTRY(vm_page) pageq;     /* queue info for FIFO queue or free list (P) */
105         TAILQ_ENTRY(vm_page) listq;     /* pages in same object (O)     */
106         struct vm_page *left;           /* splay tree link (O)          */
107         struct vm_page *right;          /* splay tree link (O)          */
108
109         vm_object_t object;             /* which object am I in (O,P)*/
110         vm_pindex_t pindex;             /* offset into object (O,P) */
111         vm_paddr_t phys_addr;           /* physical address of page */
112         struct md_page md;              /* machine dependant stuff */
113         uint8_t queue;                  /* page queue index */
114         int8_t segind;
115         u_short flags;                  /* see below */
116         uint8_t order;                  /* index of the buddy queue */
117         uint8_t pool;
118         u_short cow;                    /* page cow mapping count */
119         u_int wire_count;               /* wired down maps refs (P) */
120         short hold_count;               /* page hold count */
121         u_short oflags;                 /* page flags (O) */
122         u_char  act_count;              /* page usage count */
123         u_char  busy;                   /* page busy count (O) */
124         /* NOTE that these must support one bit per DEV_BSIZE in a page!!! */
125         /* so, on normal X86 kernels, they must be at least 8 bits wide */
126 #if PAGE_SIZE == 4096
127         u_char  valid;                  /* map of valid DEV_BSIZE chunks (O) */
128         u_char  dirty;                  /* map of dirty DEV_BSIZE chunks */
129 #elif PAGE_SIZE == 8192
130         u_short valid;                  /* map of valid DEV_BSIZE chunks (O) */
131         u_short dirty;                  /* map of dirty DEV_BSIZE chunks */
132 #elif PAGE_SIZE == 16384
133         u_int valid;                    /* map of valid DEV_BSIZE chunks (O) */
134         u_int dirty;                    /* map of dirty DEV_BSIZE chunks */
135 #elif PAGE_SIZE == 32768
136         u_long valid;                   /* map of valid DEV_BSIZE chunks (O) */
137         u_long dirty;                   /* map of dirty DEV_BSIZE chunks */
138 #endif
139 };
140
141 /*
142  * Page flags stored in oflags:
143  *
144  * Access to these page flags is synchronized by the lock on the object
145  * containing the page (O).
146  */
147 #define VPO_BUSY        0x0001  /* page is in transit */
148 #define VPO_WANTED      0x0002  /* someone is waiting for page */
149 #define VPO_CLEANCHK    0x0100  /* page will be checked for cleaning */
150 #define VPO_SWAPINPROG  0x0200  /* swap I/O in progress on page */
151 #define VPO_NOSYNC      0x0400  /* do not collect for syncer */
152
153 /* Make sure that u_long is at least 64 bits when PAGE_SIZE is 32K. */
154 #if PAGE_SIZE == 32768
155 #ifdef CTASSERT
156 CTASSERT(sizeof(u_long) >= 8);
157 #endif
158 #endif
159
160 #define PQ_NONE         0
161 #define PQ_INACTIVE     1
162 #define PQ_ACTIVE       2
163 #define PQ_HOLD         3
164 #define PQ_COUNT        4
165
166 /* Returns the real queue a page is on. */
167 #define VM_PAGE_GETQUEUE(m)     ((m)->queue)
168
169 /* Returns the well known queue a page is on. */
170 #define VM_PAGE_GETKNOWNQUEUE2(m)       VM_PAGE_GETQUEUE(m)
171
172 /* Returns true if the page is in the named well known queue. */
173 #define VM_PAGE_INQUEUE2(m, q)  (VM_PAGE_GETKNOWNQUEUE2(m) == (q))
174
175 /* Sets the queue a page is on. */
176 #define VM_PAGE_SETQUEUE2(m, q) (VM_PAGE_GETQUEUE(m) = (q))
177
178 struct vpgqueues {
179         struct pglist pl;
180         int     *cnt;
181 };
182
183 extern struct vpgqueues vm_page_queues[PQ_COUNT];
184 extern struct mtx vm_page_queue_free_mtx;
185
186 /*
187  * These are the flags defined for vm_page.
188  *
189  * Note: PG_UNMANAGED (used by OBJT_PHYS) indicates that the page is
190  *       not under PV management but otherwise should be treated as a
191  *       normal page.  Pages not under PV management cannot be paged out
192  *       via the object/vm_page_t because there is no knowledge of their
193  *       pte mappings, nor can they be removed from their objects via 
194  *       the object, and such pages are also not on any PQ queue.
195  */
196 #define PG_CACHED       0x0001          /* page is cached */
197 #define PG_FREE         0x0002          /* page is free */
198 #define PG_WINATCFLS    0x0004          /* flush dirty page on inactive q */
199 #define PG_FICTITIOUS   0x0008          /* physical page doesn't exist (O) */
200 #define PG_WRITEABLE    0x0010          /* page is mapped writeable */
201 #define PG_ZERO         0x0040          /* page is zeroed */
202 #define PG_REFERENCED   0x0080          /* page has been referenced */
203 #define PG_UNMANAGED    0x0800          /* No PV management for page */
204 #define PG_MARKER       0x1000          /* special queue marker page */
205 #define PG_SLAB         0x2000          /* object pointer is actually a slab */
206
207 /*
208  * Misc constants.
209  */
210 #define ACT_DECLINE             1
211 #define ACT_ADVANCE             3
212 #define ACT_INIT                5
213 #define ACT_MAX                 64
214
215 #ifdef _KERNEL
216
217 #include <vm/vm_param.h>
218
219 /*
220  * Each pageable resident page falls into one of five lists:
221  *
222  *      free
223  *              Available for allocation now.
224  *
225  *      cache
226  *              Almost available for allocation. Still associated with
227  *              an object, but clean and immediately freeable.
228  *
229  *      hold
230  *              Will become free after a pending I/O operation
231  *              completes.
232  *
233  * The following lists are LRU sorted:
234  *
235  *      inactive
236  *              Low activity, candidates for reclamation.
237  *              This is the list of pages that should be
238  *              paged out next.
239  *
240  *      active
241  *              Pages that are "active" i.e. they have been
242  *              recently referenced.
243  *
244  */
245
246 extern int vm_page_zero_count;
247
248 extern vm_page_t vm_page_array;         /* First resident page in table */
249 extern int vm_page_array_size;          /* number of vm_page_t's */
250 extern long first_page;                 /* first physical page number */
251
252 #define VM_PAGE_IS_FREE(m)      (((m)->flags & PG_FREE) != 0)
253
254 #define VM_PAGE_TO_PHYS(entry)  ((entry)->phys_addr)
255
256 vm_page_t vm_phys_paddr_to_vm_page(vm_paddr_t pa);
257
258 static __inline vm_page_t PHYS_TO_VM_PAGE(vm_paddr_t pa);
259
260 static __inline vm_page_t
261 PHYS_TO_VM_PAGE(vm_paddr_t pa)
262 {
263 #ifdef VM_PHYSSEG_SPARSE
264         return (vm_phys_paddr_to_vm_page(pa));
265 #elif defined(VM_PHYSSEG_DENSE)
266         return (&vm_page_array[atop(pa) - first_page]);
267 #else
268 #error "Either VM_PHYSSEG_DENSE or VM_PHYSSEG_SPARSE must be defined."
269 #endif
270 }
271
272 extern struct mtx vm_page_queue_mtx;
273 #define vm_page_lock_queues()   mtx_lock(&vm_page_queue_mtx)
274 #define vm_page_unlock_queues() mtx_unlock(&vm_page_queue_mtx)
275
276 #if PAGE_SIZE == 4096
277 #define VM_PAGE_BITS_ALL 0xffu
278 #elif PAGE_SIZE == 8192
279 #define VM_PAGE_BITS_ALL 0xffffu
280 #elif PAGE_SIZE == 16384
281 #define VM_PAGE_BITS_ALL 0xffffffffu
282 #elif PAGE_SIZE == 32768
283 #define VM_PAGE_BITS_ALL 0xfffffffffffffffflu
284 #endif
285
286 /* page allocation classes: */
287 #define VM_ALLOC_NORMAL         0
288 #define VM_ALLOC_INTERRUPT      1
289 #define VM_ALLOC_SYSTEM         2
290 #define VM_ALLOC_CLASS_MASK     3
291 /* page allocation flags: */
292 #define VM_ALLOC_WIRED          0x0020  /* non pageable */
293 #define VM_ALLOC_ZERO           0x0040  /* Try to obtain a zeroed page */
294 #define VM_ALLOC_RETRY          0x0080  /* vm_page_grab() only */
295 #define VM_ALLOC_NOOBJ          0x0100  /* No associated object */
296 #define VM_ALLOC_NOBUSY         0x0200  /* Do not busy the page */
297 #define VM_ALLOC_IFCACHED       0x0400  /* Fail if the page is not cached */
298 #define VM_ALLOC_IFNOTCACHED    0x0800  /* Fail if the page is cached */
299
300 void vm_page_flag_set(vm_page_t m, unsigned short bits);
301 void vm_page_flag_clear(vm_page_t m, unsigned short bits);
302 void vm_page_busy(vm_page_t m);
303 void vm_page_flash(vm_page_t m);
304 void vm_page_io_start(vm_page_t m);
305 void vm_page_io_finish(vm_page_t m);
306 void vm_page_hold(vm_page_t mem);
307 void vm_page_unhold(vm_page_t mem);
308 void vm_page_free(vm_page_t m);
309 void vm_page_free_zero(vm_page_t m);
310 void vm_page_dirty(vm_page_t m);
311 void vm_page_wakeup(vm_page_t m);
312
313 void vm_pageq_remove(vm_page_t m);
314
315 void vm_page_activate (vm_page_t);
316 vm_page_t vm_page_alloc (vm_object_t, vm_pindex_t, int);
317 vm_page_t vm_page_grab (vm_object_t, vm_pindex_t, int);
318 void vm_page_cache (register vm_page_t);
319 void vm_page_cache_free(vm_object_t, vm_pindex_t, vm_pindex_t);
320 void vm_page_cache_remove(vm_page_t);
321 void vm_page_cache_transfer(vm_object_t, vm_pindex_t, vm_object_t);
322 int vm_page_try_to_cache (vm_page_t);
323 int vm_page_try_to_free (vm_page_t);
324 void vm_page_dontneed (register vm_page_t);
325 void vm_page_deactivate (vm_page_t);
326 void vm_page_insert (vm_page_t, vm_object_t, vm_pindex_t);
327 vm_page_t vm_page_lookup (vm_object_t, vm_pindex_t);
328 void vm_page_remove (vm_page_t);
329 void vm_page_rename (vm_page_t, vm_object_t, vm_pindex_t);
330 void vm_page_requeue(vm_page_t m);
331 void vm_page_sleep(vm_page_t m, const char *msg);
332 vm_page_t vm_page_splay(vm_pindex_t, vm_page_t);
333 vm_offset_t vm_page_startup(vm_offset_t vaddr);
334 void vm_page_unwire (vm_page_t, int);
335 void vm_page_wire (vm_page_t);
336 void vm_page_set_validclean (vm_page_t, int, int);
337 void vm_page_clear_dirty (vm_page_t, int, int);
338 void vm_page_set_invalid (vm_page_t, int, int);
339 int vm_page_is_valid (vm_page_t, int, int);
340 void vm_page_test_dirty (vm_page_t);
341 int vm_page_bits (int, int);
342 void vm_page_zero_invalid(vm_page_t m, boolean_t setvalid);
343 void vm_page_free_toq(vm_page_t m);
344 void vm_page_zero_idle_wakeup(void);
345 void vm_page_cowfault (vm_page_t);
346 int vm_page_cowsetup(vm_page_t);
347 void vm_page_cowclear (vm_page_t);
348
349 /*
350  *      vm_page_sleep_if_busy:
351  *
352  *      Sleep and release the page queues lock if VPO_BUSY is set or,
353  *      if also_m_busy is TRUE, busy is non-zero.  Returns TRUE if the
354  *      thread slept and the page queues lock was released.
355  *      Otherwise, retains the page queues lock and returns FALSE.
356  *
357  *      The object containing the given page must be locked.
358  */
359 static __inline int
360 vm_page_sleep_if_busy(vm_page_t m, int also_m_busy, const char *msg)
361 {
362
363         if ((m->oflags & VPO_BUSY) || (also_m_busy && m->busy)) {
364                 vm_page_sleep(m, msg);
365                 return (TRUE);
366         }
367         return (FALSE);
368 }
369
370 /*
371  *      vm_page_undirty:
372  *
373  *      Set page to not be dirty.  Note: does not clear pmap modify bits
374  */
375 static __inline void
376 vm_page_undirty(vm_page_t m)
377 {
378         m->dirty = 0;
379 }
380
381 #endif                          /* _KERNEL */
382 #endif                          /* !_VM_PAGE_ */