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