1 /* $NetBSD: uvm_loan.c,v 1.20 2000/04/10 00:32:46 thorpej Exp $ */ 2 3 /* 4 * 5 * Copyright (c) 1997 Charles D. Cranor and Washington University. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by Charles D. Cranor and 19 * Washington University. 20 * 4. The name of the author may not be used to endorse or promote products 21 * derived from this software without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 * 34 * from: Id: uvm_loan.c,v 1.1.6.4 1998/02/06 05:08:43 chs Exp 35 */ 36 37 /* 38 * uvm_loan.c: page loanout handler 39 */ 40 41 #include <sys/param.h> 42 #include <sys/systm.h> 43 #include <sys/kernel.h> 44 #include <sys/proc.h> 45 #include <sys/malloc.h> 46 #include <sys/mman.h> 47 48 #include <vm/vm.h> 49 #include <vm/vm_page.h> 50 #include <vm/vm_kern.h> 51 52 #include <uvm/uvm.h> 53 54 /* 55 * "loaned" pages are pages which are (read-only, copy-on-write) loaned 56 * from the VM system to other parts of the kernel. this allows page 57 * copying to be avoided (e.g. you can loan pages from objs/anons to 58 * the mbuf system). 59 * 60 * there are 3 types of loans possible: 61 * O->K uvm_object page to wired kernel page (e.g. mbuf data area) 62 * A->K anon page to wired kernel page (e.g. mbuf data area) 63 * O->A uvm_object to anon loan (e.g. vnode page to an anon) 64 * note that it possible to have an O page loaned to both an A and K 65 * at the same time. 66 * 67 * loans are tracked by pg->loan_count. an O->A page will have both 68 * a uvm_object and a vm_anon, but PQ_ANON will not be set. this sort 69 * of page is considered "owned" by the uvm_object (not the anon). 70 * 71 * each loan of a page to the kernel bumps the pg->wire_count. the 72 * kernel mappings for these pages will be read-only and wired. since 73 * the page will also be wired, it will not be a candidate for pageout, 74 * and thus will never be pmap_page_protect()'d with VM_PROT_NONE. a 75 * write fault in the kernel to one of these pages will not cause 76 * copy-on-write. instead, the page fault is considered fatal. this 77 * is because the kernel mapping will have no way to look up the 78 * object/anon which the page is owned by. this is a good side-effect, 79 * since a kernel write to a loaned page is an error. 80 * 81 * owners that want to free their pages and discover that they are 82 * loaned out simply "disown" them (the page becomes an orphan). these 83 * pages should be freed when the last loan is dropped. in some cases 84 * an anon may "adopt" an orphaned page. 85 * 86 * locking: to read pg->loan_count either the owner or the page queues 87 * must be locked. to modify pg->loan_count, both the owner of the page 88 * and the PQs must be locked. pg->flags is (as always) locked by 89 * the owner of the page. 90 * 91 * note that locking from the "loaned" side is tricky since the object 92 * getting the loaned page has no reference to the page's owner and thus 93 * the owner could "die" at any time. in order to prevent the owner 94 * from dying the page queues should be locked. this forces us to sometimes 95 * use "try" locking. 96 * 97 * loans are typically broken by the following events: 98 * 1. write fault to a loaned page 99 * 2. pageout of clean+inactive O->A loaned page 100 * 3. owner frees page (e.g. pager flush) 101 * 102 * note that loaning a page causes all mappings of the page to become 103 * read-only (via pmap_page_protect). this could have an unexpected 104 * effect on normal "wired" pages if one is not careful (XXX). 105 */ 106 107 /* 108 * local prototypes 109 */ 110 111 static int uvm_loananon __P((struct uvm_faultinfo *, void ***, 112 int, struct vm_anon *)); 113 static int uvm_loanentry __P((struct uvm_faultinfo *, void ***, int)); 114 static int uvm_loanuobj __P((struct uvm_faultinfo *, void ***, 115 int, vaddr_t)); 116 static int uvm_loanzero __P((struct uvm_faultinfo *, void ***, int)); 117 118 /* 119 * inlines 120 */ 121 122 /* 123 * uvm_loanentry: loan out pages in a map entry (helper fn for uvm_loan()) 124 * 125 * => "ufi" is the result of a successful map lookup (meaning that 126 * the maps are locked by the caller) 127 * => we may unlock the maps if needed (for I/O) 128 * => we put our output result in "output" 129 * => we return the number of pages we loaned, or -1 if we had an error 130 */ 131 132 static __inline int 133 uvm_loanentry(ufi, output, flags) 134 struct uvm_faultinfo *ufi; 135 void ***output; 136 int flags; 137 { 138 vaddr_t curaddr = ufi->orig_rvaddr; 139 vsize_t togo = ufi->size; 140 struct vm_aref *aref = &ufi->entry->aref; 141 struct uvm_object *uobj = ufi->entry->object.uvm_obj; 142 struct vm_anon *anon; 143 int rv, result = 0; 144 145 /* 146 * lock us the rest of the way down 147 */ 148 if (aref->ar_amap) 149 amap_lock(aref->ar_amap); 150 if (uobj) 151 simple_lock(&uobj->vmobjlock); 152 153 /* 154 * loop until done 155 */ 156 while (togo) { 157 158 /* 159 * find the page we want. check the anon layer first. 160 */ 161 162 if (aref->ar_amap) { 163 anon = amap_lookup(aref, curaddr - ufi->entry->start); 164 } else { 165 anon = NULL; 166 } 167 168 if (anon) { 169 rv = uvm_loananon(ufi, output, flags, anon); 170 } else if (uobj) { 171 rv = uvm_loanuobj(ufi, output, flags, curaddr); 172 } else if (UVM_ET_ISCOPYONWRITE(ufi->entry)) { 173 rv = uvm_loanzero(ufi, output, flags); 174 } else { 175 rv = -1; /* null map entry... fail now */ 176 } 177 178 /* total failure */ 179 if (rv < 0) 180 return(-1); 181 182 /* relock failed, need to do another lookup */ 183 if (rv == 0) 184 return(result); 185 186 /* 187 * got it... advance to next page 188 */ 189 result++; 190 togo -= PAGE_SIZE; 191 curaddr += PAGE_SIZE; 192 } 193 194 /* 195 * unlock everything and return 196 */ 197 uvmfault_unlockall(ufi, aref->ar_amap, uobj, NULL); 198 return(result); 199 } 200 201 /* 202 * normal functions 203 */ 204 205 /* 206 * uvm_loan: loan pages out to anons or to the kernel 207 * 208 * => map should be unlocked 209 * => start and len should be multiples of PAGE_SIZE 210 * => result is either an array of anon's or vm_pages (depending on flags) 211 * => flag values: UVM_LOAN_TOANON - loan to anons 212 * UVM_LOAN_TOPAGE - loan to wired kernel page 213 * one and only one of these flags must be set! 214 */ 215 216 int 217 uvm_loan(map, start, len, result, flags) 218 struct vm_map *map; 219 vaddr_t start; 220 vsize_t len; 221 void **result; 222 int flags; 223 { 224 struct uvm_faultinfo ufi; 225 void **output; 226 int rv; 227 228 #ifdef DIAGNOSTIC 229 if (map->flags & VM_MAP_INTRSAFE) 230 panic("uvm_loan: intrsafe map"); 231 #endif 232 233 /* 234 * ensure that one and only one of the flags is set 235 */ 236 237 if ((flags & (UVM_LOAN_TOANON|UVM_LOAN_TOPAGE)) == 238 (UVM_LOAN_TOANON|UVM_LOAN_TOPAGE) || 239 (flags & (UVM_LOAN_TOANON|UVM_LOAN_TOPAGE)) == 0) 240 return(KERN_FAILURE); 241 242 /* 243 * "output" is a pointer to the current place to put the loaned 244 * page... 245 */ 246 247 output = &result[0]; /* start at the beginning ... */ 248 249 /* 250 * while we've got pages to do 251 */ 252 253 while (len > 0) { 254 255 /* 256 * fill in params for a call to uvmfault_lookup 257 */ 258 259 ufi.orig_map = map; 260 ufi.orig_rvaddr = start; 261 ufi.orig_size = len; 262 263 /* 264 * do the lookup, the only time this will fail is if we hit on 265 * an unmapped region (an error) 266 */ 267 268 if (!uvmfault_lookup(&ufi, FALSE)) 269 goto fail; 270 271 /* 272 * now do the loanout 273 */ 274 rv = uvm_loanentry(&ufi, &output, flags); 275 if (rv < 0) 276 goto fail; 277 278 /* 279 * done! advance pointers and unlock. 280 */ 281 rv <<= PAGE_SHIFT; 282 len -= rv; 283 start += rv; 284 uvmfault_unlockmaps(&ufi, FALSE); 285 } 286 287 /* 288 * got it! return success. 289 */ 290 291 return(KERN_SUCCESS); 292 293 fail: 294 /* 295 * fail: failed to do it. drop our loans and return failure code. 296 */ 297 if (output - result) { 298 if (flags & UVM_LOAN_TOANON) 299 uvm_unloananon((struct vm_anon **)result, 300 output - result); 301 else 302 uvm_unloanpage((struct vm_page **)result, 303 output - result); 304 } 305 return(KERN_FAILURE); 306 } 307 308 /* 309 * uvm_loananon: loan a page from an anon out 310 * 311 * => return value: 312 * -1 = fatal error, everything is unlocked, abort. 313 * 0 = lookup in ufi went stale, everything unlocked, relookup and 314 * try again 315 * 1 = got it, everything still locked 316 */ 317 318 int 319 uvm_loananon(ufi, output, flags, anon) 320 struct uvm_faultinfo *ufi; 321 void ***output; 322 int flags; 323 struct vm_anon *anon; 324 { 325 struct vm_page *pg; 326 int result; 327 328 /* 329 * if we are loaning to another anon then it is easy, we just 330 * bump the reference count on the current anon and return a 331 * pointer to it. 332 */ 333 if (flags & UVM_LOAN_TOANON) { 334 simple_lock(&anon->an_lock); 335 pg = anon->u.an_page; 336 if (pg && (pg->pqflags & PQ_ANON) != 0 && anon->an_ref == 1) 337 /* read protect it */ 338 pmap_page_protect(pg, VM_PROT_READ); 339 anon->an_ref++; 340 **output = anon; 341 *output = (*output) + 1; 342 simple_unlock(&anon->an_lock); 343 return(1); 344 } 345 346 /* 347 * we are loaning to a kernel-page. we need to get the page 348 * resident so we can wire it. uvmfault_anonget will handle 349 * this for us. 350 */ 351 352 simple_lock(&anon->an_lock); 353 result = uvmfault_anonget(ufi, ufi->entry->aref.ar_amap, anon); 354 355 /* 356 * if we were unable to get the anon, then uvmfault_anonget has 357 * unlocked everything and returned an error code. 358 */ 359 360 if (result != VM_PAGER_OK) { 361 362 /* need to refault (i.e. refresh our lookup) ? */ 363 if (result == VM_PAGER_REFAULT) 364 return(0); 365 366 /* "try again"? sleep a bit and retry ... */ 367 if (result == VM_PAGER_AGAIN) { 368 tsleep((caddr_t)&lbolt, PVM, "loanagain", 0); 369 return(0); 370 } 371 372 /* otherwise flag it as an error */ 373 return(-1); 374 } 375 376 /* 377 * we have the page and its owner locked: do the loan now. 378 */ 379 380 pg = anon->u.an_page; 381 uvm_lock_pageq(); 382 if (pg->loan_count == 0) 383 pmap_page_protect(pg, VM_PROT_READ); 384 pg->loan_count++; 385 uvm_pagewire(pg); /* always wire it */ 386 uvm_unlock_pageq(); 387 **output = pg; 388 *output = (*output) + 1; 389 390 /* unlock anon and return success */ 391 if (pg->uobject) 392 simple_unlock(&pg->uobject->vmobjlock); 393 simple_unlock(&anon->an_lock); 394 return(1); 395 } 396 397 /* 398 * uvm_loanuobj: loan a page from a uobj out 399 * 400 * => return value: 401 * -1 = fatal error, everything is unlocked, abort. 402 * 0 = lookup in ufi went stale, everything unlocked, relookup and 403 * try again 404 * 1 = got it, everything still locked 405 */ 406 407 int 408 uvm_loanuobj(ufi, output, flags, va) 409 struct uvm_faultinfo *ufi; 410 void ***output; 411 int flags; 412 vaddr_t va; 413 { 414 struct vm_amap *amap = ufi->entry->aref.ar_amap; 415 struct uvm_object *uobj = ufi->entry->object.uvm_obj; 416 struct vm_page *pg; 417 struct vm_anon *anon; 418 int result, npages; 419 boolean_t locked; 420 421 /* 422 * first we must make sure the page is resident. 423 * 424 * XXXCDC: duplicate code with uvm_fault(). 425 */ 426 427 if (uobj->pgops->pgo_get) { 428 npages = 1; 429 pg = NULL; 430 result = uobj->pgops->pgo_get(uobj, va - ufi->entry->start, 431 &pg, &npages, 0, VM_PROT_READ, MADV_NORMAL, PGO_LOCKED); 432 } else { 433 result = VM_PAGER_ERROR; 434 } 435 436 /* 437 * check the result of the locked pgo_get. if there is a problem, 438 * then we fail the loan. 439 */ 440 441 if (result != VM_PAGER_OK && result != VM_PAGER_UNLOCK) { 442 uvmfault_unlockall(ufi, amap, uobj, NULL); 443 return(-1); 444 } 445 446 /* 447 * if we need to unlock for I/O, do so now. 448 */ 449 450 if (result == VM_PAGER_UNLOCK) { 451 uvmfault_unlockall(ufi, amap, NULL, NULL); 452 453 npages = 1; 454 /* locked: uobj */ 455 result = uobj->pgops->pgo_get(uobj, va - ufi->entry->start, 456 &pg, &npages, 0, VM_PROT_READ, MADV_NORMAL, 0); 457 /* locked: <nothing> */ 458 459 /* 460 * check for errors 461 */ 462 463 if (result != VM_PAGER_OK) { 464 if (result == VM_PAGER_AGAIN) { 465 tsleep((caddr_t)&lbolt, PVM, "fltagain2", 0); 466 return(0); /* redo the lookup and try again */ 467 } 468 return(-1); /* total failure */ 469 } 470 471 /* 472 * pgo_get was a success. attempt to relock everything. 473 */ 474 475 locked = uvmfault_relock(ufi); 476 if (locked && amap) 477 amap_lock(amap); 478 simple_lock(&uobj->vmobjlock); 479 480 /* 481 * verify that the page has not be released and re-verify 482 * that amap slot is still free. if there is a problem we 483 * drop our lock (thus force a lookup refresh/retry). 484 */ 485 486 if ((pg->flags & PG_RELEASED) != 0 || 487 (locked && amap && amap_lookup(&ufi->entry->aref, 488 ufi->orig_rvaddr - ufi->entry->start))) { 489 490 if (locked) 491 uvmfault_unlockall(ufi, amap, NULL, NULL); 492 locked = FALSE; 493 } 494 495 /* 496 * didn't get the lock? release the page and retry. 497 */ 498 499 if (locked == FALSE) { 500 501 if (pg->flags & PG_WANTED) 502 /* still holding object lock */ 503 wakeup(pg); 504 505 if (pg->flags & PG_RELEASED) { 506 #ifdef DIAGNOSTIC 507 if (uobj->pgops->pgo_releasepg == NULL) 508 panic("uvm_loanuobj: object has no releasepg function"); 509 #endif 510 /* frees page */ 511 if (uobj->pgops->pgo_releasepg(pg, NULL)) 512 simple_unlock(&uobj->vmobjlock); 513 return (0); 514 } 515 516 uvm_lock_pageq(); 517 uvm_pageactivate(pg); /* make sure it is in queues */ 518 uvm_unlock_pageq(); 519 pg->flags &= ~(PG_BUSY|PG_WANTED); 520 UVM_PAGE_OWN(pg, NULL); 521 simple_unlock(&uobj->vmobjlock); 522 return (0); 523 } 524 } 525 526 /* 527 * at this point we have the page we want ("pg") marked PG_BUSY for us 528 * and we have all data structures locked. do the loanout. page can 529 * not be PG_RELEASED (we caught this above). 530 */ 531 532 if ((flags & UVM_LOAN_TOANON) == 0) { /* loan to wired-kernel page? */ 533 uvm_lock_pageq(); 534 if (pg->loan_count == 0) 535 pmap_page_protect(pg, VM_PROT_READ); 536 pg->loan_count++; 537 uvm_pagewire(pg); 538 uvm_unlock_pageq(); 539 **output = pg; 540 *output = (*output) + 1; 541 if (pg->flags & PG_WANTED) 542 wakeup(pg); 543 pg->flags &= ~(PG_WANTED|PG_BUSY); 544 UVM_PAGE_OWN(pg, NULL); 545 return(1); /* got it! */ 546 } 547 548 /* 549 * must be a loan to an anon. check to see if there is already 550 * an anon associated with this page. if so, then just return 551 * a reference to this object. the page should already be 552 * mapped read-only because it is already on loan. 553 */ 554 555 if (pg->uanon) { 556 anon = pg->uanon; 557 simple_lock(&anon->an_lock); 558 anon->an_ref++; 559 simple_unlock(&anon->an_lock); 560 **output = anon; 561 *output = (*output) + 1; 562 uvm_lock_pageq(); 563 uvm_pageactivate(pg); /* reactivate */ 564 uvm_unlock_pageq(); 565 if (pg->flags & PG_WANTED) 566 wakeup(pg); 567 pg->flags &= ~(PG_WANTED|PG_BUSY); 568 UVM_PAGE_OWN(pg, NULL); 569 return(1); 570 } 571 572 /* 573 * need to allocate a new anon 574 */ 575 576 anon = uvm_analloc(); 577 if (anon == NULL) { /* out of VM! */ 578 if (pg->flags & PG_WANTED) 579 wakeup(pg); 580 pg->flags &= ~(PG_WANTED|PG_BUSY); 581 UVM_PAGE_OWN(pg, NULL); 582 uvmfault_unlockall(ufi, amap, uobj, NULL); 583 return(-1); 584 } 585 anon->u.an_page = pg; 586 pg->uanon = anon; 587 uvm_lock_pageq(); 588 if (pg->loan_count == 0) 589 pmap_page_protect(pg, VM_PROT_READ); 590 pg->loan_count++; 591 uvm_pageactivate(pg); 592 uvm_unlock_pageq(); 593 **output = anon; 594 *output = (*output) + 1; 595 if (pg->flags & PG_WANTED) 596 wakeup(pg); 597 pg->flags &= ~(PG_WANTED|PG_BUSY); 598 UVM_PAGE_OWN(pg, NULL); 599 return(1); 600 } 601 602 /* 603 * uvm_loanzero: "loan" a zero-fill page out 604 * 605 * => return value: 606 * -1 = fatal error, everything is unlocked, abort. 607 * 0 = lookup in ufi went stale, everything unlocked, relookup and 608 * try again 609 * 1 = got it, everything still locked 610 */ 611 612 int 613 uvm_loanzero(ufi, output, flags) 614 struct uvm_faultinfo *ufi; 615 void ***output; 616 int flags; 617 { 618 struct vm_anon *anon; 619 struct vm_page *pg; 620 621 if ((flags & UVM_LOAN_TOANON) == 0) { /* loaning to kernel-page */ 622 623 while ((pg = uvm_pagealloc(NULL, 0, NULL, 624 UVM_PGA_ZERO)) == NULL) { 625 uvmfault_unlockall(ufi, ufi->entry->aref.ar_amap, 626 ufi->entry->object.uvm_obj, NULL); 627 uvm_wait("loanzero1"); 628 if (!uvmfault_relock(ufi)) 629 return(0); 630 if (ufi->entry->aref.ar_amap) 631 amap_lock(ufi->entry->aref.ar_amap); 632 if (ufi->entry->object.uvm_obj) 633 simple_lock( 634 &ufi->entry->object.uvm_obj->vmobjlock); 635 /* ... and try again */ 636 } 637 638 /* got a zero'd page; return */ 639 pg->flags &= ~(PG_BUSY|PG_FAKE); 640 UVM_PAGE_OWN(pg, NULL); 641 **output = pg; 642 *output = (*output) + 1; 643 uvm_lock_pageq(); 644 /* wire it as we are loaning to kernel-page */ 645 uvm_pagewire(pg); 646 pg->loan_count = 1; 647 uvm_unlock_pageq(); 648 return(1); 649 } 650 651 /* loaning to an anon */ 652 while ((anon = uvm_analloc()) == NULL || 653 (pg = uvm_pagealloc(NULL, 0, anon, UVM_PGA_ZERO)) == NULL) { 654 655 /* unlock everything */ 656 uvmfault_unlockall(ufi, ufi->entry->aref.ar_amap, 657 ufi->entry->object.uvm_obj, NULL); 658 659 /* out of swap causes us to fail */ 660 if (anon == NULL) 661 return(-1); 662 663 uvm_anfree(anon); 664 uvm_wait("loanzero2"); /* wait for pagedaemon */ 665 666 if (!uvmfault_relock(ufi)) 667 /* map changed while unlocked, need relookup */ 668 return (0); 669 670 /* relock everything else */ 671 if (ufi->entry->aref.ar_amap) 672 amap_lock(ufi->entry->aref.ar_amap); 673 if (ufi->entry->object.uvm_obj) 674 simple_lock(&ufi->entry->object.uvm_obj->vmobjlock); 675 /* ... and try again */ 676 } 677 678 /* got a zero'd page; return */ 679 pg->flags &= ~(PG_BUSY|PG_FAKE); 680 UVM_PAGE_OWN(pg, NULL); 681 uvm_lock_pageq(); 682 uvm_pageactivate(pg); 683 uvm_unlock_pageq(); 684 **output = anon; 685 *output = (*output) + 1; 686 return(1); 687 } 688 689 690 /* 691 * uvm_unloananon: kill loans on anons (basically a normal ref drop) 692 * 693 * => we expect all our resources to be unlocked 694 */ 695 696 void 697 uvm_unloananon(aloans, nanons) 698 struct vm_anon **aloans; 699 int nanons; 700 { 701 struct vm_anon *anon; 702 703 while (nanons-- > 0) { 704 int refs; 705 706 anon = *aloans++; 707 simple_lock(&anon->an_lock); 708 refs = --anon->an_ref; 709 simple_unlock(&anon->an_lock); 710 711 if (refs == 0) { 712 uvm_anfree(anon); /* last reference: kill anon */ 713 } 714 } 715 } 716 717 /* 718 * uvm_unloanpage: kill loans on pages loaned out to the kernel 719 * 720 * => we expect all our resources to be unlocked 721 */ 722 723 void 724 uvm_unloanpage(ploans, npages) 725 struct vm_page **ploans; 726 int npages; 727 { 728 struct vm_page *pg; 729 730 uvm_lock_pageq(); 731 732 while (npages-- > 0) { 733 pg = *ploans++; 734 735 if (pg->loan_count < 1) 736 panic("uvm_unloanpage: page %p isn't loaned", pg); 737 738 pg->loan_count--; /* drop loan */ 739 uvm_pageunwire(pg); /* and wire */ 740 741 /* 742 * if page is unowned and we killed last loan, then we can 743 * free it 744 */ 745 if (pg->loan_count == 0 && pg->uobject == NULL && 746 pg->uanon == NULL) { 747 748 if (pg->flags & PG_BUSY) 749 panic("uvm_unloanpage: page %p unowned but PG_BUSY!", pg); 750 751 /* be safe */ 752 pmap_page_protect(pg, VM_PROT_NONE); 753 uvm_pagefree(pg); /* pageq locked above */ 754 755 } 756 } 757 758 uvm_unlock_pageq(); 759 } 760 761