vm_page.h revision 1541
11541Srgrimes/*
21541Srgrimes * Copyright (c) 1991, 1993
31541Srgrimes *	The Regents of the University of California.  All rights reserved.
41541Srgrimes *
51541Srgrimes * This code is derived from software contributed to Berkeley by
61541Srgrimes * The Mach Operating System project at Carnegie-Mellon University.
71541Srgrimes *
81541Srgrimes * Redistribution and use in source and binary forms, with or without
91541Srgrimes * modification, are permitted provided that the following conditions
101541Srgrimes * are met:
111541Srgrimes * 1. Redistributions of source code must retain the above copyright
121541Srgrimes *    notice, this list of conditions and the following disclaimer.
131541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
141541Srgrimes *    notice, this list of conditions and the following disclaimer in the
151541Srgrimes *    documentation and/or other materials provided with the distribution.
161541Srgrimes * 3. All advertising materials mentioning features or use of this software
171541Srgrimes *    must display the following acknowledgement:
181541Srgrimes *	This product includes software developed by the University of
191541Srgrimes *	California, Berkeley and its contributors.
201541Srgrimes * 4. Neither the name of the University nor the names of its contributors
211541Srgrimes *    may be used to endorse or promote products derived from this software
221541Srgrimes *    without specific prior written permission.
231541Srgrimes *
241541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
251541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
261541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
271541Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
281541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
291541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
301541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
311541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
321541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
331541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
341541Srgrimes * SUCH DAMAGE.
351541Srgrimes *
361541Srgrimes *	@(#)vm_page.h	8.2 (Berkeley) 12/13/93
371541Srgrimes *
381541Srgrimes *
391541Srgrimes * Copyright (c) 1987, 1990 Carnegie-Mellon University.
401541Srgrimes * All rights reserved.
411541Srgrimes *
421541Srgrimes * Authors: Avadis Tevanian, Jr., Michael Wayne Young
431541Srgrimes *
441541Srgrimes * Permission to use, copy, modify and distribute this software and
451541Srgrimes * its documentation is hereby granted, provided that both the copyright
461541Srgrimes * notice and this permission notice appear in all copies of the
471541Srgrimes * software, derivative works or modified versions, and any portions
481541Srgrimes * thereof, and that both notices appear in supporting documentation.
491541Srgrimes *
501541Srgrimes * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
511541Srgrimes * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
521541Srgrimes * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
531541Srgrimes *
541541Srgrimes * Carnegie Mellon requests users of this software to return to
551541Srgrimes *
561541Srgrimes *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
571541Srgrimes *  School of Computer Science
581541Srgrimes *  Carnegie Mellon University
591541Srgrimes *  Pittsburgh PA 15213-3890
601541Srgrimes *
611541Srgrimes * any improvements or extensions that they make and grant Carnegie the
621541Srgrimes * rights to redistribute these changes.
631541Srgrimes */
641541Srgrimes
651541Srgrimes/*
661541Srgrimes *	Resident memory system definitions.
671541Srgrimes */
681541Srgrimes
691541Srgrimes#ifndef	_VM_PAGE_
701541Srgrimes#define	_VM_PAGE_
711541Srgrimes
721541Srgrimes/*
731541Srgrimes *	Management of resident (logical) pages.
741541Srgrimes *
751541Srgrimes *	A small structure is kept for each resident
761541Srgrimes *	page, indexed by page number.  Each structure
771541Srgrimes *	is an element of several lists:
781541Srgrimes *
791541Srgrimes *		A hash table bucket used to quickly
801541Srgrimes *		perform object/offset lookups
811541Srgrimes *
821541Srgrimes *		A list of all pages for a given object,
831541Srgrimes *		so they can be quickly deactivated at
841541Srgrimes *		time of deallocation.
851541Srgrimes *
861541Srgrimes *		An ordered list of pages due for pageout.
871541Srgrimes *
881541Srgrimes *	In addition, the structure contains the object
891541Srgrimes *	and offset to which this page belongs (for pageout),
901541Srgrimes *	and sundry status bits.
911541Srgrimes *
921541Srgrimes *	Fields in this structure are locked either by the lock on the
931541Srgrimes *	object that the page belongs to (O) or by the lock on the page
941541Srgrimes *	queues (P).
951541Srgrimes */
961541Srgrimes
971541SrgrimesTAILQ_HEAD(pglist, vm_page);
981541Srgrimes
991541Srgrimesstruct vm_page {
1001541Srgrimes	TAILQ_ENTRY(vm_page)	pageq;		/* queue info for FIFO
1011541Srgrimes						 * queue or free list (P) */
1021541Srgrimes	TAILQ_ENTRY(vm_page)	hashq;		/* hash table links (O)*/
1031541Srgrimes	TAILQ_ENTRY(vm_page)	listq;		/* pages in same object (O)*/
1041541Srgrimes
1051541Srgrimes	vm_object_t		object;		/* which object am I in (O,P)*/
1061541Srgrimes	vm_offset_t		offset;		/* offset into object (O,P) */
1071541Srgrimes
1081541Srgrimes	u_short			wire_count;	/* wired down maps refs (P) */
1091541Srgrimes	u_short			flags;		/* see below */
1101541Srgrimes
1111541Srgrimes	vm_offset_t		phys_addr;	/* physical address of page */
1121541Srgrimes};
1131541Srgrimes
1141541Srgrimes/*
1151541Srgrimes * These are the flags defined for vm_page.
1161541Srgrimes *
1171541Srgrimes * Note: PG_FILLED and PG_DIRTY are added for the filesystems.
1181541Srgrimes */
1191541Srgrimes#define	PG_INACTIVE	0x0001		/* page is in inactive list (P) */
1201541Srgrimes#define	PG_ACTIVE	0x0002		/* page is in active list (P) */
1211541Srgrimes#define	PG_LAUNDRY	0x0004		/* page is being cleaned now (P)*/
1221541Srgrimes#define	PG_CLEAN	0x0008		/* page has not been modified */
1231541Srgrimes#define	PG_BUSY		0x0010		/* page is in transit (O) */
1241541Srgrimes#define	PG_WANTED	0x0020		/* someone is waiting for page (O) */
1251541Srgrimes#define	PG_TABLED	0x0040		/* page is in VP table (O) */
1261541Srgrimes#define	PG_COPYONWRITE	0x0080		/* must copy page before changing (O) */
1271541Srgrimes#define	PG_FICTITIOUS	0x0100		/* physical page doesn't exist (O) */
1281541Srgrimes#define	PG_FAKE		0x0200		/* page is placeholder for pagein (O) */
1291541Srgrimes#define	PG_FILLED	0x0400		/* client flag to set when filled */
1301541Srgrimes#define	PG_DIRTY	0x0800		/* client flag to set when dirty */
1311541Srgrimes#define	PG_PAGEROWNED	0x4000		/* DEBUG: async paging op in progress */
1321541Srgrimes#define	PG_PTPAGE	0x8000		/* DEBUG: is a user page table page */
1331541Srgrimes
1341541Srgrimes#if	VM_PAGE_DEBUG
1351541Srgrimes#define	VM_PAGE_CHECK(mem) { \
1361541Srgrimes	if ((((unsigned int) mem) < ((unsigned int) &vm_page_array[0])) || \
1371541Srgrimes	    (((unsigned int) mem) > \
1381541Srgrimes		((unsigned int) &vm_page_array[last_page-first_page])) || \
1391541Srgrimes	    ((mem->flags & (PG_ACTIVE | PG_INACTIVE)) == \
1401541Srgrimes		(PG_ACTIVE | PG_INACTIVE))) \
1411541Srgrimes		panic("vm_page_check: not valid!"); \
1421541Srgrimes}
1431541Srgrimes#else /* VM_PAGE_DEBUG */
1441541Srgrimes#define	VM_PAGE_CHECK(mem)
1451541Srgrimes#endif /* VM_PAGE_DEBUG */
1461541Srgrimes
1471541Srgrimes#ifdef KERNEL
1481541Srgrimes/*
1491541Srgrimes *	Each pageable resident page falls into one of three lists:
1501541Srgrimes *
1511541Srgrimes *	free
1521541Srgrimes *		Available for allocation now.
1531541Srgrimes *	inactive
1541541Srgrimes *		Not referenced in any map, but still has an
1551541Srgrimes *		object/offset-page mapping, and may be dirty.
1561541Srgrimes *		This is the list of pages that should be
1571541Srgrimes *		paged out next.
1581541Srgrimes *	active
1591541Srgrimes *		A list of pages which have been placed in
1601541Srgrimes *		at least one physical map.  This list is
1611541Srgrimes *		ordered, in LRU-like fashion.
1621541Srgrimes */
1631541Srgrimes
1641541Srgrimesextern
1651541Srgrimesstruct pglist	vm_page_queue_free;	/* memory free queue */
1661541Srgrimesextern
1671541Srgrimesstruct pglist	vm_page_queue_active;	/* active memory queue */
1681541Srgrimesextern
1691541Srgrimesstruct pglist	vm_page_queue_inactive;	/* inactive memory queue */
1701541Srgrimes
1711541Srgrimesextern
1721541Srgrimesvm_page_t	vm_page_array;		/* First resident page in table */
1731541Srgrimesextern
1741541Srgrimeslong		first_page;		/* first physical page number */
1751541Srgrimes					/* ... represented in vm_page_array */
1761541Srgrimesextern
1771541Srgrimeslong		last_page;		/* last physical page number */
1781541Srgrimes					/* ... represented in vm_page_array */
1791541Srgrimes					/* [INCLUSIVE] */
1801541Srgrimesextern
1811541Srgrimesvm_offset_t	first_phys_addr;	/* physical address for first_page */
1821541Srgrimesextern
1831541Srgrimesvm_offset_t	last_phys_addr;		/* physical address for last_page */
1841541Srgrimes
1851541Srgrimes#define VM_PAGE_TO_PHYS(entry)	((entry)->phys_addr)
1861541Srgrimes
1871541Srgrimes#define IS_VM_PHYSADDR(pa) \
1881541Srgrimes		((pa) >= first_phys_addr && (pa) <= last_phys_addr)
1891541Srgrimes
1901541Srgrimes#define PHYS_TO_VM_PAGE(pa) \
1911541Srgrimes		(&vm_page_array[atop(pa) - first_page ])
1921541Srgrimes
1931541Srgrimesextern
1941541Srgrimessimple_lock_data_t	vm_page_queue_lock;	/* lock on active and inactive
1951541Srgrimes						   page queues */
1961541Srgrimesextern						/* lock on free page queue */
1971541Srgrimessimple_lock_data_t	vm_page_queue_free_lock;
1981541Srgrimes
1991541Srgrimes/*
2001541Srgrimes *	Functions implemented as macros
2011541Srgrimes */
2021541Srgrimes
2031541Srgrimes#define PAGE_ASSERT_WAIT(m, interruptible)	{ \
2041541Srgrimes				(m)->flags |= PG_WANTED; \
2051541Srgrimes				assert_wait((int) (m), (interruptible)); \
2061541Srgrimes			}
2071541Srgrimes
2081541Srgrimes#define PAGE_WAKEUP(m)	{ \
2091541Srgrimes				(m)->flags &= ~PG_BUSY; \
2101541Srgrimes				if ((m)->flags & PG_WANTED) { \
2111541Srgrimes					(m)->flags &= ~PG_WANTED; \
2121541Srgrimes					thread_wakeup((int) (m)); \
2131541Srgrimes				} \
2141541Srgrimes			}
2151541Srgrimes
2161541Srgrimes#define	vm_page_lock_queues()	simple_lock(&vm_page_queue_lock)
2171541Srgrimes#define	vm_page_unlock_queues()	simple_unlock(&vm_page_queue_lock)
2181541Srgrimes
2191541Srgrimes#define vm_page_set_modified(m)	{ (m)->flags &= ~PG_CLEAN; }
2201541Srgrimes
2211541Srgrimes#define	VM_PAGE_INIT(mem, object, offset) { \
2221541Srgrimes	(mem)->flags = PG_BUSY | PG_CLEAN | PG_FAKE; \
2231541Srgrimes	vm_page_insert((mem), (object), (offset)); \
2241541Srgrimes	(mem)->wire_count = 0; \
2251541Srgrimes}
2261541Srgrimes
2271541Srgrimesvoid		 vm_page_activate __P((vm_page_t));
2281541Srgrimesvm_page_t	 vm_page_alloc __P((vm_object_t, vm_offset_t));
2291541Srgrimesvoid		 vm_page_copy __P((vm_page_t, vm_page_t));
2301541Srgrimesvoid		 vm_page_deactivate __P((vm_page_t));
2311541Srgrimesvoid		 vm_page_free __P((vm_page_t));
2321541Srgrimesvoid		 vm_page_insert __P((vm_page_t, vm_object_t, vm_offset_t));
2331541Srgrimesvm_page_t	 vm_page_lookup __P((vm_object_t, vm_offset_t));
2341541Srgrimesvoid		 vm_page_remove __P((vm_page_t));
2351541Srgrimesvoid		 vm_page_rename __P((vm_page_t, vm_object_t, vm_offset_t));
2361541Srgrimesvoid		 vm_page_startup __P((vm_offset_t *, vm_offset_t *));
2371541Srgrimesvoid		 vm_page_unwire __P((vm_page_t));
2381541Srgrimesvoid		 vm_page_wire __P((vm_page_t));
2391541Srgrimesboolean_t	 vm_page_zero_fill __P((vm_page_t));
2401541Srgrimes
2411541Srgrimes#endif /* KERNEL */
2421541Srgrimes#endif /* !_VM_PAGE_ */
243