1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*0Sstevel@tonic-gate * Use is subject to license terms. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 28*0Sstevel@tonic-gate /* All Rights Reserved */ 29*0Sstevel@tonic-gate 30*0Sstevel@tonic-gate /* 31*0Sstevel@tonic-gate * University Copyright- Copyright (c) 1982, 1986, 1988 32*0Sstevel@tonic-gate * The Regents of the University of California 33*0Sstevel@tonic-gate * All Rights Reserved 34*0Sstevel@tonic-gate * 35*0Sstevel@tonic-gate * University Acknowledgment- Portions of this document are derived from 36*0Sstevel@tonic-gate * software developed by the University of California, Berkeley, and its 37*0Sstevel@tonic-gate * contributors. 38*0Sstevel@tonic-gate */ 39*0Sstevel@tonic-gate 40*0Sstevel@tonic-gate #ifndef _SYS_SWAP_H 41*0Sstevel@tonic-gate #define _SYS_SWAP_H 42*0Sstevel@tonic-gate 43*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 44*0Sstevel@tonic-gate 45*0Sstevel@tonic-gate #include <sys/isa_defs.h> 46*0Sstevel@tonic-gate #include <sys/feature_tests.h> 47*0Sstevel@tonic-gate #include <vm/anon.h> 48*0Sstevel@tonic-gate #include <sys/fs/swapnode.h> 49*0Sstevel@tonic-gate 50*0Sstevel@tonic-gate #ifdef __cplusplus 51*0Sstevel@tonic-gate extern "C" { 52*0Sstevel@tonic-gate #endif 53*0Sstevel@tonic-gate 54*0Sstevel@tonic-gate #if !defined(_LP64) && _FILE_OFFSET_BITS == 64 55*0Sstevel@tonic-gate #error "Cannot use swapctl in the large files compilation environment" 56*0Sstevel@tonic-gate #endif 57*0Sstevel@tonic-gate 58*0Sstevel@tonic-gate /* The following are for the swapctl system call */ 59*0Sstevel@tonic-gate 60*0Sstevel@tonic-gate #define SC_ADD 1 /* add a specified resource for swapping */ 61*0Sstevel@tonic-gate #define SC_LIST 2 /* list all the swapping resources */ 62*0Sstevel@tonic-gate #define SC_REMOVE 3 /* remove the specified swapping resource */ 63*0Sstevel@tonic-gate #define SC_GETNSWP 4 /* get number of swap resources configured */ 64*0Sstevel@tonic-gate #define SC_AINFO 5 /* get anonymous memory resource information */ 65*0Sstevel@tonic-gate 66*0Sstevel@tonic-gate typedef struct swapres { 67*0Sstevel@tonic-gate char *sr_name; /* pathname of the resource specified */ 68*0Sstevel@tonic-gate off_t sr_start; /* starting offset of the swapping resource */ 69*0Sstevel@tonic-gate off_t sr_length; /* length of the swap area */ 70*0Sstevel@tonic-gate } swapres_t; 71*0Sstevel@tonic-gate 72*0Sstevel@tonic-gate typedef struct swapent { 73*0Sstevel@tonic-gate char *ste_path; /* get the name of the swap file */ 74*0Sstevel@tonic-gate off_t ste_start; /* starting block for swapping */ 75*0Sstevel@tonic-gate off_t ste_length; /* length of swap area */ 76*0Sstevel@tonic-gate long ste_pages; /* numbers of pages for swapping */ 77*0Sstevel@tonic-gate long ste_free; /* numbers of ste_pages free */ 78*0Sstevel@tonic-gate int ste_flags; /* see below */ 79*0Sstevel@tonic-gate } swapent_t; 80*0Sstevel@tonic-gate 81*0Sstevel@tonic-gate typedef struct swaptable { 82*0Sstevel@tonic-gate int swt_n; /* number of swapents following */ 83*0Sstevel@tonic-gate struct swapent swt_ent[1]; /* array of swt_n swapents */ 84*0Sstevel@tonic-gate } swaptbl_t; 85*0Sstevel@tonic-gate 86*0Sstevel@tonic-gate 87*0Sstevel@tonic-gate #if defined(_SYSCALL32) 88*0Sstevel@tonic-gate 89*0Sstevel@tonic-gate /* Kernel's view of user ILP32 swapres and swapent structures */ 90*0Sstevel@tonic-gate 91*0Sstevel@tonic-gate typedef struct swapres32 { 92*0Sstevel@tonic-gate caddr32_t sr_name; /* pathname of the resource specified */ 93*0Sstevel@tonic-gate off32_t sr_start; /* starting offset of the swapping resource */ 94*0Sstevel@tonic-gate off32_t sr_length; /* length of the swap area */ 95*0Sstevel@tonic-gate } swapres32_t; 96*0Sstevel@tonic-gate 97*0Sstevel@tonic-gate typedef struct swapent32 { 98*0Sstevel@tonic-gate caddr32_t ste_path; /* get the name of the swap file */ 99*0Sstevel@tonic-gate off32_t ste_start; /* starting block for swapping */ 100*0Sstevel@tonic-gate off32_t ste_length; /* length of swap area */ 101*0Sstevel@tonic-gate int32_t ste_pages; /* numbers of pages for swapping */ 102*0Sstevel@tonic-gate int32_t ste_free; /* numbers of ste_pages free */ 103*0Sstevel@tonic-gate int32_t ste_flags; /* see below */ 104*0Sstevel@tonic-gate } swapent32_t; 105*0Sstevel@tonic-gate 106*0Sstevel@tonic-gate typedef struct swaptable32 { 107*0Sstevel@tonic-gate int32_t swt_n; /* number of swapents following */ 108*0Sstevel@tonic-gate struct swapent32 swt_ent[1]; /* array of swt_n swapents */ 109*0Sstevel@tonic-gate } swaptbl32_t; 110*0Sstevel@tonic-gate 111*0Sstevel@tonic-gate #endif /* _SYSCALL32 */ 112*0Sstevel@tonic-gate 113*0Sstevel@tonic-gate #if defined(_KERNEL) 114*0Sstevel@tonic-gate extern int swapctl(int, void *, int *); 115*0Sstevel@tonic-gate #if defined(_LP64) && defined(_SYSCALL32) 116*0Sstevel@tonic-gate extern int swapctl32(int, void *, int *); 117*0Sstevel@tonic-gate #endif /* _LP64 && _SYSCALL32 */ 118*0Sstevel@tonic-gate #else /* !_KERNEL */ 119*0Sstevel@tonic-gate #if defined(__STDC__) 120*0Sstevel@tonic-gate extern int swapctl(int, void *); 121*0Sstevel@tonic-gate #else 122*0Sstevel@tonic-gate extern int swapctl(); 123*0Sstevel@tonic-gate #endif 124*0Sstevel@tonic-gate #endif /* _KERNEL */ 125*0Sstevel@tonic-gate 126*0Sstevel@tonic-gate 127*0Sstevel@tonic-gate /* ste_flags values */ 128*0Sstevel@tonic-gate 129*0Sstevel@tonic-gate #define ST_INDEL 0x01 /* Deletion of file is in progress. */ 130*0Sstevel@tonic-gate /* Prevents others from deleting or */ 131*0Sstevel@tonic-gate /* allocating from it */ 132*0Sstevel@tonic-gate #define ST_DOINGDEL 0x02 /* Set during deletion of file */ 133*0Sstevel@tonic-gate /* Clearing during deletion signals */ 134*0Sstevel@tonic-gate /* that you want to add the file back */ 135*0Sstevel@tonic-gate /* again, and will eventually cause */ 136*0Sstevel@tonic-gate /* it to be added back */ 137*0Sstevel@tonic-gate 138*0Sstevel@tonic-gate /* 139*0Sstevel@tonic-gate * VM - virtual swap device. 140*0Sstevel@tonic-gate */ 141*0Sstevel@tonic-gate struct swapinfo { 142*0Sstevel@tonic-gate ulong_t si_soff; /* starting offset (bytes) of file */ 143*0Sstevel@tonic-gate ulong_t si_eoff; /* ending offset (bytes) of file */ 144*0Sstevel@tonic-gate struct vnode *si_vp; /* vnode (commonvp if device) */ 145*0Sstevel@tonic-gate struct swapinfo *si_next; /* next swap area */ 146*0Sstevel@tonic-gate int si_allocs; /* # of conseq. allocs from this area */ 147*0Sstevel@tonic-gate short si_flags; /* flags defined below */ 148*0Sstevel@tonic-gate pgcnt_t si_npgs; /* number of pages of swap space */ 149*0Sstevel@tonic-gate pgcnt_t si_nfpgs; /* number of free pages of swap space */ 150*0Sstevel@tonic-gate int si_pnamelen; /* swap file name length + 1 */ 151*0Sstevel@tonic-gate char *si_pname; /* swap file name */ 152*0Sstevel@tonic-gate ssize_t si_mapsize; /* # bytes allocated for bitmap */ 153*0Sstevel@tonic-gate uint_t *si_swapslots; /* bitmap of slots, unset == free */ 154*0Sstevel@tonic-gate pgcnt_t si_hint; /* first page to check if free */ 155*0Sstevel@tonic-gate ssize_t si_checkcnt; /* # of checks to find freeslot */ 156*0Sstevel@tonic-gate ssize_t si_alloccnt; /* used to find ave checks */ 157*0Sstevel@tonic-gate }; 158*0Sstevel@tonic-gate 159*0Sstevel@tonic-gate /* 160*0Sstevel@tonic-gate * Stuff to convert an anon slot pointer to a page name. 161*0Sstevel@tonic-gate * Because the address of the slot (ap) is a unique identifier, we 162*0Sstevel@tonic-gate * use it to generate a unique (vp,off), as shown below. 163*0Sstevel@tonic-gate * 164*0Sstevel@tonic-gate * |<-- 11 bits -->|<------32 - 11 --------->| 165*0Sstevel@tonic-gate * vp index bits off bits 166*0Sstevel@tonic-gate * 167*0Sstevel@tonic-gate * The off bits are shifted PAGESHIFT to directly form a page aligned 168*0Sstevel@tonic-gate * offset; the vp index bits map 1-1 to a vnode. 169*0Sstevel@tonic-gate * 170*0Sstevel@tonic-gate * Note: if we go to 64 bit offsets, we could use all the bits as the 171*0Sstevel@tonic-gate * unique offset and just have one vnode. 172*0Sstevel@tonic-gate */ 173*0Sstevel@tonic-gate #define AN_OFFSHIFT 11 /* vnum # bits */ 174*0Sstevel@tonic-gate #define AN_VPSHIFT 21 /* 32 - 11 */ 175*0Sstevel@tonic-gate #define AN_VPSIZEMASK 0x7FF /* vp index mask */ 176*0Sstevel@tonic-gate #define MAX_SWAP_VNODES 2048 /* 1 << AN_OFFSHIFT */ 177*0Sstevel@tonic-gate #define AN_CACHE_ALIGN 16 /* anon address aligned */ 178*0Sstevel@tonic-gate /* 16 bytes */ 179*0Sstevel@tonic-gate /* 180*0Sstevel@tonic-gate * Convert from an anon slot to associated vnode and offset. 181*0Sstevel@tonic-gate */ 182*0Sstevel@tonic-gate #define swap_xlate(AP, VPP, OFFP) \ 183*0Sstevel@tonic-gate { \ 184*0Sstevel@tonic-gate *(VPP) = (AP)->an_vp; \ 185*0Sstevel@tonic-gate *(OFFP) = (AP)->an_off; \ 186*0Sstevel@tonic-gate } 187*0Sstevel@tonic-gate #define swap_xlate_nopanic swap_xlate 188*0Sstevel@tonic-gate 189*0Sstevel@tonic-gate /* 190*0Sstevel@tonic-gate * Get a vnode name for an anon slot. 191*0Sstevel@tonic-gate * The vnum, offset are derived from anon struct address which is 192*0Sstevel@tonic-gate * 16 bytes aligned. To get swap offset the anon address is shifted 193*0Sstevel@tonic-gate * by additional 11 bits which yields 32K aligned swap offset 194*0Sstevel@tonic-gate * (11 bits plus 4 bits alignment). 195*0Sstevel@tonic-gate * The vnum (vnode index) is created from bits 31-21. 196*0Sstevel@tonic-gate * The 64 bit swap offset is created from bits 63-32 and 20-4. 197*0Sstevel@tonic-gate * The 32 bit offset is created from bits 20-4. 198*0Sstevel@tonic-gate * 199*0Sstevel@tonic-gate * +-----------...----------+--------+-----------------------+----+ 200*0Sstevel@tonic-gate * | swap offset | vnum | swap offset |0000| 201*0Sstevel@tonic-gate * +-----------...----------+--------+-----------------------+----+ 202*0Sstevel@tonic-gate * 63 32 31 21 20 4 3 0 203*0Sstevel@tonic-gate */ 204*0Sstevel@tonic-gate #define swap_alloc(AP) \ 205*0Sstevel@tonic-gate { \ 206*0Sstevel@tonic-gate (AP)->an_vp = swapfs_getvp(((uintptr_t)(AP) >> AN_VPSHIFT) \ 207*0Sstevel@tonic-gate & AN_VPSIZEMASK); \ 208*0Sstevel@tonic-gate (AP)->an_off = (anoff_t)(((uintptr_t)(AP) & ~(uintptr_t)0xFFFFFFFF) \ 209*0Sstevel@tonic-gate | (((uintptr_t)(AP) << AN_OFFSHIFT) & (uintptr_t)0xFFFFFFFF)); \ 210*0Sstevel@tonic-gate } 211*0Sstevel@tonic-gate 212*0Sstevel@tonic-gate /* 213*0Sstevel@tonic-gate * Free the page name for the specified anon slot. 214*0Sstevel@tonic-gate * For now there's nothing to do. 215*0Sstevel@tonic-gate */ 216*0Sstevel@tonic-gate #define swap_free(AP) 217*0Sstevel@tonic-gate 218*0Sstevel@tonic-gate /* Flags for swap_phys_alloc */ 219*0Sstevel@tonic-gate #define SA_NOT 0x01 /* Must have slot from swap dev other than input one */ 220*0Sstevel@tonic-gate 221*0Sstevel@tonic-gate /* Special error codes for swap_newphysname() */ 222*0Sstevel@tonic-gate #define SE_NOSWAP -1 /* No physical swap slots available */ 223*0Sstevel@tonic-gate #define SE_NOANON -2 /* No anon slot for swap slot */ 224*0Sstevel@tonic-gate 225*0Sstevel@tonic-gate #ifdef _KERNEL 226*0Sstevel@tonic-gate extern struct anon *swap_anon(struct vnode *vp, u_offset_t off); 227*0Sstevel@tonic-gate extern int swap_phys_alloc(struct vnode **vpp, u_offset_t *offp, size_t *lenp, 228*0Sstevel@tonic-gate uint_t flags); 229*0Sstevel@tonic-gate extern void swap_phys_free(struct vnode *vp, u_offset_t off, size_t len); 230*0Sstevel@tonic-gate extern int swap_getphysname(struct vnode *vp, u_offset_t off, 231*0Sstevel@tonic-gate struct vnode **pvpp, u_offset_t *poffp); 232*0Sstevel@tonic-gate extern int swap_newphysname(struct vnode *vp, u_offset_t offset, 233*0Sstevel@tonic-gate u_offset_t *offp, size_t *lenp, struct vnode **pvpp, u_offset_t *poffp); 234*0Sstevel@tonic-gate 235*0Sstevel@tonic-gate extern struct swapinfo *swapinfo; 236*0Sstevel@tonic-gate extern int swap_debug; 237*0Sstevel@tonic-gate #endif /* _KERNEL */ 238*0Sstevel@tonic-gate 239*0Sstevel@tonic-gate #ifdef SWAP_DEBUG 240*0Sstevel@tonic-gate #define SW_RENAME 0x01 241*0Sstevel@tonic-gate #define SW_RESV 0x02 242*0Sstevel@tonic-gate #define SW_ALLOC 0x04 243*0Sstevel@tonic-gate #define SW_CTL 0x08 244*0Sstevel@tonic-gate #define SWAP_PRINT(f, s, x1, x2, x3, x4, x5) \ 245*0Sstevel@tonic-gate if (swap_debug & f) \ 246*0Sstevel@tonic-gate printf(s, x1, x2, x3, x4, x5); 247*0Sstevel@tonic-gate #else /* SWAP_DEBUG */ 248*0Sstevel@tonic-gate #define SWAP_PRINT(f, s, x1, x2, x3, x4, x5) 249*0Sstevel@tonic-gate #endif /* SWAP_DEBUG */ 250*0Sstevel@tonic-gate 251*0Sstevel@tonic-gate #ifdef __cplusplus 252*0Sstevel@tonic-gate } 253*0Sstevel@tonic-gate #endif 254*0Sstevel@tonic-gate 255*0Sstevel@tonic-gate #endif /* _SYS_SWAP_H */ 256