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) 1984, 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 _VM_ANON_H 41*0Sstevel@tonic-gate #define _VM_ANON_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/cred.h> 46*0Sstevel@tonic-gate #include <vm/seg.h> 47*0Sstevel@tonic-gate #include <vm/vpage.h> 48*0Sstevel@tonic-gate 49*0Sstevel@tonic-gate #ifdef __cplusplus 50*0Sstevel@tonic-gate extern "C" { 51*0Sstevel@tonic-gate #endif 52*0Sstevel@tonic-gate 53*0Sstevel@tonic-gate /* 54*0Sstevel@tonic-gate * VM - Anonymous pages. 55*0Sstevel@tonic-gate */ 56*0Sstevel@tonic-gate 57*0Sstevel@tonic-gate typedef unsigned long anoff_t; /* anon offsets */ 58*0Sstevel@tonic-gate 59*0Sstevel@tonic-gate /* 60*0Sstevel@tonic-gate * Each anonymous page, either in memory or in swap, has an anon structure. 61*0Sstevel@tonic-gate * The structure (slot) provides a level of indirection between anonymous pages 62*0Sstevel@tonic-gate * and their backing store. 63*0Sstevel@tonic-gate * 64*0Sstevel@tonic-gate * (an_vp, an_off) names the vnode of the anonymous page for this slot. 65*0Sstevel@tonic-gate * 66*0Sstevel@tonic-gate * (an_pvp, an_poff) names the location of the physical backing store 67*0Sstevel@tonic-gate * for the page this slot represents. If the name is null there is no 68*0Sstevel@tonic-gate * associated physical store. The physical backing store location can 69*0Sstevel@tonic-gate * change while the slot is in use. 70*0Sstevel@tonic-gate * 71*0Sstevel@tonic-gate * an_hash is a hash list of anon slots. The list is hashed by 72*0Sstevel@tonic-gate * (an_vp, an_off) of the associated anonymous page and provides a 73*0Sstevel@tonic-gate * method of going from the name of an anonymous page to its 74*0Sstevel@tonic-gate * associated anon slot. 75*0Sstevel@tonic-gate * 76*0Sstevel@tonic-gate * an_refcnt holds a reference count which is the number of separate 77*0Sstevel@tonic-gate * copies that will need to be created in case of copy-on-write. 78*0Sstevel@tonic-gate * A refcnt > 0 protects the existence of the slot. The refcnt is 79*0Sstevel@tonic-gate * initialized to 1 when the anon slot is created in anon_alloc(). 80*0Sstevel@tonic-gate * If a client obtains an anon slot and allows multiple threads to 81*0Sstevel@tonic-gate * share it, then it is the client's responsibility to insure that 82*0Sstevel@tonic-gate * it does not allow one thread to try to reference the slot at the 83*0Sstevel@tonic-gate * same time as another is trying to decrement the last count and 84*0Sstevel@tonic-gate * destroy the anon slot. E.g., the seg_vn segment type protects 85*0Sstevel@tonic-gate * against this with higher level locks. 86*0Sstevel@tonic-gate */ 87*0Sstevel@tonic-gate 88*0Sstevel@tonic-gate struct anon { 89*0Sstevel@tonic-gate struct vnode *an_vp; /* vnode of anon page */ 90*0Sstevel@tonic-gate struct vnode *an_pvp; /* vnode of physical backing store */ 91*0Sstevel@tonic-gate anoff_t an_off; /* offset of anon page */ 92*0Sstevel@tonic-gate anoff_t an_poff; /* offset in vnode */ 93*0Sstevel@tonic-gate struct anon *an_hash; /* hash table of anon slots */ 94*0Sstevel@tonic-gate int an_refcnt; /* # of people sharing slot */ 95*0Sstevel@tonic-gate }; 96*0Sstevel@tonic-gate 97*0Sstevel@tonic-gate #ifdef _KERNEL 98*0Sstevel@tonic-gate /* 99*0Sstevel@tonic-gate * The swapinfo_lock protects: 100*0Sstevel@tonic-gate * swapinfo list 101*0Sstevel@tonic-gate * individual swapinfo structures 102*0Sstevel@tonic-gate * 103*0Sstevel@tonic-gate * The anoninfo_lock protects: 104*0Sstevel@tonic-gate * anoninfo counters 105*0Sstevel@tonic-gate * 106*0Sstevel@tonic-gate * The anonhash_lock protects: 107*0Sstevel@tonic-gate * anon hash lists 108*0Sstevel@tonic-gate * anon slot fields 109*0Sstevel@tonic-gate * 110*0Sstevel@tonic-gate * Fields in the anon slot which are read-only for the life of the slot 111*0Sstevel@tonic-gate * (an_vp, an_off) do not require the anonhash_lock be held to access them. 112*0Sstevel@tonic-gate * If you access a field without the anonhash_lock held you must be holding 113*0Sstevel@tonic-gate * the slot with an_refcnt to make sure it isn't destroyed. 114*0Sstevel@tonic-gate * To write (an_pvp, an_poff) in a given slot you must also hold the 115*0Sstevel@tonic-gate * p_iolock of the anonymous page for slot. 116*0Sstevel@tonic-gate */ 117*0Sstevel@tonic-gate extern kmutex_t anoninfo_lock; 118*0Sstevel@tonic-gate extern kmutex_t swapinfo_lock; 119*0Sstevel@tonic-gate extern kmutex_t anonhash_lock[]; 120*0Sstevel@tonic-gate extern pad_mutex_t anon_array_lock[]; 121*0Sstevel@tonic-gate extern kcondvar_t anon_array_cv[]; 122*0Sstevel@tonic-gate 123*0Sstevel@tonic-gate /* 124*0Sstevel@tonic-gate * Global hash table to provide a function from (vp, off) -> ap 125*0Sstevel@tonic-gate */ 126*0Sstevel@tonic-gate extern size_t anon_hash_size; 127*0Sstevel@tonic-gate extern struct anon **anon_hash; 128*0Sstevel@tonic-gate #define ANON_HASH_SIZE anon_hash_size 129*0Sstevel@tonic-gate #define ANON_HASHAVELEN 4 130*0Sstevel@tonic-gate #define ANON_HASH(VP, OFF) \ 131*0Sstevel@tonic-gate ((((uintptr_t)(VP) >> 7) ^ ((OFF) >> PAGESHIFT)) & (ANON_HASH_SIZE - 1)) 132*0Sstevel@tonic-gate 133*0Sstevel@tonic-gate #define AH_LOCK_SIZE 64 134*0Sstevel@tonic-gate #define AH_LOCK(vp, off) (ANON_HASH((vp), (off)) & (AH_LOCK_SIZE -1)) 135*0Sstevel@tonic-gate 136*0Sstevel@tonic-gate #endif /* _KERNEL */ 137*0Sstevel@tonic-gate 138*0Sstevel@tonic-gate /* 139*0Sstevel@tonic-gate * Declaration for the Global counters to accurately 140*0Sstevel@tonic-gate * track the kernel foot print in memory. 141*0Sstevel@tonic-gate */ 142*0Sstevel@tonic-gate extern pgcnt_t segvn_pages_locked; 143*0Sstevel@tonic-gate extern pgcnt_t pages_locked; 144*0Sstevel@tonic-gate extern pgcnt_t pages_claimed; 145*0Sstevel@tonic-gate extern pgcnt_t pages_useclaim; 146*0Sstevel@tonic-gate extern pgcnt_t obp_pages; 147*0Sstevel@tonic-gate 148*0Sstevel@tonic-gate /* 149*0Sstevel@tonic-gate * Anonymous backing store accounting structure for swapctl. 150*0Sstevel@tonic-gate * 151*0Sstevel@tonic-gate * ani_max = maximum amount of swap space 152*0Sstevel@tonic-gate * (including potentially available physical memory) 153*0Sstevel@tonic-gate * ani_free = amount of unallocated anonymous memory 154*0Sstevel@tonic-gate * (some of which might be reserved and including 155*0Sstevel@tonic-gate * potentially available physical memory) 156*0Sstevel@tonic-gate * ani_resv = amount of claimed (reserved) anonymous memory 157*0Sstevel@tonic-gate * 158*0Sstevel@tonic-gate * The swap data can be aquired more efficiently through the 159*0Sstevel@tonic-gate * kstats interface. 160*0Sstevel@tonic-gate * Total slots currently available for reservation = 161*0Sstevel@tonic-gate * MAX(ani_max - ani_resv, 0) + (availrmem - swapfs_minfree) 162*0Sstevel@tonic-gate */ 163*0Sstevel@tonic-gate struct anoninfo { 164*0Sstevel@tonic-gate pgcnt_t ani_max; 165*0Sstevel@tonic-gate pgcnt_t ani_free; 166*0Sstevel@tonic-gate pgcnt_t ani_resv; 167*0Sstevel@tonic-gate }; 168*0Sstevel@tonic-gate 169*0Sstevel@tonic-gate #ifdef _SYSCALL32 170*0Sstevel@tonic-gate struct anoninfo32 { 171*0Sstevel@tonic-gate size32_t ani_max; 172*0Sstevel@tonic-gate size32_t ani_free; 173*0Sstevel@tonic-gate size32_t ani_resv; 174*0Sstevel@tonic-gate }; 175*0Sstevel@tonic-gate #endif /* _SYSCALL32 */ 176*0Sstevel@tonic-gate 177*0Sstevel@tonic-gate /* 178*0Sstevel@tonic-gate * Define the NCPU pool of the ani_free counters. Update the counter 179*0Sstevel@tonic-gate * of the cpu on which the thread is running and in every clock intr 180*0Sstevel@tonic-gate * sync anoninfo.ani_free with the current total off all the NCPU entries. 181*0Sstevel@tonic-gate */ 182*0Sstevel@tonic-gate 183*0Sstevel@tonic-gate typedef struct ani_free { 184*0Sstevel@tonic-gate kmutex_t ani_lock; 185*0Sstevel@tonic-gate pgcnt_t ani_count; 186*0Sstevel@tonic-gate uchar_t pad[64 - sizeof (kmutex_t) - sizeof (pgcnt_t)]; 187*0Sstevel@tonic-gate /* XXX 64 = cacheline size */ 188*0Sstevel@tonic-gate } ani_free_t; 189*0Sstevel@tonic-gate 190*0Sstevel@tonic-gate #define ANI_MAX_POOL 128 191*0Sstevel@tonic-gate extern ani_free_t ani_free_pool[]; 192*0Sstevel@tonic-gate 193*0Sstevel@tonic-gate #define ANI_ADD(inc) { \ 194*0Sstevel@tonic-gate ani_free_t *anifp; \ 195*0Sstevel@tonic-gate int index; \ 196*0Sstevel@tonic-gate index = (CPU->cpu_id & (ANI_MAX_POOL - 1)); \ 197*0Sstevel@tonic-gate anifp = &ani_free_pool[index]; \ 198*0Sstevel@tonic-gate mutex_enter(&anifp->ani_lock); \ 199*0Sstevel@tonic-gate anifp->ani_count += inc; \ 200*0Sstevel@tonic-gate mutex_exit(&anifp->ani_lock); \ 201*0Sstevel@tonic-gate } 202*0Sstevel@tonic-gate 203*0Sstevel@tonic-gate /* 204*0Sstevel@tonic-gate * Anon array pointers are allocated in chunks. Each chunk 205*0Sstevel@tonic-gate * has PAGESIZE/sizeof(u_long *) of anon pointers. 206*0Sstevel@tonic-gate * There are two levels of arrays for anon array pointers larger 207*0Sstevel@tonic-gate * than a chunk. The first level points to anon array chunks. 208*0Sstevel@tonic-gate * The second level consists of chunks of anon pointers. 209*0Sstevel@tonic-gate * 210*0Sstevel@tonic-gate * If anon array is smaller than a chunk then the whole anon array 211*0Sstevel@tonic-gate * is created (memory is allocated for whole anon array). 212*0Sstevel@tonic-gate * If anon array is larger than a chunk only first level array is 213*0Sstevel@tonic-gate * allocated. Then other arrays (chunks) are allocated only when 214*0Sstevel@tonic-gate * they are initialized with anon pointers. 215*0Sstevel@tonic-gate */ 216*0Sstevel@tonic-gate struct anon_hdr { 217*0Sstevel@tonic-gate kmutex_t serial_lock; /* serialize array chunk allocation */ 218*0Sstevel@tonic-gate pgcnt_t size; /* number of pointers to (anon) pages */ 219*0Sstevel@tonic-gate void **array_chunk; /* pointers to anon pointers or chunks of */ 220*0Sstevel@tonic-gate /* anon pointers */ 221*0Sstevel@tonic-gate int flags; /* ANON_ALLOC_FORCE force preallocation of */ 222*0Sstevel@tonic-gate /* whole anon array */ 223*0Sstevel@tonic-gate }; 224*0Sstevel@tonic-gate 225*0Sstevel@tonic-gate #ifdef _LP64 226*0Sstevel@tonic-gate #define ANON_PTRSHIFT 3 227*0Sstevel@tonic-gate #define ANON_PTRMASK ~7 228*0Sstevel@tonic-gate #else 229*0Sstevel@tonic-gate #define ANON_PTRSHIFT 2 230*0Sstevel@tonic-gate #define ANON_PTRMASK ~3 231*0Sstevel@tonic-gate #endif 232*0Sstevel@tonic-gate 233*0Sstevel@tonic-gate #define ANON_CHUNK_SIZE (PAGESIZE >> ANON_PTRSHIFT) 234*0Sstevel@tonic-gate #define ANON_CHUNK_SHIFT (PAGESHIFT - ANON_PTRSHIFT) 235*0Sstevel@tonic-gate #define ANON_CHUNK_OFF (ANON_CHUNK_SIZE - 1) 236*0Sstevel@tonic-gate 237*0Sstevel@tonic-gate /* 238*0Sstevel@tonic-gate * Anon flags. 239*0Sstevel@tonic-gate */ 240*0Sstevel@tonic-gate #define ANON_SLEEP 0x0 /* ok to block */ 241*0Sstevel@tonic-gate #define ANON_NOSLEEP 0x1 /* non-blocking call */ 242*0Sstevel@tonic-gate #define ANON_ALLOC_FORCE 0x2 /* force single level anon array */ 243*0Sstevel@tonic-gate #define ANON_GROWDOWN 0x4 /* anon array should grow downward */ 244*0Sstevel@tonic-gate 245*0Sstevel@tonic-gate /* 246*0Sstevel@tonic-gate * The anon_map structure is used by various clients of the anon layer to 247*0Sstevel@tonic-gate * manage anonymous memory. When anonymous memory is shared, 248*0Sstevel@tonic-gate * then the different clients sharing it will point to the 249*0Sstevel@tonic-gate * same anon_map structure. Also, if a segment is unmapped 250*0Sstevel@tonic-gate * in the middle where an anon_map structure exists, the 251*0Sstevel@tonic-gate * newly created segment will also share the anon_map structure, 252*0Sstevel@tonic-gate * although the two segments will use different ranges of the 253*0Sstevel@tonic-gate * anon array. When mappings are private (or shared with 254*0Sstevel@tonic-gate * a reference count of 1), an unmap operation will free up 255*0Sstevel@tonic-gate * a range of anon slots in the array given by the anon_map 256*0Sstevel@tonic-gate * structure. Because of fragmentation due to this unmapping, 257*0Sstevel@tonic-gate * we have to store the size of the anon array in the anon_map 258*0Sstevel@tonic-gate * structure so that we can free everything when the referernce 259*0Sstevel@tonic-gate * count goes to zero. 260*0Sstevel@tonic-gate * 261*0Sstevel@tonic-gate * A new rangelock scheme is introduced to make the anon layer scale. 262*0Sstevel@tonic-gate * A reader/writer lock per anon_amp and an array of system-wide hash 263*0Sstevel@tonic-gate * locks, anon_array_lock[] are introduced to replace serial_lock and 264*0Sstevel@tonic-gate * anonmap lock. The writer lock is held when we want to singlethreaD 265*0Sstevel@tonic-gate * the reference to the anon array pointers or when references to 266*0Sstevel@tonic-gate * anon_map's members, whereas reader lock and anon_array_lock are 267*0Sstevel@tonic-gate * held to allows multiple threads to reference different part of 268*0Sstevel@tonic-gate * anon array. A global set of condition variables, anon_array_cv, 269*0Sstevel@tonic-gate * are used with anon_array_lock[] to make the hold time of the locks 270*0Sstevel@tonic-gate * short. 271*0Sstevel@tonic-gate * 272*0Sstevel@tonic-gate * szc is used to calculate the index of hash locks and cv's. We 273*0Sstevel@tonic-gate * could've just used seg->s_szc if not for the possible sharing of 274*0Sstevel@tonic-gate * anon_amp between SYSV shared memory and ISM, so now we introduce 275*0Sstevel@tonic-gate * szc in the anon_map structure. For MAP_SHARED, the amp->szc is either 276*0Sstevel@tonic-gate * 0 (base page size) or page_num_pagesizes() - 1, while MAP_PRIVATE 277*0Sstevel@tonic-gate * the amp->szc could be anything in [0, page_num_pagesizes() - 1]. 278*0Sstevel@tonic-gate */ 279*0Sstevel@tonic-gate struct anon_map { 280*0Sstevel@tonic-gate krwlock_t a_rwlock; /* protect anon_map and anon array */ 281*0Sstevel@tonic-gate size_t size; /* size in bytes mapped by the anon array */ 282*0Sstevel@tonic-gate struct anon_hdr *ahp; /* anon array header pointer, containing */ 283*0Sstevel@tonic-gate /* anon pointer array(s) */ 284*0Sstevel@tonic-gate size_t swresv; /* swap space reserved for this anon_map */ 285*0Sstevel@tonic-gate uint_t refcnt; /* reference count on this structure */ 286*0Sstevel@tonic-gate ushort_t a_szc; /* max szc among shared processes */ 287*0Sstevel@tonic-gate void *locality; /* lgroup locality info */ 288*0Sstevel@tonic-gate }; 289*0Sstevel@tonic-gate 290*0Sstevel@tonic-gate #ifdef _KERNEL 291*0Sstevel@tonic-gate 292*0Sstevel@tonic-gate #define ANON_BUSY 0x1 293*0Sstevel@tonic-gate #define ANON_ISBUSY(slot) (*(slot) & ANON_BUSY) 294*0Sstevel@tonic-gate #define ANON_SETBUSY(slot) (*(slot) |= ANON_BUSY) 295*0Sstevel@tonic-gate #define ANON_CLRBUSY(slot) (*(slot) &= ~ANON_BUSY) 296*0Sstevel@tonic-gate 297*0Sstevel@tonic-gate #define ANON_MAP_SHIFT 6 /* log2(sizeof (struct anon_map)) */ 298*0Sstevel@tonic-gate #define ANON_ARRAY_SHIFT 7 /* log2(ANON_LOCKSIZE) */ 299*0Sstevel@tonic-gate #define ANON_LOCKSIZE 128 300*0Sstevel@tonic-gate 301*0Sstevel@tonic-gate #define ANON_LOCK_ENTER(lock, type) rw_enter((lock), (type)) 302*0Sstevel@tonic-gate #define ANON_LOCK_EXIT(lock) rw_exit((lock)) 303*0Sstevel@tonic-gate 304*0Sstevel@tonic-gate #define ANON_ARRAY_HASH(amp, idx)\ 305*0Sstevel@tonic-gate ((((idx) + ((idx) >> ANON_ARRAY_SHIFT) +\ 306*0Sstevel@tonic-gate ((idx) >> (ANON_ARRAY_SHIFT << 1)) +\ 307*0Sstevel@tonic-gate ((idx) >> (ANON_ARRAY_SHIFT + (ANON_ARRAY_SHIFT << 1)))) ^\ 308*0Sstevel@tonic-gate ((uintptr_t)(amp) >> ANON_MAP_SHIFT)) & (ANON_LOCKSIZE - 1)) 309*0Sstevel@tonic-gate 310*0Sstevel@tonic-gate typedef struct anon_sync_obj { 311*0Sstevel@tonic-gate kmutex_t *sync_mutex; 312*0Sstevel@tonic-gate kcondvar_t *sync_cv; 313*0Sstevel@tonic-gate ulong_t *sync_data; 314*0Sstevel@tonic-gate } anon_sync_obj_t; 315*0Sstevel@tonic-gate 316*0Sstevel@tonic-gate /* 317*0Sstevel@tonic-gate * Anonymous backing store accounting structure for kernel. 318*0Sstevel@tonic-gate * ani_max = total reservable slots on physical (disk-backed) swap 319*0Sstevel@tonic-gate * ani_phys_resv = total phys slots reserved for use by clients 320*0Sstevel@tonic-gate * ani_mem_resv = total mem slots reserved for use by clients 321*0Sstevel@tonic-gate * ani_free = # unallocated physical slots + # of reserved unallocated 322*0Sstevel@tonic-gate * memory slots 323*0Sstevel@tonic-gate */ 324*0Sstevel@tonic-gate 325*0Sstevel@tonic-gate /* 326*0Sstevel@tonic-gate * Initial total swap slots available for reservation 327*0Sstevel@tonic-gate */ 328*0Sstevel@tonic-gate #define TOTAL_AVAILABLE_SWAP \ 329*0Sstevel@tonic-gate (k_anoninfo.ani_max + MAX((spgcnt_t)(availrmem - swapfs_minfree), 0)) 330*0Sstevel@tonic-gate 331*0Sstevel@tonic-gate /* 332*0Sstevel@tonic-gate * Swap slots currently available for reservation 333*0Sstevel@tonic-gate */ 334*0Sstevel@tonic-gate #define CURRENT_TOTAL_AVAILABLE_SWAP \ 335*0Sstevel@tonic-gate ((k_anoninfo.ani_max - k_anoninfo.ani_phys_resv) + \ 336*0Sstevel@tonic-gate MAX((spgcnt_t)(availrmem - swapfs_minfree), 0)) 337*0Sstevel@tonic-gate 338*0Sstevel@tonic-gate struct k_anoninfo { 339*0Sstevel@tonic-gate pgcnt_t ani_max; /* total reservable slots on phys */ 340*0Sstevel@tonic-gate /* (disk) swap */ 341*0Sstevel@tonic-gate pgcnt_t ani_free; /* # of unallocated phys and mem slots */ 342*0Sstevel@tonic-gate pgcnt_t ani_phys_resv; /* # of reserved phys (disk) slots */ 343*0Sstevel@tonic-gate pgcnt_t ani_mem_resv; /* # of reserved mem slots */ 344*0Sstevel@tonic-gate pgcnt_t ani_locked_swap; /* # of swap slots locked in reserved */ 345*0Sstevel@tonic-gate /* mem swap */ 346*0Sstevel@tonic-gate }; 347*0Sstevel@tonic-gate 348*0Sstevel@tonic-gate extern struct k_anoninfo k_anoninfo; 349*0Sstevel@tonic-gate 350*0Sstevel@tonic-gate extern void anon_init(void); 351*0Sstevel@tonic-gate extern struct anon *anon_alloc(struct vnode *, anoff_t); 352*0Sstevel@tonic-gate extern void anon_dup(struct anon_hdr *, ulong_t, 353*0Sstevel@tonic-gate struct anon_hdr *, ulong_t, size_t); 354*0Sstevel@tonic-gate extern void anon_dup_fill_holes(struct anon_hdr *, ulong_t, 355*0Sstevel@tonic-gate struct anon_hdr *, ulong_t, size_t, uint_t, int); 356*0Sstevel@tonic-gate extern int anon_fill_cow_holes(struct seg *, caddr_t, struct anon_hdr *, 357*0Sstevel@tonic-gate ulong_t, struct vnode *, u_offset_t, size_t, uint_t, 358*0Sstevel@tonic-gate uint_t, struct vpage [], struct cred *); 359*0Sstevel@tonic-gate extern void anon_free(struct anon_hdr *, ulong_t, size_t); 360*0Sstevel@tonic-gate extern void anon_free_pages(struct anon_hdr *, ulong_t, size_t, uint_t); 361*0Sstevel@tonic-gate extern void anon_disclaim(struct anon_map *, ulong_t, size_t, int); 362*0Sstevel@tonic-gate extern int anon_getpage(struct anon **, uint_t *, struct page **, 363*0Sstevel@tonic-gate size_t, struct seg *, caddr_t, enum seg_rw, struct cred *); 364*0Sstevel@tonic-gate extern int swap_getconpage(struct vnode *, u_offset_t, size_t, 365*0Sstevel@tonic-gate uint_t *, page_t *[], size_t, page_t *, 366*0Sstevel@tonic-gate spgcnt_t *, struct seg *, caddr_t, 367*0Sstevel@tonic-gate enum seg_rw, struct cred *); 368*0Sstevel@tonic-gate extern int anon_map_getpages(struct anon_map *, ulong_t, 369*0Sstevel@tonic-gate uint_t, struct seg *, caddr_t, uint_t, 370*0Sstevel@tonic-gate uint_t *, page_t *[], uint_t *, 371*0Sstevel@tonic-gate struct vpage [], enum seg_rw, int, int, struct cred *); 372*0Sstevel@tonic-gate extern int anon_map_privatepages(struct anon_map *, ulong_t, 373*0Sstevel@tonic-gate uint_t, struct seg *, caddr_t, uint_t, 374*0Sstevel@tonic-gate page_t *[], struct vpage [], int, struct cred *); 375*0Sstevel@tonic-gate extern struct page *anon_private(struct anon **, struct seg *, 376*0Sstevel@tonic-gate caddr_t, uint_t, struct page *, 377*0Sstevel@tonic-gate int, struct cred *); 378*0Sstevel@tonic-gate extern struct page *anon_zero(struct seg *, caddr_t, 379*0Sstevel@tonic-gate struct anon **, struct cred *); 380*0Sstevel@tonic-gate extern int anon_map_createpages(struct anon_map *, ulong_t, 381*0Sstevel@tonic-gate size_t, struct page **, 382*0Sstevel@tonic-gate struct seg *, caddr_t, 383*0Sstevel@tonic-gate enum seg_rw, struct cred *); 384*0Sstevel@tonic-gate extern int anon_map_demotepages(struct anon_map *, ulong_t, 385*0Sstevel@tonic-gate struct seg *, caddr_t, uint_t, 386*0Sstevel@tonic-gate struct vpage [], struct cred *); 387*0Sstevel@tonic-gate extern int anon_resvmem(size_t, uint_t); 388*0Sstevel@tonic-gate extern void anon_unresv(size_t); 389*0Sstevel@tonic-gate extern struct anon_map *anonmap_alloc(size_t, size_t); 390*0Sstevel@tonic-gate extern void anonmap_free(struct anon_map *); 391*0Sstevel@tonic-gate extern void anon_decref(struct anon *); 392*0Sstevel@tonic-gate extern int non_anon(struct anon_hdr *, ulong_t, u_offset_t *, size_t *); 393*0Sstevel@tonic-gate extern pgcnt_t anon_pages(struct anon_hdr *, ulong_t, pgcnt_t); 394*0Sstevel@tonic-gate extern int anon_swap_adjust(pgcnt_t); 395*0Sstevel@tonic-gate extern void anon_swap_restore(pgcnt_t); 396*0Sstevel@tonic-gate extern struct anon_hdr *anon_create(pgcnt_t, int); 397*0Sstevel@tonic-gate extern void anon_release(struct anon_hdr *, pgcnt_t); 398*0Sstevel@tonic-gate extern struct anon *anon_get_ptr(struct anon_hdr *, ulong_t); 399*0Sstevel@tonic-gate extern ulong_t *anon_get_slot(struct anon_hdr *, ulong_t); 400*0Sstevel@tonic-gate extern struct anon *anon_get_next_ptr(struct anon_hdr *, ulong_t *); 401*0Sstevel@tonic-gate extern int anon_set_ptr(struct anon_hdr *, ulong_t, struct anon *, int); 402*0Sstevel@tonic-gate extern int anon_copy_ptr(struct anon_hdr *, ulong_t, 403*0Sstevel@tonic-gate struct anon_hdr *, ulong_t, pgcnt_t, int); 404*0Sstevel@tonic-gate extern pgcnt_t anon_grow(struct anon_hdr *, ulong_t *, pgcnt_t, pgcnt_t, int); 405*0Sstevel@tonic-gate extern void anon_array_enter(struct anon_map *, ulong_t, 406*0Sstevel@tonic-gate anon_sync_obj_t *); 407*0Sstevel@tonic-gate extern void anon_array_exit(anon_sync_obj_t *); 408*0Sstevel@tonic-gate 409*0Sstevel@tonic-gate /* 410*0Sstevel@tonic-gate * anon_resv checks to see if there is enough swap space to fulfill a 411*0Sstevel@tonic-gate * request and if so, reserves the appropriate anonymous memory resources. 412*0Sstevel@tonic-gate * anon_checkspace just checks to see if there is space to fulfill the request, 413*0Sstevel@tonic-gate * without taking any resources. Both return 1 if successful and 0 if not. 414*0Sstevel@tonic-gate */ 415*0Sstevel@tonic-gate #define anon_resv(size) anon_resvmem((size), 1) 416*0Sstevel@tonic-gate #define anon_checkspace(size) anon_resvmem((size), 0) 417*0Sstevel@tonic-gate 418*0Sstevel@tonic-gate /* 419*0Sstevel@tonic-gate * Flags to anon_private 420*0Sstevel@tonic-gate */ 421*0Sstevel@tonic-gate #define STEAL_PAGE 0x1 /* page can be stolen */ 422*0Sstevel@tonic-gate #define LOCK_PAGE 0x2 /* page must be ``logically'' locked */ 423*0Sstevel@tonic-gate 424*0Sstevel@tonic-gate /* 425*0Sstevel@tonic-gate * Flags to anon_disclaim 426*0Sstevel@tonic-gate */ 427*0Sstevel@tonic-gate #define ANON_PGLOOKUP_BLK 0x1 /* block on locked pages */ 428*0Sstevel@tonic-gate 429*0Sstevel@tonic-gate /* 430*0Sstevel@tonic-gate * SEGKP ANON pages that are locked are assumed to be LWP stack pages 431*0Sstevel@tonic-gate * and thus count towards the user pages locked count. 432*0Sstevel@tonic-gate * This value is protected by the same lock as availrmem. 433*0Sstevel@tonic-gate */ 434*0Sstevel@tonic-gate extern pgcnt_t anon_segkp_pages_locked; 435*0Sstevel@tonic-gate 436*0Sstevel@tonic-gate extern int anon_debug; 437*0Sstevel@tonic-gate 438*0Sstevel@tonic-gate #ifdef ANON_DEBUG 439*0Sstevel@tonic-gate 440*0Sstevel@tonic-gate #define A_ANON 0x01 441*0Sstevel@tonic-gate #define A_RESV 0x02 442*0Sstevel@tonic-gate #define A_MRESV 0x04 443*0Sstevel@tonic-gate 444*0Sstevel@tonic-gate /* vararg-like debugging macro. */ 445*0Sstevel@tonic-gate #define ANON_PRINT(f, printf_args) \ 446*0Sstevel@tonic-gate if (anon_debug & f) \ 447*0Sstevel@tonic-gate printf printf_args 448*0Sstevel@tonic-gate 449*0Sstevel@tonic-gate #else /* ANON_DEBUG */ 450*0Sstevel@tonic-gate 451*0Sstevel@tonic-gate #define ANON_PRINT(f, printf_args) 452*0Sstevel@tonic-gate 453*0Sstevel@tonic-gate #endif /* ANON_DEBUG */ 454*0Sstevel@tonic-gate 455*0Sstevel@tonic-gate #endif /* _KERNEL */ 456*0Sstevel@tonic-gate 457*0Sstevel@tonic-gate #ifdef __cplusplus 458*0Sstevel@tonic-gate } 459*0Sstevel@tonic-gate #endif 460*0Sstevel@tonic-gate 461*0Sstevel@tonic-gate #endif /* _VM_ANON_H */ 462