1df8bae1dSRodney W. Grimes /* 2df8bae1dSRodney W. Grimes * Copyright (c) 1990 University of Utah. 3df8bae1dSRodney W. Grimes * Copyright (c) 1991, 1993 4df8bae1dSRodney W. Grimes * The Regents of the University of California. All rights reserved. 5df8bae1dSRodney W. Grimes * 6df8bae1dSRodney W. Grimes * This code is derived from software contributed to Berkeley by 7df8bae1dSRodney W. Grimes * the Systems Programming Group of the University of Utah Computer 8df8bae1dSRodney W. Grimes * Science Department. 9df8bae1dSRodney W. Grimes * 10df8bae1dSRodney W. Grimes * Redistribution and use in source and binary forms, with or without 11df8bae1dSRodney W. Grimes * modification, are permitted provided that the following conditions 12df8bae1dSRodney W. Grimes * are met: 13df8bae1dSRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 14df8bae1dSRodney W. Grimes * notice, this list of conditions and the following disclaimer. 15df8bae1dSRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 16df8bae1dSRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 17df8bae1dSRodney W. Grimes * documentation and/or other materials provided with the distribution. 18df8bae1dSRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 19df8bae1dSRodney W. Grimes * must display the following acknowledgement: 20df8bae1dSRodney W. Grimes * This product includes software developed by the University of 21df8bae1dSRodney W. Grimes * California, Berkeley and its contributors. 22df8bae1dSRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 23df8bae1dSRodney W. Grimes * may be used to endorse or promote products derived from this software 24df8bae1dSRodney W. Grimes * without specific prior written permission. 25df8bae1dSRodney W. Grimes * 26df8bae1dSRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27df8bae1dSRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28df8bae1dSRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29df8bae1dSRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30df8bae1dSRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31df8bae1dSRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32df8bae1dSRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33df8bae1dSRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34df8bae1dSRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35df8bae1dSRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36df8bae1dSRodney W. Grimes * SUCH DAMAGE. 37df8bae1dSRodney W. Grimes * 38df8bae1dSRodney W. Grimes * @(#)vm_pager.h 8.4 (Berkeley) 1/12/94 39c3aac50fSPeter Wemm * $FreeBSD$ 40df8bae1dSRodney W. Grimes */ 41df8bae1dSRodney W. Grimes 42df8bae1dSRodney W. Grimes /* 43df8bae1dSRodney W. Grimes * Pager routine interface definition. 44df8bae1dSRodney W. Grimes */ 45df8bae1dSRodney W. Grimes 46df8bae1dSRodney W. Grimes #ifndef _VM_PAGER_ 47df8bae1dSRodney W. Grimes #define _VM_PAGER_ 48df8bae1dSRodney W. Grimes 49e7a58978SBruce Evans #include <sys/queue.h> 50e7a58978SBruce Evans 51e3975643SJake Burkholder TAILQ_HEAD(pagerlst, vm_object); 52df8bae1dSRodney W. Grimes 530b441832SPoul-Henning Kamp struct bio; 54a5296b05SJulian Elischer 55df8bae1dSRodney W. Grimes struct pagerops { 560d94caffSDavid Greenman void (*pgo_init) __P((void)); /* Initialize pager. */ 576cde7a16SDavid Greenman vm_object_t (*pgo_alloc) __P((void *, vm_ooffset_t, vm_prot_t, vm_ooffset_t)); /* Allocate pager. */ 5824a1cce3SDavid Greenman void (*pgo_dealloc) __P((vm_object_t)); /* Disassociate. */ 5924a1cce3SDavid Greenman int (*pgo_getpages) __P((vm_object_t, vm_page_t *, int, int)); /* Get (read) page. */ 60e4542174SMatthew Dillon void (*pgo_putpages) __P((vm_object_t, vm_page_t *, int, int, int *)); /* Put (write) page. */ 61a316d390SJohn Dyson boolean_t (*pgo_haspage) __P((vm_object_t, vm_pindex_t, int *, int *)); /* Does pager have page? */ 621c7c3c6aSMatthew Dillon void (*pgo_pageunswapped) __P((vm_page_t)); 630b441832SPoul-Henning Kamp void (*pgo_strategy) __P((vm_object_t, struct bio *)); 64df8bae1dSRodney W. Grimes }; 65df8bae1dSRodney W. Grimes 66df8bae1dSRodney W. Grimes /* 67df8bae1dSRodney W. Grimes * get/put return values 68df8bae1dSRodney W. Grimes * OK operation was successful 69df8bae1dSRodney W. Grimes * BAD specified data was out of the accepted range 70df8bae1dSRodney W. Grimes * FAIL specified data was in range, but doesn't exist 71df8bae1dSRodney W. Grimes * PEND operations was initiated but not completed 72df8bae1dSRodney W. Grimes * ERROR error while accessing data that is in range and exists 73df8bae1dSRodney W. Grimes * AGAIN temporary resource shortage prevented operation from happening 74df8bae1dSRodney W. Grimes */ 75df8bae1dSRodney W. Grimes #define VM_PAGER_OK 0 76df8bae1dSRodney W. Grimes #define VM_PAGER_BAD 1 77df8bae1dSRodney W. Grimes #define VM_PAGER_FAIL 2 78df8bae1dSRodney W. Grimes #define VM_PAGER_PEND 3 79df8bae1dSRodney W. Grimes #define VM_PAGER_ERROR 4 80df8bae1dSRodney W. Grimes #define VM_PAGER_AGAIN 5 81df8bae1dSRodney W. Grimes 828f9110f6SJohn Dyson #define VM_PAGER_PUT_SYNC 0x1 838f9110f6SJohn Dyson #define VM_PAGER_PUT_INVAL 0x2 848f9110f6SJohn Dyson 85c4473420SPeter Wemm #ifdef _KERNEL 86a1c995b6SPoul-Henning Kamp 87a1c995b6SPoul-Henning Kamp #ifdef MALLOC_DECLARE 88a1c995b6SPoul-Henning Kamp MALLOC_DECLARE(M_VMPGDATA); 89a1c995b6SPoul-Henning Kamp #endif 90a1c995b6SPoul-Henning Kamp 9128f8db14SBruce Evans extern vm_map_t pager_map; 9228f8db14SBruce Evans extern int pager_map_size; 931c7c3c6aSMatthew Dillon extern struct pagerops *pagertab[]; 942a758ebeSAlfred Perlstein extern struct mtx pbuf_mtx; 9528f8db14SBruce Evans 966cde7a16SDavid Greenman vm_object_t vm_pager_allocate __P((objtype_t, void *, vm_ooffset_t, vm_prot_t, vm_ooffset_t)); 97b5e8ce9fSBruce Evans void vm_pager_bufferinit __P((void)); 9824a1cce3SDavid Greenman void vm_pager_deallocate __P((vm_object_t)); 991c7c3c6aSMatthew Dillon static __inline int vm_pager_get_pages __P((vm_object_t, vm_page_t *, int, int)); 1001c7c3c6aSMatthew Dillon static __inline boolean_t vm_pager_has_page __P((vm_object_t, vm_pindex_t, int *, int *)); 101df8bae1dSRodney W. Grimes void vm_pager_init __P((void)); 10224a1cce3SDavid Greenman vm_object_t vm_pager_object_lookup __P((struct pagerlst *, void *)); 103df8bae1dSRodney W. Grimes vm_offset_t vm_pager_map_pages __P((vm_page_t *, int, boolean_t)); 10405f0fdd2SPoul-Henning Kamp vm_offset_t vm_pager_map_page __P((vm_page_t)); 105df8bae1dSRodney W. Grimes void vm_pager_sync __P((void)); 106df8bae1dSRodney W. Grimes void vm_pager_unmap_pages __P((vm_offset_t, int)); 10705f0fdd2SPoul-Henning Kamp void vm_pager_unmap_page __P((vm_offset_t)); 1080b441832SPoul-Henning Kamp void vm_pager_strategy __P((vm_object_t object, struct bio *bp)); 1091c7c3c6aSMatthew Dillon 1104221e284SAlan Cox /* 1114221e284SAlan Cox * vm_page_get_pages: 1124221e284SAlan Cox * 1134221e284SAlan Cox * Retrieve pages from the VM system in order to map them into an object 1144221e284SAlan Cox * ( or into VM space somewhere ). If the pagein was successful, we 1154221e284SAlan Cox * must fully validate it. 1164221e284SAlan Cox */ 1174221e284SAlan Cox 1181c7c3c6aSMatthew Dillon static __inline int 1191c7c3c6aSMatthew Dillon vm_pager_get_pages( 1201c7c3c6aSMatthew Dillon vm_object_t object, 1211c7c3c6aSMatthew Dillon vm_page_t *m, 1221c7c3c6aSMatthew Dillon int count, 1231c7c3c6aSMatthew Dillon int reqpage 1241c7c3c6aSMatthew Dillon ) { 1254221e284SAlan Cox int r; 1264221e284SAlan Cox 1270cddd8f0SMatthew Dillon GIANT_REQUIRED; 1280cddd8f0SMatthew Dillon 1294221e284SAlan Cox r = (*pagertab[object->type]->pgo_getpages)(object, m, count, reqpage); 1304221e284SAlan Cox if (r == VM_PAGER_OK && m[reqpage]->valid != VM_PAGE_BITS_ALL) { 1314221e284SAlan Cox vm_page_zero_invalid(m[reqpage], TRUE); 1324221e284SAlan Cox } 1334221e284SAlan Cox return(r); 1341c7c3c6aSMatthew Dillon } 1351c7c3c6aSMatthew Dillon 136e4542174SMatthew Dillon static __inline void 1371c7c3c6aSMatthew Dillon vm_pager_put_pages( 1381c7c3c6aSMatthew Dillon vm_object_t object, 1391c7c3c6aSMatthew Dillon vm_page_t *m, 1401c7c3c6aSMatthew Dillon int count, 1411c7c3c6aSMatthew Dillon int flags, 1421c7c3c6aSMatthew Dillon int *rtvals 1431c7c3c6aSMatthew Dillon ) { 1440cddd8f0SMatthew Dillon GIANT_REQUIRED; 145e4542174SMatthew Dillon (*pagertab[object->type]->pgo_putpages) 146e4542174SMatthew Dillon (object, m, count, flags, rtvals); 1471c7c3c6aSMatthew Dillon } 1481c7c3c6aSMatthew Dillon 14925db2c54SMatthew Dillon /* 15025db2c54SMatthew Dillon * vm_pager_haspage 15125db2c54SMatthew Dillon * 15225db2c54SMatthew Dillon * Check to see if an object's pager has the requested page. The 15325db2c54SMatthew Dillon * object's pager will also set before and after to give the caller 15425db2c54SMatthew Dillon * some idea of the number of pages before and after the requested 15525db2c54SMatthew Dillon * page can be I/O'd efficiently. 15625db2c54SMatthew Dillon * 15725db2c54SMatthew Dillon * This routine does not have to be called at any particular spl. 15825db2c54SMatthew Dillon */ 15925db2c54SMatthew Dillon 1601c7c3c6aSMatthew Dillon static __inline boolean_t 1611c7c3c6aSMatthew Dillon vm_pager_has_page( 1621c7c3c6aSMatthew Dillon vm_object_t object, 1631c7c3c6aSMatthew Dillon vm_pindex_t offset, 1641c7c3c6aSMatthew Dillon int *before, 1651c7c3c6aSMatthew Dillon int *after 1661c7c3c6aSMatthew Dillon ) { 16723955314SAlfred Perlstein boolean_t ret; 16823955314SAlfred Perlstein 1690cddd8f0SMatthew Dillon GIANT_REQUIRED; 17023955314SAlfred Perlstein ret = (*pagertab[object->type]->pgo_haspage) 17123955314SAlfred Perlstein (object, offset, before, after); 17223955314SAlfred Perlstein return (ret); 1731c7c3c6aSMatthew Dillon } 1741c7c3c6aSMatthew Dillon 1751c7c3c6aSMatthew Dillon /* 1761c7c3c6aSMatthew Dillon * vm_pager_page_unswapped 1771c7c3c6aSMatthew Dillon * 1781c7c3c6aSMatthew Dillon * called at splvm() to destroy swap associated with the page. 1791c7c3c6aSMatthew Dillon * 1801c7c3c6aSMatthew Dillon * This function may not block. 1811c7c3c6aSMatthew Dillon */ 1821c7c3c6aSMatthew Dillon 1831c7c3c6aSMatthew Dillon static __inline void 1841c7c3c6aSMatthew Dillon vm_pager_page_unswapped(vm_page_t m) 1851c7c3c6aSMatthew Dillon { 1860cddd8f0SMatthew Dillon GIANT_REQUIRED; 1871c7c3c6aSMatthew Dillon if (pagertab[m->object->type]->pgo_pageunswapped) 1881c7c3c6aSMatthew Dillon (*pagertab[m->object->type]->pgo_pageunswapped)(m); 1891c7c3c6aSMatthew Dillon } 1901c7c3c6aSMatthew Dillon 191df8bae1dSRodney W. Grimes #endif 192df8bae1dSRodney W. Grimes 193df8bae1dSRodney W. Grimes #endif /* _VM_PAGER_ */ 194