uvm_aobj.c revision 1.1 1 /* $Id: uvm_aobj.c,v 1.1 1998/02/05 06:25:10 mrg Exp $ */
2
3 /* copyright here */
4
5 #include <sys/param.h>
6 #include <sys/systm.h>
7 #include <sys/proc.h>
8 #include <sys/malloc.h>
9
10 #include <vm/vm.h>
11 #include <vm/vm_page.h>
12 #include <vm/vm_kern.h>
13
14 #include <uvm/uvm.h>
15
16 /*
17 * uvm_aobj.c: anonymous-memory backed uvm_object
18 */
19
20 /*
21 * an aobj manages anonymous-memory backed uvm_objects. in addition
22 * to keeping the list of resident pages, it also keeps a list of
23 * allocated swap blocks. depending on the size of the aobj this list
24 * of allocated swap blocks is either stored in an array (small objects)
25 * or in a hash table (large objects).
26 */
27
28 /*
29 * local structures
30 */
31
32 /*
33 * for hash tables, we break the address space of the aobj into blocks
34 * of UAO_SWHASH_CLUSTER_SIZE pages. we require the cluster size to
35 * be a power of two.
36 */
37
38 #define UAO_SWHASH_CLUSTER_SHIFT 4
39 #define UAO_SWHASH_CLUSTER_SIZE (1 << UAO_SWHASH_CLUSTER_SHIFT)
40
41 /* get the "tag" for this page index */
42 #define UAO_SWHASH_ELT_TAG(PAGEIDX) \
43 ((PAGEIDX) >> UAO_SWHASH_CLUSTER_SHIFT)
44
45 /* given an ELT and a page index, find the swap slot */
46 #define UAO_SWHASH_ELT_PAGESLOT(ELT, PAGEIDX) \
47 ((ELT)->slots[(PAGEIDX) & (UAO_SWHASH_CLUSTER_SIZE - 1)])
48
49 /* given an ELT, return its pageidx base */
50 #define UAO_SWHASH_ELT_PAGEIDX_BASE(ELT) \
51 ((ELT)->tag << UAO_SWHASH_CLUSTER_SHIFT)
52
53 /*
54 * the swhash hash function
55 */
56 #define UAO_SWHASH_HASH(AOBJ, PAGEIDX) \
57 (&(AOBJ)->u_swhash[(((PAGEIDX) >> UAO_SWHASH_CLUSTER_SHIFT) \
58 & (AOBJ)->u_swhashmask)])
59
60 /*
61 * the swhash threshhold determines if we will use an array or a
62 * hash table to store the list of allocated swap blocks.
63 */
64
65 #define UAO_SWHASH_THRESHOLD (UAO_SWHASH_CLUSTER_SIZE * 4)
66 #define UAO_USES_SWHASH(AOBJ) \
67 ((AOBJ)->u_pages > UAO_SWHASH_THRESHOLD) /* use hash? */
68
69 /*
70 * the number of buckets in a swhash, with and upper bound
71 */
72 #define UAO_SWHASH_MAXBUCKETS 256
73 #define UAO_SWHASH_BUCKETS(AOBJ) \
74 (min((AOBJ)->u_pages >> UAO_SWHASH_CLUSTER_SHIFT, \
75 UAO_SWHASH_MAXBUCKETS))
76
77
78 /* XXXCHS until the deadlock is fixed */
79 #undef UAO_USES_SWHASH
80 #define UAO_USES_SWHASH(AOBJ) 0
81
82
83 /*
84 * uao_swhash_elt: when a hash table is being used, this structure defines
85 * the format of an entry in the bucket list.
86 */
87
88 struct uao_swhash_elt {
89 LIST_ENTRY(uao_swhash_elt) list; /* the hash list */
90 vm_offset_t tag; /* our 'tag' */
91 int count; /* our number of active slots */
92 int slots[UAO_SWHASH_CLUSTER_SIZE]; /* the slots */
93 };
94
95 /*
96 * uao_swhash: the swap hash table structure
97 */
98
99 LIST_HEAD(uao_swhash, uao_swhash_elt);
100
101
102 /*
103 * uvm_aobj: the actual anon-backed uvm_object
104 *
105 * => the uvm_object is at the top of the structure, this allows
106 * (struct uvm_device *) == (struct uvm_object *)
107 * => only one of u_swslots and u_swhash is used in any given aobj
108 */
109
110 struct uvm_aobj {
111 struct uvm_object u_obj; /* has: lock, pgops, memq, #pages, #refs */
112 vm_size_t u_pages; /* number of pages in entire object */
113 int u_flags; /* the flags (see uvm_aobj.h) */
114 int *u_swslots; /* array of offset->swapslot mappings */
115 struct uao_swhash *u_swhash; /* hashtable of offset->swapslot mappings */
116 /* (u_swhash is an array of bucket heads) */
117 u_long u_swhashmask; /* mask for hashtable */
118 LIST_ENTRY(uvm_aobj) u_list; /* global list of aobjs */
119 };
120
121 /*
122 * local functions
123 */
124
125 static void uao_init __P((void));
126 static struct uao_swhash_elt *uao_find_swhash_elt __P((struct uvm_aobj *,
127 int, boolean_t));
128 static int uao_find_swslot __P((struct uvm_aobj *,
129 vm_offset_t));
130 static boolean_t uao_flush __P((struct uvm_object *,
131 vm_offset_t, vm_offset_t,
132 int));
133 static void uao_free __P((struct uvm_aobj *));
134 static int uao_get __P((struct uvm_object *, vm_offset_t,
135 vm_page_t *, int *, int,
136 vm_prot_t, int, int));
137 static boolean_t uao_releasepg __P((struct vm_page *,
138 struct vm_page **));
139
140
141
142 /*
143 * aobj_pager
144 *
145 * note that some functions (e.g. put) are handled elsewhere
146 */
147
148 struct uvm_pagerops aobj_pager = {
149 uao_init, /* init */
150 NULL, /* attach */
151 uao_reference, /* reference */
152 uao_detach, /* detach */
153 NULL, /* fault */
154 uao_flush, /* flush */
155 uao_get, /* get */
156 NULL, /* asyncget */
157 NULL, /* put (done by pagedaemon) */
158 NULL, /* cluster */
159 NULL, /* mk_pcluster */
160 uvm_shareprot, /* shareprot */
161 NULL, /* aiodone */
162 uao_releasepg /* releasepg */
163 };
164
165 /*
166 * uao_list: global list of active aobjs, locked by uao_list_lock
167 */
168
169 static LIST_HEAD(aobjlist, uvm_aobj) uao_list;
170 #if NCPU > 1
171 static simple_lock_data_t uao_list_lock;
172 #endif
173
174
175 /*
176 * functions
177 */
178
179 /*
180 * hash table/array related functions
181 */
182
183 /*
184 * uao_find_swhash_elt: find (or create) a hash table entry for a page
185 * offset.
186 *
187 * => the object should be locked by the caller
188 */
189
190 static struct uao_swhash_elt *uao_find_swhash_elt(aobj, pageidx, create)
191
192 struct uvm_aobj *aobj;
193 int pageidx;
194 boolean_t create;
195
196 {
197 struct uao_swhash *swhash;
198 struct uao_swhash_elt *elt;
199 int page_tag;
200
201 swhash = UAO_SWHASH_HASH(aobj, pageidx); /* first hash to get bucket */
202 page_tag = UAO_SWHASH_ELT_TAG(pageidx); /* tag to search for */
203
204 /*
205 * now search the bucket for the requested tag
206 */
207 for (elt = swhash->lh_first; elt != NULL; elt = elt->list.le_next) {
208 if (elt->tag == page_tag)
209 return(elt);
210 }
211
212 /* fail now if we are not allowed to create a new entry in the bucket */
213 if (!create)
214 return NULL;
215
216
217 /*
218 * malloc a new entry for the bucket and init/insert it in
219 */
220 MALLOC(elt, struct uao_swhash_elt *, sizeof(*elt), M_UVMAOBJ, M_WAITOK);
221 elt->tag = page_tag;
222 bzero(elt->slots, sizeof(elt->slots));
223 LIST_INSERT_HEAD(swhash, elt, list);
224
225 return(elt);
226 }
227
228 /*
229 * uao_find_swslot: find the swap slot number for an aobj/pageidx
230 *
231 * => object must be locked by caller
232 */
233
234 __inline static int uao_find_swslot(aobj, pageidx)
235
236 struct uvm_aobj *aobj;
237 vm_offset_t pageidx;
238
239 {
240 /*
241 * if noswap flag is set, then we never return a slot
242 */
243
244 if (aobj->u_flags & UAO_FLAG_NOSWAP)
245 return(0);
246
247 /*
248 * if hashing, look in hash table.
249 */
250
251 if (UAO_USES_SWHASH(aobj)) {
252 struct uao_swhash_elt *elt = uao_find_swhash_elt(aobj, pageidx, FALSE);
253
254 if (elt)
255 return(UAO_SWHASH_ELT_PAGESLOT(elt, pageidx));
256 else
257 return(NULL);
258 }
259
260 /*
261 * otherwise, look in the array
262 */
263 return(aobj->u_swslots[pageidx]);
264 }
265
266 /*
267 * uao_set_swslot: set the swap slot for a page in an aobj.
268 *
269 * => setting a slot to zero frees the slot
270 * => object must be locked by caller
271 */
272
273 int uao_set_swslot(uobj, pageidx, slot)
274
275 struct uvm_object *uobj;
276 int pageidx, slot;
277
278 {
279 struct uvm_aobj *aobj = (struct uvm_aobj *)uobj;
280 int oldslot;
281 UVMHIST_FUNC("uao_set_swslot"); UVMHIST_CALLED(pdhist);
282 UVMHIST_LOG(pdhist, "aobj %p pageidx %d slot %d", aobj, pageidx, slot, 0);
283
284 /*
285 * if noswap flag is set, then we can't set a slot
286 */
287
288 if (aobj->u_flags & UAO_FLAG_NOSWAP) {
289
290 if (slot == 0)
291 return(0); /* a clear is ok */
292
293 /* but a set is not */
294 printf("uao_set_swslot: uobj = %p\n", uobj);
295 panic("uao_set_swslot: attempt to set a slot on a NOSWAP object");
296 }
297
298 /*
299 * are we using a hash table? if so, add it in the hash.
300 */
301
302 if (UAO_USES_SWHASH(aobj)) {
303 struct uao_swhash_elt *elt = uao_find_swhash_elt(aobj, pageidx, TRUE);
304
305 oldslot = UAO_SWHASH_ELT_PAGESLOT(elt, pageidx);
306 UAO_SWHASH_ELT_PAGESLOT(elt, pageidx) = slot;
307
308 /*
309 * now adjust the elt's reference counter and free it if we've dropped
310 * it to zero.
311 */
312
313 if (slot) { /* an allocation? */
314
315 if (oldslot == 0)
316 elt->count++;
317
318 } else { /* freeing slot ... */
319
320 if (oldslot) /* to be safe (who would replace zero with zero?) */
321 elt->count--;
322
323 if (elt->count == 0) {
324 LIST_REMOVE(elt, list);
325 FREE(elt, M_UVMAOBJ);
326 }
327 }
328
329 } else {
330
331 /* we are using an array */
332 oldslot = aobj->u_swslots[pageidx];
333 aobj->u_swslots[pageidx] = slot;
334
335 }
336
337 return(oldslot);
338 }
339
340 /*
341 * end of hash/array functions
342 */
343
344 /*
345 * uao_free: free all resources held by an aobj, and then free the aobj
346 *
347 * => the aobj should be dead
348 */
349
350 static void
351 uao_free(aobj)
352 struct uvm_aobj *aobj;
353 {
354
355
356 if (UAO_USES_SWHASH(aobj)) {
357 int i, hashbuckets = aobj->u_swhashmask + 1;
358
359 /*
360 * free the swslots from each hash bucket,
361 * then the hash bucket, and finally the hash table itself.
362 */
363 for (i = 0; i < hashbuckets; i++) {
364 struct uao_swhash_elt *elt, *next;
365
366 for (elt = aobj->u_swhash[i].lh_first; elt != NULL; elt = next) {
367 int j;
368
369 for (j = 0; j < UAO_SWHASH_CLUSTER_SIZE; j++)
370 {
371 int slot = elt->slots[j];
372
373 if (slot)
374 {
375 uvm_swap_free(slot, 1);
376 }
377 }
378
379 next = elt->list.le_next;
380 FREE(elt, M_UVMAOBJ);
381 }
382 }
383 FREE(aobj->u_swhash, M_UVMAOBJ);
384 } else {
385 int i;
386
387 /*
388 * free the array
389 */
390
391 for (i = 0; i < aobj->u_pages; i++)
392 {
393 int slot = aobj->u_swslots[i];
394
395 if (slot)
396 {
397 uvm_swap_free(slot, 1);
398 }
399 }
400
401 FREE(aobj->u_swslots, M_UVMAOBJ);
402 }
403
404 /*
405 * finally free the aobj itself
406 */
407 FREE(aobj, M_UVMAOBJ);
408 }
409
410
411 /*
412 * pager functions
413 */
414
415 /*
416 * uao_create: create an aobj of the given size and return its uvm_object.
417 *
418 * => for normal use, flags are always zero
419 * => for the kernel object, the flags are:
420 * UAO_FLAG_KERNOBJ - allocate the kernel object (can only happen once)
421 * UAO_FLAG_KERNSWAP - enable swapping of kernel object (" ")
422 */
423
424 struct uvm_object *uao_create(size, flags)
425
426 vm_size_t size;
427 int flags;
428
429 {
430 static struct uvm_aobj kernel_object_store; /* home of kernel_object */
431 static int kobj_alloced = 0; /* not allocated yet */
432 int pages = round_page(size) / PAGE_SIZE;
433 struct uvm_aobj *aobj;
434
435 /*
436 * malloc a new aobj unless we are asked for the kernel object
437 */
438 if (flags & UAO_FLAG_KERNOBJ) { /* want kernel object? */
439 if (kobj_alloced)
440 panic("uao_create: kernel object already allocated");
441
442 aobj = &kernel_object_store;
443 aobj->u_pages = pages;
444 aobj->u_flags = UAO_FLAG_NOSWAP; /* no swap to start */
445 aobj->u_obj.uo_refs = UVM_OBJ_KERN; /* we are special, we never die */
446 kobj_alloced = UAO_FLAG_KERNOBJ;
447
448 } else if (flags & UAO_FLAG_KERNSWAP) {
449
450 aobj = &kernel_object_store;
451 if (kobj_alloced != UAO_FLAG_KERNOBJ)
452 panic("uao_create: asked to enable swap on kernel object");
453 kobj_alloced = UAO_FLAG_KERNSWAP;
454
455 } else { /* normal object */
456
457 MALLOC(aobj, struct uvm_aobj *, sizeof(*aobj), M_UVMAOBJ, M_WAITOK);
458 aobj->u_pages = pages;
459 aobj->u_flags = 0; /* normal object */
460 aobj->u_obj.uo_refs = 1; /* start with 1 reference */
461
462 }
463
464 /*
465 * allocate hash/array if necessary
466 *
467 * note: in the KERNSWAP case no need to worry about locking since
468 * we are still booting we should be the only thread around.
469 *
470 * XXXCHS: WAITOK is wrong for kernel object - we should panic rather
471 * than wait... but hashinit() doesn't take a malloc wait flag.
472 */
473
474 if (flags == 0 || (flags & UAO_FLAG_KERNSWAP) != 0) {
475
476 /* allocate hash table or array depending on object size */
477 if (UAO_USES_SWHASH(aobj)) {
478 aobj->u_swhash = hashinit(UAO_SWHASH_BUCKETS(aobj), M_UVMAOBJ,
479 &aobj->u_swhashmask);
480 } else {
481 MALLOC(aobj->u_swslots, int *, pages * sizeof(int), M_UVMAOBJ, M_WAITOK);
482 bzero(aobj->u_swslots, pages * sizeof(int));
483 }
484
485 if (flags) {
486 aobj->u_flags &= ~UAO_FLAG_NOSWAP; /* clear noswap */
487 return(&aobj->u_obj);
488 /* done! */
489 }
490 }
491
492 /*
493 * init aobj fields
494 */
495 simple_lock_init(&aobj->u_obj.vmobjlock);
496 aobj->u_obj.pgops = &aobj_pager;
497 TAILQ_INIT(&aobj->u_obj.memq);
498 aobj->u_obj.uo_npages = 0;
499
500 /*
501 * now that aobj is ready, add it to the global list
502 * XXXCHS: uao_init hasn't been called'd in the KERNOBJ case, do we really
503 * need the kernel object on this list anyway?
504 */
505 simple_lock(&uao_list_lock);
506 LIST_INSERT_HEAD(&uao_list, aobj, u_list);
507 simple_unlock(&uao_list_lock);
508
509 /*
510 * done!
511 */
512 return(&aobj->u_obj);
513 }
514
515
516
517 /*
518 * uao_init: set up aobj pager subsystem
519 *
520 * => called at boot time from uvm_pager_init()
521 */
522
523 static void uao_init()
524
525 {
526 LIST_INIT(&uao_list);
527 simple_lock_init(&uao_list_lock);
528 }
529
530 /*
531 * uao_reference: add a ref to an aobj
532 *
533 * => aobj must be unlocked (we will lock it)
534 */
535
536 void uao_reference(uobj)
537
538 struct uvm_object *uobj;
539
540 {
541 UVMHIST_FUNC("uao_reference"); UVMHIST_CALLED(maphist);
542
543 /*
544 * kernel_object already has plenty of references, leave it alone.
545 */
546
547 if (uobj->uo_refs == UVM_OBJ_KERN) {
548 return;
549 }
550
551 simple_lock(&uobj->vmobjlock);
552 uobj->uo_refs++; /* bump! */
553 UVMHIST_LOG(maphist, "<- done (uobj=0x%x, ref = %d)",
554 uobj, uobj->uo_refs,0,0);
555 simple_unlock(&uobj->vmobjlock);
556 }
557
558 /*
559 * uao_detach: drop a reference to an aobj
560 *
561 * => aobj must be unlocked, we will lock it
562 */
563
564 void uao_detach(uobj)
565
566 struct uvm_object *uobj;
567
568 {
569 struct uvm_aobj *aobj = (struct uvm_aobj *)uobj;
570 struct vm_page *pg;
571 boolean_t busybody;
572 UVMHIST_FUNC("uao_detach"); UVMHIST_CALLED(maphist);
573
574 /*
575 * detaching from kernel_object is a noop.
576 */
577
578 if (uobj->uo_refs == UVM_OBJ_KERN) {
579 return;
580 }
581
582 simple_lock(&uobj->vmobjlock);
583
584 UVMHIST_LOG(maphist," (uobj=0x%x) ref=%d", uobj,uobj->uo_refs,0,0);
585 uobj->uo_refs--; /* drop ref! */
586 if (uobj->uo_refs) { /* still more refs? */
587 simple_unlock(&uobj->vmobjlock);
588 UVMHIST_LOG(maphist, "<- done (rc>0)", 0,0,0,0);
589 return;
590 }
591
592 /*
593 * remove the aobj from the global list.
594 */
595 simple_lock(&uao_list_lock);
596 LIST_REMOVE(aobj, u_list);
597 simple_unlock(&uao_list_lock);
598
599 /*
600 * free all the pages that aren't PG_BUSY, mark for release any that are.
601 */
602
603 busybody = FALSE;
604 for (pg = uobj->memq.tqh_first ; pg != NULL ; pg = pg->listq.tqe_next) {
605 int swslot;
606
607 if (pg->flags & PG_BUSY) {
608 pg->flags |= PG_RELEASED;
609 busybody = TRUE;
610 continue;
611 }
612
613 /* zap the mappings, free the page, free the swap slot (if any) */
614 pmap_page_protect(PMAP_PGARG(pg), VM_PROT_NONE);
615 uvm_lock_pageq();
616 uvm_pagefree(pg);
617 uvm_unlock_pageq();
618
619 swslot = uao_set_swslot(&aobj->u_obj, pg->offset / PAGE_SIZE, 0);
620 if (swslot) {
621 uvm_swap_free(swslot, 1);
622 }
623 }
624
625 /*
626 * if we found any busy pages, we're done for now.
627 * mark the aobj for death, releasepg will finish up for us.
628 */
629 if (busybody) {
630 aobj->u_flags |= UAO_FLAG_KILLME;
631 simple_unlock(&aobj->u_obj.vmobjlock);
632 return;
633 }
634
635 /*
636 * finally, free the rest.
637 */
638 uao_free(aobj);
639 }
640
641
642
643 /*
644 * uao_flush: uh, yea, sure it's flushed. really!
645 */
646 boolean_t uao_flush(uobj, start, end, flags)
647
648 struct uvm_object *uobj;
649 vm_offset_t start, end;
650 int flags;
651
652 {
653 /*
654 * anonymous memory doesn't "flush"
655 */
656 /*
657 * XXX
658 * deal with PGO_DEACTIVATE (for madvise(MADV_SEQUENTIAL))
659 * and PGO_FREE (for msync(MSINVALIDATE))
660 */
661 return TRUE;
662 }
663
664 /*
665 * uao_get: fetch me a page
666 *
667 * we have three cases:
668 * 1: page is resident -> just return the page.
669 * 2: page is zero-fill -> allocate a new page and zero it.
670 * 3: page is swapped out -> fetch the page from swap.
671 *
672 * cases 1 and 2 can be handled with PGO_LOCKED, case 3 cannot.
673 * so, if the "center" page hits case 3 (or any page, with PGO_ALLPAGES),
674 * then we will need to return VM_PAGER_UNLOCK.
675 *
676 * => prefer map unlocked (not required)
677 * => object must be locked! we will _unlock_ it before starting any I/O.
678 * => flags: PGO_ALLPAGES: get all of the pages
679 * PGO_LOCKED: fault data structures are locked
680 * => NOTE: offset is the offset of pps[0], _NOT_ pps[centeridx]
681 * => NOTE: caller must check for released pages!!
682 */
683
684 static int uao_get(uobj, offset, pps, npagesp, centeridx, access_type,
685 advice, flags)
686
687 struct uvm_object *uobj;
688 vm_offset_t offset;
689 struct vm_page **pps;
690 int *npagesp;
691 int centeridx, advice, flags;
692 vm_prot_t access_type;
693
694 {
695 struct uvm_aobj *aobj = (struct uvm_aobj *)uobj;
696 vm_offset_t current_offset;
697 vm_page_t ptmp;
698 int lcv, gotpages, maxpages, swslot, rv;
699 boolean_t done;
700 UVMHIST_FUNC("uao_get"); UVMHIST_CALLED(pdhist);
701
702 UVMHIST_LOG(pdhist, "aobj=%p flags=%d", aobj, flags,0,0);
703
704 /*
705 * get number of pages
706 */
707
708 maxpages = *npagesp;
709
710 /*
711 * step 1: handled the case where fault data structures are locked.
712 */
713
714 if (flags & PGO_LOCKED) {
715
716 /*
717 * step 1a: get pages that are already resident. only do this
718 * if the data structures are locked (i.e. the first time through).
719 */
720
721 done = TRUE; /* be optimistic */
722 gotpages = 0; /* # of pages we got so far */
723
724 for (lcv = 0, current_offset = offset ;
725 lcv < maxpages ; lcv++, current_offset += PAGE_SIZE) {
726
727 /* do we care about this page? if not, skip it */
728 if (pps[lcv] == PGO_DONTCARE)
729 continue;
730
731 ptmp = uvm_pagelookup(uobj, current_offset);
732
733 /*
734 * if page is new, attempt to allocate the page, then zero-fill it.
735 */
736 if (ptmp == NULL &&
737 uao_find_swslot(aobj, current_offset / PAGE_SIZE) == 0) {
738
739 ptmp = uvm_pagealloc(uobj, current_offset, NULL);
740 if (ptmp) {
741 ptmp->flags &= ~(PG_BUSY|PG_FAKE); /* new page */
742 ptmp->pqflags |= PQ_AOBJ;
743 UVM_PAGE_OWN(ptmp, NULL);
744 uvm_pagezero(ptmp);
745 }
746 }
747
748 /* to be useful must get a non-busy, non-released page */
749 if (ptmp == NULL || (ptmp->flags & (PG_BUSY|PG_RELEASED)) != 0) {
750 if (lcv == centeridx || (flags & PGO_ALLPAGES) != 0)
751 done = FALSE; /* need to do a wait or I/O! */
752 continue;
753 }
754
755 /* useful page: busy/lock it and plug it in our result array */
756 ptmp->flags |= PG_BUSY; /* caller must un-busy this page */
757 UVM_PAGE_OWN(ptmp, "uao_get1");
758 pps[lcv] = ptmp;
759 gotpages++;
760
761 } /* "for" lcv loop */
762
763 /*
764 * step 1b: now we've either done everything needed or we to unlock
765 * and do some waiting or I/O.
766 */
767
768 UVMHIST_LOG(pdhist, "<- done (done=%d)", done, 0,0,0);
769
770 *npagesp = gotpages;
771 if (done)
772 return(VM_PAGER_OK); /* bingo! */
773 else
774 return(VM_PAGER_UNLOCK); /* EEK! Need to unlock and I/O */
775 }
776
777 /*
778 * step 2: get non-resident or busy pages.
779 * object is locked. data structures are unlocked.
780 */
781
782 for (lcv = 0, current_offset = offset ;
783 lcv < maxpages ;
784 lcv++, current_offset += PAGE_SIZE) {
785
786 /* skip over pages we've already gotten or don't want */
787 /* skip over pages we don't _have_ to get */
788 if (pps[lcv] != NULL ||
789 (lcv != centeridx && (flags & PGO_ALLPAGES) == 0))
790 continue;
791
792 /*
793 * we have yet to locate the current page (pps[lcv]). we first
794 * look for a page that is already at the current offset. if we
795 * find a page, we check to see if it is busy or released. if that
796 * is the case, then we sleep on the page until it is no longer busy
797 * or released and repeat the lookup. if the page we found is
798 * neither busy nor released, then we busy it (so we own it) and
799 * plug it into pps[lcv]. this 'break's the following while loop
800 * and indicates we are ready to move on to the next page in the
801 * "lcv" loop above.
802 *
803 * if we exit the while loop with pps[lcv] still set to NULL, then
804 * it means that we allocated a new busy/fake/clean page ptmp in the
805 * object and we need to do I/O to fill in the data.
806 */
807
808 while (pps[lcv] == NULL) { /* top of "pps" while loop */
809
810 /* look for a resident page */
811 ptmp = uvm_pagelookup(uobj, current_offset);
812
813 /* not resident? allocate one now (if we can) */
814 if (ptmp == NULL) {
815
816 ptmp = uvm_pagealloc(uobj, current_offset, NULL); /* alloc */
817
818 /* out of RAM? */
819 if (ptmp == NULL) {
820 simple_unlock(&uobj->vmobjlock);
821 UVMHIST_LOG(pdhist, "sleeping, ptmp == NULL\n",0,0,0,0);
822 uvm_wait("uao_getpage");
823 simple_lock(&uobj->vmobjlock);
824 continue; /* goto top of pps while loop */
825 }
826
827 /* safe with PQ's unlocked: because we just alloc'd the page */
828 ptmp->pqflags |= PQ_AOBJ;
829
830 /*
831 * got new page ready for I/O. break pps while loop. pps[lcv] is
832 * still NULL.
833 */
834 break;
835 }
836
837 /* page is there, see if we need to wait on it */
838 if ((ptmp->flags & (PG_BUSY|PG_RELEASED)) != 0) {
839 ptmp->flags |= PG_WANTED;
840 UVMHIST_LOG(pdhist, "sleeping, ptmp->flags 0x%x\n",ptmp->flags,0,0,0);
841 UVM_UNLOCK_AND_WAIT(ptmp,&uobj->vmobjlock,0,"uao_get",0);
842 simple_lock(&uobj->vmobjlock);
843 continue; /* goto top of pps while loop */
844 }
845
846 /*
847 * if we get here then the page has become resident and unbusy
848 * between steps 1 and 2. we busy it now (so we own it) and set
849 * pps[lcv] (so that we exit the while loop).
850 */
851 ptmp->flags |= PG_BUSY; /* we own it, caller must un-busy */
852 UVM_PAGE_OWN(ptmp, "uao_get2");
853 pps[lcv] = ptmp;
854 }
855
856 /*
857 * if we own the valid page at the correct offset, pps[lcv] will
858 * point to it. nothing more to do except go to the next page.
859 */
860
861 if (pps[lcv])
862 continue; /* next lcv */
863
864 /*
865 * we have a "fake/busy/clean" page that we just allocated.
866 * do the needed "i/o", either reading from swap or zeroing.
867 */
868
869 swslot = uao_find_swslot(aobj, current_offset / PAGE_SIZE);
870
871 /*
872 * just zero the page if there's nothing in swap.
873 */
874 if (swslot == 0)
875 {
876 /*
877 * page hasn't existed before, just zero it.
878 */
879 uvm_pagezero(ptmp);
880 }
881 else
882 {
883 UVMHIST_LOG(pdhist, "pagein from swslot %d", swslot, 0,0,0);
884
885 /*
886 * page in the swapped-out page.
887 * unlock object for i/o, relock when done.
888 */
889 simple_unlock(&uobj->vmobjlock);
890 rv = uvm_swap_get(ptmp, swslot, PGO_SYNCIO);
891 simple_lock(&uobj->vmobjlock);
892
893 /*
894 * I/O done. check for errors.
895 */
896 if (rv != VM_PAGER_OK)
897 {
898 UVMHIST_LOG(pdhist, "<- done (error=%d)",rv,0,0,0);
899 if (ptmp->flags & PG_WANTED)
900 thread_wakeup(ptmp); /* object lock still held */
901 ptmp->flags &= ~(PG_WANTED|PG_BUSY);
902 UVM_PAGE_OWN(ptmp, NULL);
903 uvm_lock_pageq();
904 uvm_pagefree(ptmp);
905 uvm_unlock_pageq();
906 simple_unlock(&uobj->vmobjlock);
907 return rv;
908 }
909 }
910
911 /*
912 * we got the page! clear the fake flag (indicates valid data now
913 * in page) and plug into our result array. note that page is still
914 * busy.
915 *
916 * it is the callers job to:
917 * => check if the page is released
918 * => unbusy the page
919 * => activate the page
920 */
921
922 ptmp->flags &= ~PG_FAKE; /* data is valid ... */
923 pmap_clear_modify(PMAP_PGARG(ptmp)); /* ... and clean */
924 pps[lcv] = ptmp;
925
926 } /* lcv loop */
927
928 /*
929 * finally, unlock object and return.
930 */
931
932 simple_unlock(&uobj->vmobjlock);
933 UVMHIST_LOG(pdhist, "<- done (OK)",0,0,0,0);
934 return(VM_PAGER_OK);
935 }
936
937 /*
938 * uao_releasepg: handle released page in an aobj
939 *
940 * => "pg" is a PG_BUSY [caller owns it], PG_RELEASED page that we need
941 * to dispose of.
942 * => caller must handle PG_WANTED case
943 * => called with page's object locked, pageq's unlocked
944 * => returns TRUE if page's object is still alive, FALSE if we
945 * killed the page's object. if we return TRUE, then we
946 * return with the object locked.
947 * => if (nextpgp != NULL) => we return pageq.tqe_next here, and return
948 * with the page queues locked [for pagedaemon]
949 * => if (nextpgp == NULL) => we return with page queues unlocked [normal case]
950 * => we kill the aobj if it is not referenced and we are suppose to
951 * kill it ("KILLME").
952 */
953
954 static boolean_t uao_releasepg(pg, nextpgp)
955
956 struct vm_page *pg;
957 struct vm_page **nextpgp; /* OUT */
958
959 {
960 struct uvm_aobj *aobj = (struct uvm_aobj *) pg->uobject;
961 int slot;
962
963 #ifdef DIAGNOSTIC
964 if ((pg->flags & PG_RELEASED) == 0)
965 panic("uao_releasepg: page not released!");
966 #endif
967
968 /*
969 * dispose of the page [caller handles PG_WANTED]
970 */
971 pmap_page_protect(PMAP_PGARG(pg), VM_PROT_NONE);
972 uvm_lock_pageq();
973 if (nextpgp)
974 *nextpgp = pg->pageq.tqe_next; /* next page for daemon */
975 uvm_pagefree(pg);
976 if (!nextpgp)
977 uvm_unlock_pageq(); /* keep locked for daemon */
978
979 /*
980 * free the swap slot for this page, if any.
981 */
982 slot = uao_set_swslot(&aobj->u_obj, pg->offset / PAGE_SIZE, 0);
983 if (slot)
984 uvm_swap_free(slot, 1);
985
986 /*
987 * if we're not killing the object, we're done.
988 */
989 if ((aobj->u_flags & UAO_FLAG_KILLME) == 0)
990 return TRUE;
991
992 #ifdef DIAGNOSTIC
993 if (aobj->u_obj.uo_refs)
994 panic("uvm_km_releasepg: kill flag set on referenced object!");
995 #endif
996
997 /*
998 * if there are still pages in the object, we're done for now.
999 */
1000 if (aobj->u_obj.uo_npages != 0)
1001 return TRUE;
1002
1003 #ifdef DIAGNOSTIC
1004 if (aobj->u_obj.memq.tqh_first)
1005 panic("uvn_releasepg: pages in object with npages == 0");
1006 #endif
1007
1008 /*
1009 * finally, free the rest.
1010 */
1011 uao_free(aobj);
1012
1013 return FALSE;
1014 }
1015