160727d8bSWarner Losh /*- 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 * 4. Neither the name of the University nor the names of its contributors 19df8bae1dSRodney W. Grimes * may be used to endorse or promote products derived from this software 20df8bae1dSRodney W. Grimes * without specific prior written permission. 21df8bae1dSRodney W. Grimes * 22df8bae1dSRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23df8bae1dSRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24df8bae1dSRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25df8bae1dSRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26df8bae1dSRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27df8bae1dSRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28df8bae1dSRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29df8bae1dSRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30df8bae1dSRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31df8bae1dSRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32df8bae1dSRodney W. Grimes * SUCH DAMAGE. 33df8bae1dSRodney W. Grimes * 34df8bae1dSRodney W. Grimes * @(#)vm_pager.h 8.4 (Berkeley) 1/12/94 35c3aac50fSPeter Wemm * $FreeBSD$ 36df8bae1dSRodney W. Grimes */ 37df8bae1dSRodney W. Grimes 38df8bae1dSRodney W. Grimes /* 39df8bae1dSRodney W. Grimes * Pager routine interface definition. 40df8bae1dSRodney W. Grimes */ 41df8bae1dSRodney W. Grimes 42df8bae1dSRodney W. Grimes #ifndef _VM_PAGER_ 43df8bae1dSRodney W. Grimes #define _VM_PAGER_ 44df8bae1dSRodney W. Grimes 45e7a58978SBruce Evans #include <sys/queue.h> 46e7a58978SBruce Evans 47e3975643SJake Burkholder TAILQ_HEAD(pagerlst, vm_object); 48df8bae1dSRodney W. Grimes 490b441832SPoul-Henning Kamp struct bio; 50a5296b05SJulian Elischer 51d20b2f76SPoul-Henning Kamp typedef void pgo_init_t(void); 52d20b2f76SPoul-Henning Kamp typedef vm_object_t pgo_alloc_t(void *, vm_ooffset_t, vm_prot_t, vm_ooffset_t); 53d20b2f76SPoul-Henning Kamp typedef void pgo_dealloc_t(vm_object_t); 54d20b2f76SPoul-Henning Kamp typedef int pgo_getpages_t(vm_object_t, vm_page_t *, int, int); 55d20b2f76SPoul-Henning Kamp typedef void pgo_putpages_t(vm_object_t, vm_page_t *, int, int, int *); 56d20b2f76SPoul-Henning Kamp typedef boolean_t pgo_haspage_t(vm_object_t, vm_pindex_t, int *, int *); 57d20b2f76SPoul-Henning Kamp typedef void pgo_pageunswapped_t(vm_page_t); 58d20b2f76SPoul-Henning Kamp 59df8bae1dSRodney W. Grimes struct pagerops { 60d20b2f76SPoul-Henning Kamp pgo_init_t *pgo_init; /* Initialize pager. */ 61d20b2f76SPoul-Henning Kamp pgo_alloc_t *pgo_alloc; /* Allocate pager. */ 62d20b2f76SPoul-Henning Kamp pgo_dealloc_t *pgo_dealloc; /* Disassociate. */ 63d20b2f76SPoul-Henning Kamp pgo_getpages_t *pgo_getpages; /* Get (read) page. */ 64d20b2f76SPoul-Henning Kamp pgo_putpages_t *pgo_putpages; /* Put (write) page. */ 65d20b2f76SPoul-Henning Kamp pgo_haspage_t *pgo_haspage; /* Does pager have page? */ 66d20b2f76SPoul-Henning Kamp pgo_pageunswapped_t *pgo_pageunswapped; 67df8bae1dSRodney W. Grimes }; 68df8bae1dSRodney W. Grimes 69745f3305SPoul-Henning Kamp extern struct pagerops defaultpagerops; 70745f3305SPoul-Henning Kamp extern struct pagerops swappagerops; 71745f3305SPoul-Henning Kamp extern struct pagerops vnodepagerops; 72745f3305SPoul-Henning Kamp extern struct pagerops devicepagerops; 73745f3305SPoul-Henning Kamp extern struct pagerops physpagerops; 74745f3305SPoul-Henning Kamp 75df8bae1dSRodney W. Grimes /* 76df8bae1dSRodney W. Grimes * get/put return values 77df8bae1dSRodney W. Grimes * OK operation was successful 78df8bae1dSRodney W. Grimes * BAD specified data was out of the accepted range 79df8bae1dSRodney W. Grimes * FAIL specified data was in range, but doesn't exist 80df8bae1dSRodney W. Grimes * PEND operations was initiated but not completed 81df8bae1dSRodney W. Grimes * ERROR error while accessing data that is in range and exists 82df8bae1dSRodney W. Grimes * AGAIN temporary resource shortage prevented operation from happening 83df8bae1dSRodney W. Grimes */ 84df8bae1dSRodney W. Grimes #define VM_PAGER_OK 0 85df8bae1dSRodney W. Grimes #define VM_PAGER_BAD 1 86df8bae1dSRodney W. Grimes #define VM_PAGER_FAIL 2 87df8bae1dSRodney W. Grimes #define VM_PAGER_PEND 3 88df8bae1dSRodney W. Grimes #define VM_PAGER_ERROR 4 89df8bae1dSRodney W. Grimes #define VM_PAGER_AGAIN 5 90df8bae1dSRodney W. Grimes 9143b7990eSMatthew Dillon #define VM_PAGER_PUT_SYNC 0x0001 9243b7990eSMatthew Dillon #define VM_PAGER_PUT_INVAL 0x0002 9343b7990eSMatthew Dillon #define VM_PAGER_IGNORE_CLEANCHK 0x0004 9443b7990eSMatthew Dillon #define VM_PAGER_CLUSTER_OK 0x0008 958f9110f6SJohn Dyson 96c4473420SPeter Wemm #ifdef _KERNEL 97a1c995b6SPoul-Henning Kamp #ifdef MALLOC_DECLARE 98a1c995b6SPoul-Henning Kamp MALLOC_DECLARE(M_VMPGDATA); 99a1c995b6SPoul-Henning Kamp #endif 100a1c995b6SPoul-Henning Kamp 10128f8db14SBruce Evans extern vm_map_t pager_map; 1021c7c3c6aSMatthew Dillon extern struct pagerops *pagertab[]; 1032a758ebeSAlfred Perlstein extern struct mtx pbuf_mtx; 10428f8db14SBruce Evans 10511caded3SAlfred Perlstein vm_object_t vm_pager_allocate(objtype_t, void *, vm_ooffset_t, vm_prot_t, vm_ooffset_t); 10611caded3SAlfred Perlstein void vm_pager_bufferinit(void); 10711caded3SAlfred Perlstein void vm_pager_deallocate(vm_object_t); 10811caded3SAlfred Perlstein static __inline int vm_pager_get_pages(vm_object_t, vm_page_t *, int, int); 10911caded3SAlfred Perlstein static __inline boolean_t vm_pager_has_page(vm_object_t, vm_pindex_t, int *, int *); 11011caded3SAlfred Perlstein void vm_pager_init(void); 11111caded3SAlfred Perlstein vm_object_t vm_pager_object_lookup(struct pagerlst *, void *); 1121c7c3c6aSMatthew Dillon 1134221e284SAlan Cox /* 1144221e284SAlan Cox * vm_page_get_pages: 1154221e284SAlan Cox * 1164221e284SAlan Cox * Retrieve pages from the VM system in order to map them into an object 1174221e284SAlan Cox * ( or into VM space somewhere ). If the pagein was successful, we 1184221e284SAlan Cox * must fully validate it. 1194221e284SAlan Cox */ 1201c7c3c6aSMatthew Dillon static __inline int 1211c7c3c6aSMatthew Dillon vm_pager_get_pages( 1221c7c3c6aSMatthew Dillon vm_object_t object, 1231c7c3c6aSMatthew Dillon vm_page_t *m, 1241c7c3c6aSMatthew Dillon int count, 1251c7c3c6aSMatthew Dillon int reqpage 1261c7c3c6aSMatthew Dillon ) { 1274221e284SAlan Cox int r; 1284221e284SAlan Cox 129f566a0b6SAlan Cox VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); 1304221e284SAlan Cox r = (*pagertab[object->type]->pgo_getpages)(object, m, count, reqpage); 1314221e284SAlan Cox if (r == VM_PAGER_OK && m[reqpage]->valid != VM_PAGE_BITS_ALL) { 1324221e284SAlan Cox vm_page_zero_invalid(m[reqpage], TRUE); 1334221e284SAlan Cox } 1344221e284SAlan Cox return (r); 1351c7c3c6aSMatthew Dillon } 1361c7c3c6aSMatthew Dillon 137e4542174SMatthew Dillon static __inline void 1381c7c3c6aSMatthew Dillon vm_pager_put_pages( 1391c7c3c6aSMatthew Dillon vm_object_t object, 1401c7c3c6aSMatthew Dillon vm_page_t *m, 1411c7c3c6aSMatthew Dillon int count, 1421c7c3c6aSMatthew Dillon int flags, 1431c7c3c6aSMatthew Dillon int *rtvals 1441c7c3c6aSMatthew Dillon ) { 1452e3b314dSAlan Cox 1462e3b314dSAlan Cox VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); 147e4542174SMatthew Dillon (*pagertab[object->type]->pgo_putpages) 148e4542174SMatthew Dillon (object, m, count, flags, rtvals); 1491c7c3c6aSMatthew Dillon } 1501c7c3c6aSMatthew Dillon 15125db2c54SMatthew Dillon /* 15225db2c54SMatthew Dillon * vm_pager_haspage 15325db2c54SMatthew Dillon * 15425db2c54SMatthew Dillon * Check to see if an object's pager has the requested page. The 15525db2c54SMatthew Dillon * object's pager will also set before and after to give the caller 15625db2c54SMatthew Dillon * some idea of the number of pages before and after the requested 15725db2c54SMatthew Dillon * page can be I/O'd efficiently. 15825db2c54SMatthew Dillon * 159cf51adc0SAlan Cox * The object must be locked. 16025db2c54SMatthew Dillon */ 1611c7c3c6aSMatthew Dillon static __inline boolean_t 1621c7c3c6aSMatthew Dillon vm_pager_has_page( 1631c7c3c6aSMatthew Dillon vm_object_t object, 1641c7c3c6aSMatthew Dillon vm_pindex_t offset, 1651c7c3c6aSMatthew Dillon int *before, 1661c7c3c6aSMatthew Dillon int *after 1671c7c3c6aSMatthew Dillon ) { 16823955314SAlfred Perlstein boolean_t ret; 16923955314SAlfred Perlstein 170f29ba63eSAlan Cox VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); 17123955314SAlfred Perlstein ret = (*pagertab[object->type]->pgo_haspage) 17223955314SAlfred Perlstein (object, offset, before, after); 17323955314SAlfred Perlstein return (ret); 1741c7c3c6aSMatthew Dillon } 1751c7c3c6aSMatthew Dillon 1761c7c3c6aSMatthew Dillon /* 1771c7c3c6aSMatthew Dillon * vm_pager_page_unswapped 1781c7c3c6aSMatthew Dillon * 179cf51adc0SAlan Cox * Destroy swap associated with the page. 1801c7c3c6aSMatthew Dillon * 181cf51adc0SAlan Cox * The object containing the page must be locked. 1821c7c3c6aSMatthew Dillon * This function may not block. 183f976cfd9SPoul-Henning Kamp * 184f976cfd9SPoul-Henning Kamp * XXX: A much better name would be "vm_pager_page_dirtied()" 185f976cfd9SPoul-Henning Kamp * XXX: It is not obvious if this could be profitably used by any 186f976cfd9SPoul-Henning Kamp * XXX: pagers besides the swap_pager or if it should even be a 187f976cfd9SPoul-Henning Kamp * XXX: generic pager_op in the first place. 1881c7c3c6aSMatthew Dillon */ 1891c7c3c6aSMatthew Dillon static __inline void 1901c7c3c6aSMatthew Dillon vm_pager_page_unswapped(vm_page_t m) 1911c7c3c6aSMatthew Dillon { 1922e3b314dSAlan Cox 1932e3b314dSAlan Cox VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); 1941c7c3c6aSMatthew Dillon if (pagertab[m->object->type]->pgo_pageunswapped) 1951c7c3c6aSMatthew Dillon (*pagertab[m->object->type]->pgo_pageunswapped)(m); 1961c7c3c6aSMatthew Dillon } 1971c7c3c6aSMatthew Dillon 198a1287949SEivind Eklund #endif /* _KERNEL */ 199df8bae1dSRodney W. Grimes #endif /* _VM_PAGER_ */ 200