uvm_pager.c revision 1.5 1 /* $NetBSD: uvm_pager.c,v 1.5 1998/02/10 14:12:25 mrg Exp $ */
2
3 /*
4 * XXXCDC: "ROUGH DRAFT" QUALITY UVM PRE-RELEASE FILE!
5 * >>>USE AT YOUR OWN RISK, WORK IS NOT FINISHED<<<
6 */
7 /*
8 *
9 * Copyright (c) 1997 Charles D. Cranor and Washington University.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 * must display the following acknowledgement:
22 * This product includes software developed by Charles D. Cranor and
23 * Washington University.
24 * 4. The name of the author may not be used to endorse or promote products
25 * derived from this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
28 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
29 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
30 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
31 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
32 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
36 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 *
38 * from: Id: uvm_pager.c,v 1.1.2.23 1998/02/02 20:38:06 chuck Exp
39 */
40
41 #include "opt_uvmhist.h"
42 #include "opt_pmap_new.h"
43
44 /*
45 * uvm_pager.c: generic functions used to assist the pagers.
46 */
47
48 #include <sys/param.h>
49 #include <sys/systm.h>
50 #include <sys/mount.h>
51 #include <sys/proc.h>
52 #include <sys/malloc.h>
53
54 #include <vm/vm.h>
55 #include <vm/vm_page.h>
56 #include <vm/vm_kern.h>
57
58 #include <sys/syscallargs.h>
59
60 #define UVM_PAGER
61 #include <uvm/uvm.h>
62
63 /*
64 * list of uvm pagers in the system
65 */
66
67 extern struct uvm_pagerops uvm_deviceops;
68 extern struct uvm_pagerops uvm_vnodeops;
69
70 struct uvm_pagerops *uvmpagerops[] = {
71 &uvm_deviceops,
72 &uvm_vnodeops,
73 };
74
75 /*
76 * the pager map: provides KVA for I/O
77 */
78
79 #define PAGER_MAP_SIZE (4 * 1024 * 1024)
80 vm_map_t pager_map; /* XXX */
81 simple_lock_data_t pager_map_wanted_lock;
82 boolean_t pager_map_wanted; /* locked by pager map */
83
84
85 /*
86 * uvm_pager_init: init pagers (at boot time)
87 */
88
89 void uvm_pager_init()
90
91 {
92 int lcv;
93
94 /*
95 * init pager map
96 */
97
98 pager_map = uvm_km_suballoc(kernel_map, &uvm.pager_sva, &uvm.pager_eva,
99 PAGER_MAP_SIZE, FALSE, FALSE, NULL);
100 simple_lock_init(&pager_map_wanted_lock);
101 pager_map_wanted = FALSE;
102
103 /*
104 * init ASYNC I/O queue
105 */
106
107 TAILQ_INIT(&uvm.aio_done);
108
109 /*
110 * call pager init functions
111 */
112 for (lcv = 0 ;
113 lcv < sizeof(uvmpagerops)/sizeof(struct uvm_pagerops *) ; lcv++) {
114 if (uvmpagerops[lcv]->pgo_init)
115 uvmpagerops[lcv]->pgo_init();
116 }
117 }
118
119 /*
120 * uvm_pagermapin: map pages into KVA (pager_map) for I/O that needs mappings
121 *
122 * we basically just map in a blank map entry to reserve the space in the
123 * map and then use pmap_enter() to put the mappings in by hand.
124 */
125
126 vm_offset_t uvm_pagermapin(pps, npages, aiop, waitf)
127
128 struct vm_page **pps;
129 int npages;
130 struct uvm_aiodesc **aiop; /* OUT */
131 int waitf;
132
133 {
134 vm_size_t size;
135 vm_offset_t kva;
136 struct uvm_aiodesc *aio;
137 #if !defined(PMAP_NEW)
138 vm_offset_t cva;
139 struct vm_page *pp;
140 #endif
141 UVMHIST_FUNC("uvm_pagermapin"); UVMHIST_CALLED(maphist);
142
143 UVMHIST_LOG(maphist,"(pps=0x%x, npages=%d, aiop=0x%x, waitf=%d)",
144 pps, npages, aiop, waitf);
145
146 ReStart:
147 if (aiop) {
148 MALLOC(aio, struct uvm_aiodesc *, sizeof(*aio), M_TEMP, waitf);
149 if (aio == NULL)
150 return(0);
151 *aiop = aio;
152 } else {
153 aio = NULL;
154 }
155
156 size = npages * PAGE_SIZE;
157 kva = NULL; /* let system choose VA */
158
159 if (uvm_map(pager_map, &kva, size, NULL,
160 UVM_UNKNOWN_OFFSET, UVM_FLAG_NOMERGE) != KERN_SUCCESS) {
161 if (waitf == M_NOWAIT) {
162 if (aio)
163 FREE(aio, M_TEMP);
164 UVMHIST_LOG(maphist,"<- NOWAIT failed", 0,0,0,0);
165 return(NULL);
166 }
167 simple_lock(&pager_map_wanted_lock);
168 pager_map_wanted = TRUE;
169 UVMHIST_LOG(maphist, " SLEEPING on pager_map",0,0,0,0);
170 UVM_UNLOCK_AND_WAIT(pager_map, &pager_map_wanted_lock, FALSE,
171 "pager_map",0);
172 goto ReStart;
173 }
174
175 #if defined(PMAP_NEW)
176 /*
177 * XXX: (ab)using the pmap module to store state info for us.
178 * (pmap stores the PAs... we fetch them back later and convert back
179 * to pages with PHYS_TO_VM_PAGE).
180 */
181 pmap_kenter_pgs(kva, pps, npages);
182
183 #else /* PMAP_NEW */
184
185 /* got it */
186 for (cva = kva ; size != 0 ; size -= PAGE_SIZE, cva += PAGE_SIZE) {
187 pp = *pps++;
188 #ifdef DEBUG
189 if ((pp->flags & PG_BUSY) == 0)
190 panic("uvm_pagermapin: page not busy");
191 #endif
192
193 pmap_enter(vm_map_pmap(pager_map), cva, VM_PAGE_TO_PHYS(pp),
194 VM_PROT_DEFAULT, TRUE);
195 }
196
197 #endif /* PMAP_NEW */
198
199 UVMHIST_LOG(maphist, "<- done (KVA=0x%x)", kva,0,0,0);
200 return(kva);
201 }
202
203 /*
204 * uvm_pagermapout: remove pager_map mapping
205 *
206 * we remove our mappings by hand and then remove the mapping (waking
207 * up anyone wanting space).
208 */
209
210 void uvm_pagermapout(kva, npages)
211
212 vm_offset_t kva;
213 int npages;
214
215 {
216 vm_size_t size = npages * PAGE_SIZE;
217 vm_map_entry_t entries;
218 UVMHIST_FUNC("uvm_pagermapout"); UVMHIST_CALLED(maphist);
219
220 UVMHIST_LOG(maphist, " (kva=0x%x, npages=%d)", kva, npages,0,0);
221
222 /*
223 * duplicate uvm_unmap, but add in pager_map_wanted handling.
224 */
225
226 vm_map_lock(pager_map);
227 (void) uvm_unmap_remove(pager_map, kva, kva + size, 0, &entries);
228 simple_lock(&pager_map_wanted_lock);
229 if (pager_map_wanted) {
230 pager_map_wanted = FALSE;
231 wakeup(pager_map);
232 }
233 simple_unlock(&pager_map_wanted_lock);
234 vm_map_unlock(pager_map);
235 if (entries)
236 uvm_unmap_detach(entries, 0);
237
238 UVMHIST_LOG(maphist,"<- done",0,0,0,0);
239 }
240
241 /*
242 * uvm_mk_pcluster
243 *
244 * generic "make 'pager put' cluster" function. a pager can either
245 * [1] set pgo_mk_pcluster to NULL (never cluster), [2] set it to this
246 * generic function, or [3] set it to a pager specific function.
247 *
248 * => caller must lock object _and_ pagequeues (since we need to look
249 * at active vs. inactive bits, etc.)
250 * => caller must make center page busy and write-protect it
251 * => we mark all cluster pages busy for the caller
252 * => the caller must unbusy all pages (and check wanted/released
253 * status if it drops the object lock)
254 * => flags:
255 * PGO_ALLPAGES: all pages in object are valid targets
256 * !PGO_ALLPAGES: use "lo" and "hi" to limit range of cluster
257 * PGO_DOACTCLUST: include active pages in cluster.
258 * NOTE: the caller should clear PG_CLEANCHK bits if PGO_DOACTCLUST.
259 * PG_CLEANCHK is only a hint, but clearing will help reduce
260 * the number of calls we make to the pmap layer.
261 */
262
263 struct vm_page **uvm_mk_pcluster(uobj, pps, npages, center, flags, mlo, mhi)
264
265 struct uvm_object *uobj; /* IN */
266 struct vm_page **pps, *center; /* IN/OUT, IN */
267 int *npages, flags; /* IN/OUT, IN */
268 vm_offset_t mlo, mhi; /* IN (if !PGO_ALLPAGES) */
269
270 {
271 struct vm_page **ppsp, *pclust;
272 vm_offset_t lo, hi, curoff;
273 int center_idx, forward;
274 UVMHIST_FUNC("uvm_mk_pcluster"); UVMHIST_CALLED(maphist);
275
276 /*
277 * center page should already be busy and write protected. XXX:
278 * suppose page is wired? if we lock, then a process could
279 * fault/block on it. if we don't lock, a process could write the
280 * pages in the middle of an I/O. (consider an msync()). let's
281 * lock it for now (better to delay than corrupt data?).
282 */
283
284 /*
285 * get cluster boundaries, check sanity, and apply our limits as well.
286 */
287
288 uobj->pgops->pgo_cluster(uobj, center->offset, &lo, &hi);
289 if ((flags & PGO_ALLPAGES) == 0) {
290 if (lo < mlo)
291 lo = mlo;
292 if (hi > mhi)
293 hi = mhi;
294 }
295 if ((hi - lo) / PAGE_SIZE > *npages) { /* pps too small, bail out! */
296 #ifdef DIAGNOSTIC
297 printf("uvm_mk_pcluster: provided page array too small (fixed)\n");
298 #endif
299 pps[0] = center;
300 *npages = 1;
301 return(pps);
302 }
303
304 /*
305 * now determine the center and attempt to cluster around the
306 * edges
307 */
308
309 center_idx = (center->offset - lo) / PAGE_SIZE;
310 pps[center_idx] = center; /* plug in the center page */
311 ppsp = &pps[center_idx];
312 *npages = 1;
313
314 /*
315 * attempt to cluster around the left [backward], and then
316 * the right side [forward].
317 *
318 * note that for inactive pages (pages that have been deactivated)
319 * there are no valid mappings and PG_CLEAN should be up to date.
320 * [i.e. there is no need to query the pmap with pmap_is_modified
321 * since there are no mappings].
322 */
323
324 for (forward = 0 ; forward <= 1 ; forward++) {
325
326 curoff = center->offset + PAGE_SIZE * (forward) ? 1 : -1;
327 for ( ; (forward == 0 && curoff >= lo) || (forward && curoff < hi) ;
328 curoff = curoff + PAGE_SIZE * (forward) ? 1 : -1) {
329
330 pclust = uvm_pagelookup(uobj, curoff); /* lookup page */
331 if (pclust == NULL)
332 break; /* no page */
333 /* handle active pages */
334 /* NOTE: inactive pages don't have pmap mappings */
335 if ((pclust->pqflags & PQ_INACTIVE) == 0) {
336 if ((flags & PGO_DOACTCLUST) == 0)
337 break; /* dont want mapped pages at all */
338 /* make sure "clean" bit is sync'd */
339 if ((pclust->flags & PG_CLEANCHK) == 0) {
340 if ((pclust->flags & (PG_CLEAN|PG_BUSY)) == PG_CLEAN &&
341 pmap_is_modified(PMAP_PGARG(pclust)))
342 pclust->flags &= ~PG_CLEAN;
343 pclust->flags |= PG_CLEANCHK; /* now checked */
344 }
345 }
346 /* is page available for cleaning and does it need it? */
347 if ((pclust->flags & (PG_CLEAN|PG_BUSY)) != 0)
348 break; /* page is already clean or is busy */
349 /* yes! enroll the page in our array */
350 pclust->flags |= PG_BUSY; /* busy! */
351 UVM_PAGE_OWN(pclust, "uvm_mk_pcluster");
352 /* XXX: protect wired page? see above comment. */
353 pmap_page_protect(PMAP_PGARG(pclust), VM_PROT_READ);
354 if (!forward) {
355 ppsp--; /* back up one page */
356 *ppsp = pclust;
357 } else {
358 ppsp[*npages] = pclust; /* move forward one page */
359 }
360 *npages = *npages + 1;
361 }
362
363 }
364
365 /*
366 * done! return the cluster array to the caller!!!
367 */
368
369 UVMHIST_LOG(maphist, "<- done",0,0,0,0);
370 return(ppsp);
371 }
372
373
374 /*
375 * uvm_shareprot: generic share protect routine
376 *
377 * => caller must lock map entry's map
378 * => caller must lock object pointed to by map entry
379 */
380
381 void uvm_shareprot(entry, prot)
382
383 vm_map_entry_t entry;
384 vm_prot_t prot;
385
386 {
387 struct uvm_object *uobj = entry->object.uvm_obj;
388 struct vm_page *pp;
389 vm_offset_t start, stop;
390 UVMHIST_FUNC("uvm_shareprot"); UVMHIST_CALLED(maphist);
391
392 if (UVM_ET_ISMAP(entry))
393 panic("uvm_shareprot: non-object attached");
394
395 start = entry->offset;
396 stop = start + (entry->end - entry->start);
397
398 /*
399 * traverse list of pages in object. if page in range, pmap_prot it
400 */
401
402 for (pp = uobj->memq.tqh_first ; pp != NULL ; pp = pp->listq.tqe_next) {
403 if (pp->offset >= start && pp->offset < stop)
404 pmap_page_protect(PMAP_PGARG(pp), prot);
405 }
406 UVMHIST_LOG(maphist, "<- done",0,0,0,0);
407 }
408
409 /*
410 * uvm_pager_put: high level pageout routine
411 *
412 * we want to pageout page "pg" to backing store, clustering if
413 * possible.
414 *
415 * => page queues must be locked by caller
416 * => if page is not swap-backed, then "uobj" points to the object
417 * backing it. this object should be locked by the caller.
418 * => if page is swap-backed, then "uobj" should be NULL.
419 * => "pg" should be PG_BUSY (by caller), and !PG_CLEAN
420 * for swap-backed memory, "pg" can be NULL if there is no page
421 * of interest [sometimes the case for the pagedaemon]
422 * => "ppsp_ptr" should point to an array of npages vm_page pointers
423 * for possible cluster building
424 * => flags (first two for non-swap-backed pages)
425 * PGO_ALLPAGES: all pages in uobj are valid targets
426 * PGO_DOACTCLUST: include "PQ_ACTIVE" pages as valid targets
427 * PGO_SYNCIO: do SYNC I/O (no async)
428 * PGO_PDFREECLUST: pagedaemon: drop cluster on successful I/O
429 * => start/stop: if (uobj && !PGO_ALLPAGES) limit targets to this range
430 * if (!uobj) start is the (daddr_t) of the starting swapblk
431 * => return state:
432 * 1. we return the VM_PAGER status code of the pageout
433 * 2. we return with the page queues unlocked
434 * 3. if (uobj != NULL) [!swap_backed] we return with
435 * uobj locked _only_ if PGO_PDFREECLUST is set
436 * AND result != VM_PAGER_PEND. in all other cases
437 * we return with uobj unlocked. [this is a hack
438 * that allows the pagedaemon to save one lock/unlock
439 * pair in the !swap_backed case since we have to
440 * lock the uobj to drop the cluster anyway]
441 * 4. on errors we always drop the cluster. thus, if we return
442 * !PEND, !OK, then the caller only has to worry about
443 * un-busying the main page (not the cluster pages).
444 * 5. on success, if !PGO_PDFREECLUST, we return the cluster
445 * with all pages busy (caller must un-busy and check
446 * wanted/released flags).
447 */
448
449 int uvm_pager_put(uobj, pg, ppsp_ptr, npages, flags, start, stop)
450
451 struct uvm_object *uobj; /* IN */
452 struct vm_page *pg, ***ppsp_ptr;/* IN, IN/OUT */
453 int *npages; /* IN/OUT */
454 int flags; /* IN */
455 vm_offset_t start, stop; /* IN, IN */
456
457 {
458 int result;
459 daddr_t swblk;
460 struct vm_page **ppsp = *ppsp_ptr;
461
462 /*
463 * note that uobj is null if we are doing a swap-backed pageout.
464 * note that uobj is !null if we are doing normal object pageout.
465 * note that the page queues must be locked to cluster.
466 */
467
468 if (uobj) { /* if !swap-backed */
469
470 /*
471 * attempt to build a cluster for pageout using its make-put-cluster
472 * function (if it has one).
473 */
474
475 if (uobj->pgops->pgo_mk_pcluster) {
476 ppsp = uobj->pgops->pgo_mk_pcluster(uobj, ppsp, npages, pg, flags,
477 start, stop);
478 *ppsp_ptr = ppsp; /* update caller's pointer */
479 } else {
480 ppsp[0] = pg;
481 *npages = 1;
482 }
483
484 swblk = 0; /* XXX: keep gcc happy */
485
486 } else {
487
488 /*
489 * for swap-backed pageout, the caller (the pagedaemon) has already
490 * built the cluster for us. the starting swap block we are writing
491 * to has been passed in as "start." "pg" could be NULL if there
492 * is no page we are especially interested in (in which case the
493 * whole cluster gets dropped in the event of an error or a sync
494 * "done").
495 */
496 swblk = (daddr_t) start;
497 /* ppsp and npages should be ok */
498 }
499
500 /* now that we've clustered we can unlock the page queues */
501 uvm_unlock_pageq();
502
503 /*
504 * now attempt the I/O. if we have a failure and we are
505 * clustered, we will drop the cluster and try again.
506 */
507
508 ReTry:
509 if (uobj) {
510 /* object is locked */
511 result = uobj->pgops->pgo_put(uobj, ppsp, *npages, flags & PGO_SYNCIO);
512 /* object is now unlocked */
513 } else {
514 /* nothing locked */
515 result = uvm_swap_put(swblk, ppsp, *npages, flags & PGO_SYNCIO);
516 /* nothing locked */
517 }
518
519 /*
520 * we have attempted the I/O.
521 *
522 * if the I/O was a success then:
523 * if !PGO_PDFREECLUST, we return the cluster to the
524 * caller (who must un-busy all pages)
525 * else we un-busy cluster pages for the pagedaemon
526 *
527 * if I/O is pending (async i/o) then we return the pending code.
528 * [in this case the async i/o done function must clean up when
529 * i/o is done...]
530 */
531
532 if (result == VM_PAGER_PEND || result == VM_PAGER_OK) {
533 if (result == VM_PAGER_OK && (flags & PGO_PDFREECLUST)) {
534 /*
535 * drop cluster and relock object (only if I/O is not pending)
536 */
537 if (uobj)
538 simple_lock(&uobj->vmobjlock); /* required for dropcluster */
539 if (*npages > 1 || pg == NULL)
540 uvm_pager_dropcluster(uobj, pg, ppsp, npages, PGO_PDFREECLUST, 0);
541 /* if (uobj): object still locked, as per return-state item #3 */
542 }
543 return(result);
544 }
545
546 /*
547 * a pager error occured. if we have clustered, we drop the
548 * cluster and try again.
549 */
550
551 if (*npages > 1 || pg == NULL) {
552 if (uobj)
553 simple_lock(&uobj->vmobjlock);
554 uvm_pager_dropcluster(uobj, pg, ppsp, npages, PGO_REALLOCSWAP, swblk);
555 if (pg != NULL)
556 goto ReTry;
557 }
558
559 /*
560 * a pager error occured (even after dropping the cluster, if there
561 * was one). give up! the caller only has one page ("pg")
562 * to worry about.
563 */
564
565 if (uobj && (flags & PGO_PDFREECLUST) != 0)
566 simple_lock(&uobj->vmobjlock);
567 return(result);
568 }
569
570 /*
571 * uvm_pager_dropcluster: drop a cluster we have built (because we
572 * got an error, or, if PGO_PDFREECLUST we are un-busying the
573 * cluster pages on behalf of the pagedaemon).
574 *
575 * => uobj, if non-null, is a non-swap-backed object that is
576 * locked by the caller. we return with this object still
577 * locked.
578 * => page queues are not locked
579 * => pg is our page of interest (the one we clustered around, can be null)
580 * => ppsp/npages is our current cluster
581 * => flags: PGO_PDFREECLUST: pageout was a success: un-busy cluster
582 * pages on behalf of the pagedaemon.
583 * PGO_REALLOCSWAP: drop previously allocated swap slots for
584 * clustered swap-backed pages (except for "pg" if !NULL)
585 * "swblk" is the start of swap alloc (e.g. for ppsp[0])
586 * [only meaningful if swap-backed (uobj == NULL)]
587 */
588
589
590 void uvm_pager_dropcluster(uobj, pg, ppsp, npages, flags, swblk)
591
592 struct uvm_object *uobj; /* IN */
593 struct vm_page *pg, **ppsp; /* IN, IN/OUT */
594 int *npages; /* IN/OUT */
595 int flags;
596 int swblk; /* valid if (uobj == NULL && PGO_REALLOCSWAP) */
597
598 {
599 int lcv;
600 boolean_t obj_is_alive;
601
602 /*
603 * if we need to reallocate swap space for the cluster we are dropping
604 * (true if swap-backed and PGO_REALLOCSWAP) then free the old allocation
605 * now. save a block for "pg" if it is non-NULL.
606 *
607 * note that we will zap the object's pointer to swap in the "for" loop
608 * below...
609 */
610
611 if (uobj == NULL && (flags & PGO_REALLOCSWAP)) {
612 if (pg)
613 uvm_swap_free(swblk + 1, *npages - 1);
614 else
615 uvm_swap_free(swblk, *npages);
616 }
617
618 /*
619 * drop all pages but "pg"
620 */
621
622 for (lcv = 0 ; lcv < *npages ; lcv++) {
623
624 if (ppsp[lcv] == pg) /* skip "pg" */
625 continue;
626
627 /*
628 * if swap-backed, gain lock on object that owns page. note
629 * that PQ_ANON bit can't change as long as we are holding
630 * the PG_BUSY bit (so there is no need to lock the page
631 * queues to test it).
632 *
633 * once we have the lock, dispose of the pointer to swap, if requested
634 */
635 if (!uobj) {
636 if (ppsp[lcv]->pqflags & PQ_ANON) {
637 simple_lock(&ppsp[lcv]->uanon->an_lock);
638 if (flags & PGO_REALLOCSWAP)
639 ppsp[lcv]->uanon->an_swslot = 0; /* zap swap block */
640 } else {
641 simple_lock(&ppsp[lcv]->uobject->vmobjlock);
642 if (flags & PGO_REALLOCSWAP)
643 uao_set_swslot(ppsp[lcv]->uobject, ppsp[lcv]->offset / PAGE_SIZE, 0);
644 }
645 }
646
647 /* did someone want the page while we had it busy-locked? */
648 if (ppsp[lcv]->flags & PG_WANTED)
649 thread_wakeup(ppsp[lcv]); /* still holding obj lock */
650
651 /* if page was released, release it. otherwise un-busy it */
652 if (ppsp[lcv]->flags & PG_RELEASED) {
653
654 if (ppsp[lcv]->pqflags & PQ_ANON) {
655 ppsp[lcv]->flags &= ~(PG_BUSY); /* so that anfree will free */
656 UVM_PAGE_OWN(ppsp[lcv], NULL);
657 pmap_page_protect(PMAP_PGARG(ppsp[lcv]), VM_PROT_NONE); /* be safe */
658 uvm_anfree(ppsp[lcv]->uanon); /* kills anon and frees pg */
659 continue;
660 }
661
662 /*
663 * pgo_releasepg will dump the page for us
664 */
665
666 #ifdef DIAGNOSTIC
667 if (ppsp[lcv]->uobject->pgops->pgo_releasepg == NULL)
668 panic("uvm_pager_dropcluster: no releasepg function");
669 #endif
670 obj_is_alive = ppsp[lcv]->uobject->pgops->pgo_releasepg(pg, NULL);
671
672 #ifdef DIAGNOSTIC
673 /* for normal objects, "pg" is still PG_BUSY by us, so obj can't die */
674 if (uobj && !obj_is_alive)
675 panic("uvm_pager_dropcluster: object died with active page");
676 #endif
677 if (!obj_is_alive)
678 continue;
679
680 } else {
681 ppsp[lcv]->flags &= ~(PG_BUSY|PG_WANTED);
682 UVM_PAGE_OWN(ppsp[lcv], NULL);
683 }
684
685 /*
686 * if we are operating on behalf of the pagedaemon and we
687 * had a successful pageout update the page!
688 */
689 if (flags & PGO_PDFREECLUST) {
690 /* XXX: with PMAP_NEW ref should already be clear, but don't trust! */
691 pmap_clear_reference(PMAP_PGARG(ppsp[lcv]));
692 pmap_clear_modify(PMAP_PGARG(ppsp[lcv]));
693 ppsp[lcv]->flags |= PG_CLEAN;
694 }
695
696 /* if anonymous cluster, unlock object and move on */
697 if (!uobj) {
698 if (ppsp[lcv]->pqflags & PQ_ANON)
699 simple_unlock(&ppsp[lcv]->uanon->an_lock);
700 else
701 simple_unlock(&ppsp[lcv]->uobject->vmobjlock);
702 }
703
704 }
705
706 /*
707 * drop to a cluster of 1 page ("pg") if requested
708 */
709
710 if (pg && (flags & PGO_PDFREECLUST) == 0) {
711 /*
712 * if we are not a successful pageout, we make a 1 page cluster.
713 */
714 ppsp[0] = pg;
715 *npages = 1;
716
717 /*
718 * assign new swap block to new cluster, if anon backed
719 */
720 if (uobj == NULL && (flags & PGO_REALLOCSWAP)) {
721 if (pg->pqflags & PQ_ANON) {
722 simple_lock(&pg->uanon->an_lock);
723 pg->uanon->an_swslot = swblk; /* reassign */
724 simple_unlock(&pg->uanon->an_lock);
725 } else {
726 simple_lock(&pg->uobject->vmobjlock);
727 uao_set_swslot(pg->uobject, pg->offset / PAGE_SIZE, swblk);
728 simple_unlock(&pg->uobject->vmobjlock);
729 }
730 }
731 }
732
733 }
734