uvm_anon.c revision 1.53
1/* $NetBSD: uvm_anon.c,v 1.53 2011/04/23 18:14:12 rmind Exp $ */ 2 3/* 4 * Copyright (c) 1997 Charles D. Cranor and Washington University. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28/* 29 * uvm_anon.c: uvm anon ops 30 */ 31 32#include <sys/cdefs.h> 33__KERNEL_RCSID(0, "$NetBSD: uvm_anon.c,v 1.53 2011/04/23 18:14:12 rmind Exp $"); 34 35#include "opt_uvmhist.h" 36 37#include <sys/param.h> 38#include <sys/systm.h> 39#include <sys/pool.h> 40#include <sys/kernel.h> 41 42#include <uvm/uvm.h> 43#include <uvm/uvm_swap.h> 44#include <uvm/uvm_pdpolicy.h> 45 46static struct pool_cache uvm_anon_cache; 47 48static int uvm_anon_ctor(void *, void *, int); 49static void uvm_anon_dtor(void *, void *); 50 51/* 52 * allocate anons 53 */ 54void 55uvm_anon_init(void) 56{ 57 58 pool_cache_bootstrap(&uvm_anon_cache, sizeof(struct vm_anon), 0, 0, 59 PR_LARGECACHE, "anonpl", NULL, IPL_NONE, uvm_anon_ctor, 60 uvm_anon_dtor, NULL); 61} 62 63static int 64uvm_anon_ctor(void *arg, void *object, int flags) 65{ 66 struct vm_anon *anon = object; 67 68 anon->an_ref = 0; 69 mutex_init(&anon->an_lock, MUTEX_DEFAULT, IPL_NONE); 70 anon->an_page = NULL; 71#if defined(VMSWAP) 72 anon->an_swslot = 0; 73#endif /* defined(VMSWAP) */ 74 75 return 0; 76} 77 78static void 79uvm_anon_dtor(void *arg, void *object) 80{ 81 struct vm_anon *anon = object; 82 83 mutex_destroy(&anon->an_lock); 84} 85 86/* 87 * allocate an anon 88 * 89 * => new anon is returned locked! 90 */ 91struct vm_anon * 92uvm_analloc(void) 93{ 94 struct vm_anon *anon; 95 96 anon = pool_cache_get(&uvm_anon_cache, PR_NOWAIT); 97 if (anon) { 98 KASSERT(anon->an_ref == 0); 99 KASSERT(anon->an_page == NULL); 100#if defined(VMSWAP) 101 KASSERT(anon->an_swslot == 0); 102#endif /* defined(VMSWAP) */ 103 anon->an_ref = 1; 104 mutex_enter(&anon->an_lock); 105 } 106 return anon; 107} 108 109/* 110 * uvm_anfree: free a single anon structure 111 * 112 * => caller must remove anon from its amap before calling (if it was in 113 * an amap). 114 * => anon must be unlocked and have a zero reference count. 115 * => we may lock the pageq's. 116 */ 117 118void 119uvm_anfree(struct vm_anon *anon) 120{ 121 struct vm_page *pg; 122 UVMHIST_FUNC("uvm_anfree"); UVMHIST_CALLED(maphist); 123 UVMHIST_LOG(maphist,"(anon=0x%x)", anon, 0,0,0); 124 125 KASSERT(anon->an_ref == 0); 126 KASSERT(!mutex_owned(&anon->an_lock)); 127 128 /* 129 * get page 130 */ 131 132 pg = anon->an_page; 133 134 /* 135 * if there is a resident page and it is loaned, then anon may not 136 * own it. call out to uvm_anon_lockpage() to ensure the real owner 137 * of the page has been identified and locked. 138 */ 139 140 if (pg && pg->loan_count) { 141 mutex_enter(&anon->an_lock); 142 pg = uvm_anon_lockloanpg(anon); 143 mutex_exit(&anon->an_lock); 144 } 145 146 /* 147 * if we have a resident page, we must dispose of it before freeing 148 * the anon. 149 */ 150 151 if (pg) { 152 153 /* 154 * if the page is owned by a uobject (now locked), then we must 155 * kill the loan on the page rather than free it. 156 */ 157 158 if (pg->uobject) { 159 mutex_enter(&uvm_pageqlock); 160 KASSERT(pg->loan_count > 0); 161 pg->loan_count--; 162 pg->uanon = NULL; 163 mutex_exit(&uvm_pageqlock); 164 mutex_exit(&pg->uobject->vmobjlock); 165 } else { 166 167 /* 168 * page has no uobject, so we must be the owner of it. 169 */ 170 171 KASSERT((pg->flags & PG_RELEASED) == 0); 172 mutex_enter(&anon->an_lock); 173 pmap_page_protect(pg, VM_PROT_NONE); 174 175 /* 176 * if the page is busy, mark it as PG_RELEASED 177 * so that uvm_anon_release will release it later. 178 */ 179 180 if (pg->flags & PG_BUSY) { 181 pg->flags |= PG_RELEASED; 182 mutex_exit(&anon->an_lock); 183 return; 184 } 185 mutex_enter(&uvm_pageqlock); 186 uvm_pagefree(pg); 187 mutex_exit(&uvm_pageqlock); 188 mutex_exit(&anon->an_lock); 189 UVMHIST_LOG(maphist, "anon 0x%x, page 0x%x: " 190 "freed now!", anon, pg, 0, 0); 191 } 192 } 193#if defined(VMSWAP) 194 if (pg == NULL && anon->an_swslot > 0) { 195 /* this page is no longer only in swap. */ 196 mutex_enter(&uvm_swap_data_lock); 197 KASSERT(uvmexp.swpgonly > 0); 198 uvmexp.swpgonly--; 199 mutex_exit(&uvm_swap_data_lock); 200 } 201#endif /* defined(VMSWAP) */ 202 203 /* 204 * free any swap resources. 205 */ 206 207 uvm_anon_dropswap(anon); 208 209 /* 210 * give a page replacement hint. 211 */ 212 213 uvmpdpol_anfree(anon); 214 215 /* 216 * now that we've stripped the data areas from the anon, 217 * free the anon itself. 218 */ 219 220 KASSERT(anon->an_page == NULL); 221#if defined(VMSWAP) 222 KASSERT(anon->an_swslot == 0); 223#endif /* defined(VMSWAP) */ 224 225 pool_cache_put(&uvm_anon_cache, anon); 226 UVMHIST_LOG(maphist,"<- done!",0,0,0,0); 227} 228 229#if defined(VMSWAP) 230 231/* 232 * uvm_anon_dropswap: release any swap resources from this anon. 233 * 234 * => anon must be locked or have a reference count of 0. 235 */ 236void 237uvm_anon_dropswap(struct vm_anon *anon) 238{ 239 UVMHIST_FUNC("uvm_anon_dropswap"); UVMHIST_CALLED(maphist); 240 241 if (anon->an_swslot == 0) 242 return; 243 244 UVMHIST_LOG(maphist,"freeing swap for anon %p, paged to swslot 0x%x", 245 anon, anon->an_swslot, 0, 0); 246 uvm_swap_free(anon->an_swslot, 1); 247 anon->an_swslot = 0; 248} 249 250#endif /* defined(VMSWAP) */ 251 252/* 253 * uvm_anon_lockloanpg: given a locked anon, lock its resident page 254 * 255 * => anon is locked by caller 256 * => on return: anon is locked 257 * if there is a resident page: 258 * if it has a uobject, it is locked by us 259 * if it is ownerless, we take over as owner 260 * we return the resident page (it can change during 261 * this function) 262 * => note that the only time an anon has an ownerless resident page 263 * is if the page was loaned from a uvm_object and the uvm_object 264 * disowned it 265 * => this only needs to be called when you want to do an operation 266 * on an anon's resident page and that page has a non-zero loan 267 * count. 268 */ 269struct vm_page * 270uvm_anon_lockloanpg(struct vm_anon *anon) 271{ 272 struct vm_page *pg; 273 bool locked = false; 274 275 KASSERT(mutex_owned(&anon->an_lock)); 276 277 /* 278 * loop while we have a resident page that has a non-zero loan count. 279 * if we successfully get our lock, we will "break" the loop. 280 * note that the test for pg->loan_count is not protected -- this 281 * may produce false positive results. note that a false positive 282 * result may cause us to do more work than we need to, but it will 283 * not produce an incorrect result. 284 */ 285 286 while (((pg = anon->an_page) != NULL) && pg->loan_count != 0) { 287 288 /* 289 * quickly check to see if the page has an object before 290 * bothering to lock the page queues. this may also produce 291 * a false positive result, but that's ok because we do a real 292 * check after that. 293 */ 294 295 if (pg->uobject) { 296 mutex_enter(&uvm_pageqlock); 297 if (pg->uobject) { 298 locked = 299 mutex_tryenter(&pg->uobject->vmobjlock); 300 } else { 301 /* object disowned before we got PQ lock */ 302 locked = true; 303 } 304 mutex_exit(&uvm_pageqlock); 305 306 /* 307 * if we didn't get a lock (try lock failed), then we 308 * toggle our anon lock and try again 309 */ 310 311 if (!locked) { 312 mutex_exit(&anon->an_lock); 313 314 /* 315 * someone locking the object has a chance to 316 * lock us right now 317 */ 318 /* XXX Better than yielding but inadequate. */ 319 kpause("livelock", false, 1, NULL); 320 321 mutex_enter(&anon->an_lock); 322 continue; 323 } 324 } 325 326 /* 327 * if page is un-owned [i.e. the object dropped its ownership], 328 * then we can take over as owner! 329 */ 330 331 if (pg->uobject == NULL && (pg->pqflags & PQ_ANON) == 0) { 332 mutex_enter(&uvm_pageqlock); 333 pg->pqflags |= PQ_ANON; 334 pg->loan_count--; 335 mutex_exit(&uvm_pageqlock); 336 } 337 break; 338 } 339 return(pg); 340} 341 342#if defined(VMSWAP) 343 344/* 345 * fetch an anon's page. 346 * 347 * => anon must be locked, and is unlocked upon return. 348 * => returns true if pagein was aborted due to lack of memory. 349 */ 350 351bool 352uvm_anon_pagein(struct vm_anon *anon) 353{ 354 struct vm_page *pg; 355 struct uvm_object *uobj; 356 int rv; 357 358 /* locked: anon */ 359 KASSERT(mutex_owned(&anon->an_lock)); 360 361 rv = uvmfault_anonget(NULL, NULL, anon); 362 363 /* 364 * if rv == 0, anon is still locked, else anon 365 * is unlocked 366 */ 367 368 switch (rv) { 369 case 0: 370 break; 371 372 case EIO: 373 case ERESTART: 374 375 /* 376 * nothing more to do on errors. 377 * ERESTART can only mean that the anon was freed, 378 * so again there's nothing to do. 379 */ 380 381 return false; 382 383 default: 384 return true; 385 } 386 387 /* 388 * ok, we've got the page now. 389 * mark it as dirty, clear its swslot and un-busy it. 390 */ 391 392 pg = anon->an_page; 393 uobj = pg->uobject; 394 if (anon->an_swslot > 0) 395 uvm_swap_free(anon->an_swslot, 1); 396 anon->an_swslot = 0; 397 pg->flags &= ~(PG_CLEAN); 398 399 /* 400 * deactivate the page (to put it on a page queue) 401 */ 402 403 mutex_enter(&uvm_pageqlock); 404 if (pg->wire_count == 0) 405 uvm_pagedeactivate(pg); 406 mutex_exit(&uvm_pageqlock); 407 408 if (pg->flags & PG_WANTED) { 409 wakeup(pg); 410 pg->flags &= ~(PG_WANTED); 411 } 412 413 /* 414 * unlock the anon and we're done. 415 */ 416 417 mutex_exit(&anon->an_lock); 418 if (uobj) { 419 mutex_exit(&uobj->vmobjlock); 420 } 421 return false; 422} 423 424#endif /* defined(VMSWAP) */ 425 426/* 427 * uvm_anon_release: release an anon and its page. 428 * 429 * => caller must lock the anon. 430 */ 431 432void 433uvm_anon_release(struct vm_anon *anon) 434{ 435 struct vm_page *pg = anon->an_page; 436 437 KASSERT(mutex_owned(&anon->an_lock)); 438 KASSERT(pg != NULL); 439 KASSERT((pg->flags & PG_RELEASED) != 0); 440 KASSERT((pg->flags & PG_BUSY) != 0); 441 KASSERT(pg->uobject == NULL); 442 KASSERT(pg->uanon == anon); 443 KASSERT(pg->loan_count == 0); 444 KASSERT(anon->an_ref == 0); 445 446 mutex_enter(&uvm_pageqlock); 447 uvm_pagefree(pg); 448 mutex_exit(&uvm_pageqlock); 449 mutex_exit(&anon->an_lock); 450 451 KASSERT(anon->an_page == NULL); 452 453 uvm_anfree(anon); 454} 455