10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*12230SFrank.Rival@oracle.com * Common Development and Distribution License (the "License"). 6*12230SFrank.Rival@oracle.com * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* 22*12230SFrank.Rival@oracle.com * Copyright (c) 1987, 2010, Oracle and/or its affiliates. All rights reserved. 230Sstevel@tonic-gate */ 240Sstevel@tonic-gate 250Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 260Sstevel@tonic-gate /* All Rights Reserved */ 270Sstevel@tonic-gate 280Sstevel@tonic-gate /* 290Sstevel@tonic-gate * University Copyright- Copyright (c) 1982, 1986, 1988 300Sstevel@tonic-gate * The Regents of the University of California 310Sstevel@tonic-gate * All Rights Reserved 320Sstevel@tonic-gate * 330Sstevel@tonic-gate * University Acknowledgment- Portions of this document are derived from 340Sstevel@tonic-gate * software developed by the University of California, Berkeley, and its 350Sstevel@tonic-gate * contributors. 360Sstevel@tonic-gate */ 370Sstevel@tonic-gate 380Sstevel@tonic-gate #ifndef _SYS_SWAP_H 390Sstevel@tonic-gate #define _SYS_SWAP_H 400Sstevel@tonic-gate 410Sstevel@tonic-gate #include <sys/isa_defs.h> 420Sstevel@tonic-gate #include <sys/feature_tests.h> 430Sstevel@tonic-gate #include <vm/anon.h> 440Sstevel@tonic-gate #include <sys/fs/swapnode.h> 450Sstevel@tonic-gate 460Sstevel@tonic-gate #ifdef __cplusplus 470Sstevel@tonic-gate extern "C" { 480Sstevel@tonic-gate #endif 490Sstevel@tonic-gate 500Sstevel@tonic-gate #if !defined(_LP64) && _FILE_OFFSET_BITS == 64 510Sstevel@tonic-gate #error "Cannot use swapctl in the large files compilation environment" 520Sstevel@tonic-gate #endif 530Sstevel@tonic-gate 540Sstevel@tonic-gate /* The following are for the swapctl system call */ 550Sstevel@tonic-gate 560Sstevel@tonic-gate #define SC_ADD 1 /* add a specified resource for swapping */ 570Sstevel@tonic-gate #define SC_LIST 2 /* list all the swapping resources */ 580Sstevel@tonic-gate #define SC_REMOVE 3 /* remove the specified swapping resource */ 590Sstevel@tonic-gate #define SC_GETNSWP 4 /* get number of swap resources configured */ 600Sstevel@tonic-gate #define SC_AINFO 5 /* get anonymous memory resource information */ 610Sstevel@tonic-gate 620Sstevel@tonic-gate typedef struct swapres { 630Sstevel@tonic-gate char *sr_name; /* pathname of the resource specified */ 640Sstevel@tonic-gate off_t sr_start; /* starting offset of the swapping resource */ 650Sstevel@tonic-gate off_t sr_length; /* length of the swap area */ 660Sstevel@tonic-gate } swapres_t; 670Sstevel@tonic-gate 680Sstevel@tonic-gate typedef struct swapent { 690Sstevel@tonic-gate char *ste_path; /* get the name of the swap file */ 700Sstevel@tonic-gate off_t ste_start; /* starting block for swapping */ 710Sstevel@tonic-gate off_t ste_length; /* length of swap area */ 720Sstevel@tonic-gate long ste_pages; /* numbers of pages for swapping */ 730Sstevel@tonic-gate long ste_free; /* numbers of ste_pages free */ 740Sstevel@tonic-gate int ste_flags; /* see below */ 750Sstevel@tonic-gate } swapent_t; 760Sstevel@tonic-gate 770Sstevel@tonic-gate typedef struct swaptable { 780Sstevel@tonic-gate int swt_n; /* number of swapents following */ 790Sstevel@tonic-gate struct swapent swt_ent[1]; /* array of swt_n swapents */ 800Sstevel@tonic-gate } swaptbl_t; 810Sstevel@tonic-gate 820Sstevel@tonic-gate 830Sstevel@tonic-gate #if defined(_SYSCALL32) 840Sstevel@tonic-gate 850Sstevel@tonic-gate /* Kernel's view of user ILP32 swapres and swapent structures */ 860Sstevel@tonic-gate 870Sstevel@tonic-gate typedef struct swapres32 { 880Sstevel@tonic-gate caddr32_t sr_name; /* pathname of the resource specified */ 890Sstevel@tonic-gate off32_t sr_start; /* starting offset of the swapping resource */ 900Sstevel@tonic-gate off32_t sr_length; /* length of the swap area */ 910Sstevel@tonic-gate } swapres32_t; 920Sstevel@tonic-gate 930Sstevel@tonic-gate typedef struct swapent32 { 940Sstevel@tonic-gate caddr32_t ste_path; /* get the name of the swap file */ 950Sstevel@tonic-gate off32_t ste_start; /* starting block for swapping */ 960Sstevel@tonic-gate off32_t ste_length; /* length of swap area */ 970Sstevel@tonic-gate int32_t ste_pages; /* numbers of pages for swapping */ 980Sstevel@tonic-gate int32_t ste_free; /* numbers of ste_pages free */ 990Sstevel@tonic-gate int32_t ste_flags; /* see below */ 1000Sstevel@tonic-gate } swapent32_t; 1010Sstevel@tonic-gate 1020Sstevel@tonic-gate typedef struct swaptable32 { 1030Sstevel@tonic-gate int32_t swt_n; /* number of swapents following */ 1040Sstevel@tonic-gate struct swapent32 swt_ent[1]; /* array of swt_n swapents */ 1050Sstevel@tonic-gate } swaptbl32_t; 1060Sstevel@tonic-gate 1070Sstevel@tonic-gate #endif /* _SYSCALL32 */ 1080Sstevel@tonic-gate 1090Sstevel@tonic-gate #if defined(_KERNEL) 1100Sstevel@tonic-gate extern int swapctl(int, void *, int *); 1110Sstevel@tonic-gate #if defined(_LP64) && defined(_SYSCALL32) 1120Sstevel@tonic-gate extern int swapctl32(int, void *, int *); 1130Sstevel@tonic-gate #endif /* _LP64 && _SYSCALL32 */ 1140Sstevel@tonic-gate #else /* !_KERNEL */ 1150Sstevel@tonic-gate #if defined(__STDC__) 1160Sstevel@tonic-gate extern int swapctl(int, void *); 1170Sstevel@tonic-gate #else 1180Sstevel@tonic-gate extern int swapctl(); 1190Sstevel@tonic-gate #endif 1200Sstevel@tonic-gate #endif /* _KERNEL */ 1210Sstevel@tonic-gate 1220Sstevel@tonic-gate 1230Sstevel@tonic-gate /* ste_flags values */ 1240Sstevel@tonic-gate 1250Sstevel@tonic-gate #define ST_INDEL 0x01 /* Deletion of file is in progress. */ 1260Sstevel@tonic-gate /* Prevents others from deleting or */ 1270Sstevel@tonic-gate /* allocating from it */ 1280Sstevel@tonic-gate #define ST_DOINGDEL 0x02 /* Set during deletion of file */ 1290Sstevel@tonic-gate /* Clearing during deletion signals */ 1300Sstevel@tonic-gate /* that you want to add the file back */ 1310Sstevel@tonic-gate /* again, and will eventually cause */ 1320Sstevel@tonic-gate /* it to be added back */ 1330Sstevel@tonic-gate 1340Sstevel@tonic-gate /* 1350Sstevel@tonic-gate * VM - virtual swap device. 1360Sstevel@tonic-gate */ 1370Sstevel@tonic-gate struct swapinfo { 1380Sstevel@tonic-gate ulong_t si_soff; /* starting offset (bytes) of file */ 1390Sstevel@tonic-gate ulong_t si_eoff; /* ending offset (bytes) of file */ 1400Sstevel@tonic-gate struct vnode *si_vp; /* vnode (commonvp if device) */ 1410Sstevel@tonic-gate struct swapinfo *si_next; /* next swap area */ 1420Sstevel@tonic-gate int si_allocs; /* # of conseq. allocs from this area */ 1430Sstevel@tonic-gate short si_flags; /* flags defined below */ 1440Sstevel@tonic-gate pgcnt_t si_npgs; /* number of pages of swap space */ 1450Sstevel@tonic-gate pgcnt_t si_nfpgs; /* number of free pages of swap space */ 1460Sstevel@tonic-gate int si_pnamelen; /* swap file name length + 1 */ 1470Sstevel@tonic-gate char *si_pname; /* swap file name */ 1480Sstevel@tonic-gate ssize_t si_mapsize; /* # bytes allocated for bitmap */ 1490Sstevel@tonic-gate uint_t *si_swapslots; /* bitmap of slots, unset == free */ 1500Sstevel@tonic-gate pgcnt_t si_hint; /* first page to check if free */ 1510Sstevel@tonic-gate ssize_t si_checkcnt; /* # of checks to find freeslot */ 1520Sstevel@tonic-gate ssize_t si_alloccnt; /* used to find ave checks */ 1530Sstevel@tonic-gate }; 1540Sstevel@tonic-gate 1550Sstevel@tonic-gate /* 1560Sstevel@tonic-gate * Stuff to convert an anon slot pointer to a page name. 1570Sstevel@tonic-gate * Because the address of the slot (ap) is a unique identifier, we 158*12230SFrank.Rival@oracle.com * use it to generate a unique (vp,off), as shown in the comment for 159*12230SFrank.Rival@oracle.com * swap_alloc(). 1600Sstevel@tonic-gate * 1610Sstevel@tonic-gate * The off bits are shifted PAGESHIFT to directly form a page aligned 1620Sstevel@tonic-gate * offset; the vp index bits map 1-1 to a vnode. 1630Sstevel@tonic-gate * 1640Sstevel@tonic-gate */ 165*12230SFrank.Rival@oracle.com #define MAX_SWAP_VNODES_LOG2 11 /* log2(MAX_SWAP_VNODES) */ 166*12230SFrank.Rival@oracle.com #define MAX_SWAP_VNODES (1U << MAX_SWAP_VNODES_LOG2) /* max # swap vnodes */ 167*12230SFrank.Rival@oracle.com #define AN_VPMASK (MAX_SWAP_VNODES - 1) /* vp index mask */ 168*12230SFrank.Rival@oracle.com #define AN_VPSHIFT MAX_SWAP_VNODES_LOG2 1690Sstevel@tonic-gate /* 1700Sstevel@tonic-gate * Convert from an anon slot to associated vnode and offset. 1710Sstevel@tonic-gate */ 1720Sstevel@tonic-gate #define swap_xlate(AP, VPP, OFFP) \ 1730Sstevel@tonic-gate { \ 1740Sstevel@tonic-gate *(VPP) = (AP)->an_vp; \ 1750Sstevel@tonic-gate *(OFFP) = (AP)->an_off; \ 1760Sstevel@tonic-gate } 1770Sstevel@tonic-gate #define swap_xlate_nopanic swap_xlate 1780Sstevel@tonic-gate 1790Sstevel@tonic-gate /* 1800Sstevel@tonic-gate * Get a vnode name for an anon slot. 1810Sstevel@tonic-gate * The vnum, offset are derived from anon struct address which is 182*12230SFrank.Rival@oracle.com * 16 bytes aligned. anon structs may be kmem_cache_alloc'd concurrently by 183*12230SFrank.Rival@oracle.com * multiple threads and come from a small range of addresses (same slab), in 184*12230SFrank.Rival@oracle.com * which case high order AP bits do not vary much, so choose vnum from low 185*12230SFrank.Rival@oracle.com * order bits which vary the most. Different threads will thus get different 186*12230SFrank.Rival@oracle.com * vnums and vnodes, which avoids vph_mutex_contention on the subsequent 187*12230SFrank.Rival@oracle.com * page_hashin(). 1880Sstevel@tonic-gate * 189*12230SFrank.Rival@oracle.com * +-----------...-------------------+-----------------------+----+ 190*12230SFrank.Rival@oracle.com * | swap offset | vnum |0000| 191*12230SFrank.Rival@oracle.com * +-----------...-------------------+-----------------------+----+ 192*12230SFrank.Rival@oracle.com * 63 15 14 4 3 0 1930Sstevel@tonic-gate */ 1940Sstevel@tonic-gate #define swap_alloc(AP) \ 1950Sstevel@tonic-gate { \ 196*12230SFrank.Rival@oracle.com (AP)->an_vp = swapfs_getvp(((uintptr_t)(AP) >> AN_CACHE_ALIGN_LOG2) \ 197*12230SFrank.Rival@oracle.com & AN_VPMASK); \ 198*12230SFrank.Rival@oracle.com (AP)->an_off = (anoff_t)((((uintptr_t)(AP)) >> \ 199*12230SFrank.Rival@oracle.com AN_VPSHIFT + AN_CACHE_ALIGN_LOG2) << PAGESHIFT); \ 2000Sstevel@tonic-gate } 2010Sstevel@tonic-gate 2020Sstevel@tonic-gate /* 2030Sstevel@tonic-gate * Free the page name for the specified anon slot. 2040Sstevel@tonic-gate * For now there's nothing to do. 2050Sstevel@tonic-gate */ 2060Sstevel@tonic-gate #define swap_free(AP) 2070Sstevel@tonic-gate 2080Sstevel@tonic-gate /* Flags for swap_phys_alloc */ 2090Sstevel@tonic-gate #define SA_NOT 0x01 /* Must have slot from swap dev other than input one */ 2100Sstevel@tonic-gate 2110Sstevel@tonic-gate /* Special error codes for swap_newphysname() */ 2120Sstevel@tonic-gate #define SE_NOSWAP -1 /* No physical swap slots available */ 2130Sstevel@tonic-gate #define SE_NOANON -2 /* No anon slot for swap slot */ 2140Sstevel@tonic-gate 2150Sstevel@tonic-gate #ifdef _KERNEL 2160Sstevel@tonic-gate extern struct anon *swap_anon(struct vnode *vp, u_offset_t off); 2170Sstevel@tonic-gate extern int swap_phys_alloc(struct vnode **vpp, u_offset_t *offp, size_t *lenp, 2180Sstevel@tonic-gate uint_t flags); 2190Sstevel@tonic-gate extern void swap_phys_free(struct vnode *vp, u_offset_t off, size_t len); 2200Sstevel@tonic-gate extern int swap_getphysname(struct vnode *vp, u_offset_t off, 2210Sstevel@tonic-gate struct vnode **pvpp, u_offset_t *poffp); 2220Sstevel@tonic-gate extern int swap_newphysname(struct vnode *vp, u_offset_t offset, 2230Sstevel@tonic-gate u_offset_t *offp, size_t *lenp, struct vnode **pvpp, u_offset_t *poffp); 2240Sstevel@tonic-gate 2250Sstevel@tonic-gate extern struct swapinfo *swapinfo; 2260Sstevel@tonic-gate extern int swap_debug; 2270Sstevel@tonic-gate #endif /* _KERNEL */ 2280Sstevel@tonic-gate 2290Sstevel@tonic-gate #ifdef SWAP_DEBUG 2300Sstevel@tonic-gate #define SW_RENAME 0x01 2310Sstevel@tonic-gate #define SW_RESV 0x02 2320Sstevel@tonic-gate #define SW_ALLOC 0x04 2330Sstevel@tonic-gate #define SW_CTL 0x08 2340Sstevel@tonic-gate #define SWAP_PRINT(f, s, x1, x2, x3, x4, x5) \ 2350Sstevel@tonic-gate if (swap_debug & f) \ 2360Sstevel@tonic-gate printf(s, x1, x2, x3, x4, x5); 2370Sstevel@tonic-gate #else /* SWAP_DEBUG */ 2380Sstevel@tonic-gate #define SWAP_PRINT(f, s, x1, x2, x3, x4, x5) 2390Sstevel@tonic-gate #endif /* SWAP_DEBUG */ 2400Sstevel@tonic-gate 2410Sstevel@tonic-gate #ifdef __cplusplus 2420Sstevel@tonic-gate } 2430Sstevel@tonic-gate #endif 2440Sstevel@tonic-gate 2450Sstevel@tonic-gate #endif /* _SYS_SWAP_H */ 246