Annotation of sys/uvm/uvm_aobj.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: uvm_aobj.c,v 1.34 2007/04/13 18:57:49 art Exp $ */
2: /* $NetBSD: uvm_aobj.c,v 1.39 2001/02/18 21:19:08 chs Exp $ */
3:
4: /*
5: * Copyright (c) 1998 Chuck Silvers, Charles D. Cranor and
6: * Washington University.
7: * All rights reserved.
8: *
9: * Redistribution and use in source and binary forms, with or without
10: * modification, are permitted provided that the following conditions
11: * are met:
12: * 1. Redistributions of source code must retain the above copyright
13: * notice, this list of conditions and the following disclaimer.
14: * 2. Redistributions in binary form must reproduce the above copyright
15: * notice, this list of conditions and the following disclaimer in the
16: * documentation and/or other materials provided with the distribution.
17: * 3. All advertising materials mentioning features or use of this software
18: * must display the following acknowledgement:
19: * This product includes software developed by Charles D. Cranor and
20: * Washington University.
21: * 4. The name of the author may not be used to endorse or promote products
22: * derived from this software without specific prior written permission.
23: *
24: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
25: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34: *
35: * from: Id: uvm_aobj.c,v 1.1.2.5 1998/02/06 05:14:38 chs Exp
36: */
37: /*
38: * uvm_aobj.c: anonymous memory uvm_object pager
39: *
40: * author: Chuck Silvers <chuq@chuq.com>
41: * started: Jan-1998
42: *
43: * - design mostly from Chuck Cranor
44: */
45:
46: #include <sys/param.h>
47: #include <sys/systm.h>
48: #include <sys/proc.h>
49: #include <sys/malloc.h>
50: #include <sys/kernel.h>
51: #include <sys/pool.h>
52: #include <sys/kernel.h>
53:
54: #include <uvm/uvm.h>
55:
56: /*
57: * an aobj manages anonymous-memory backed uvm_objects. in addition
58: * to keeping the list of resident pages, it also keeps a list of
59: * allocated swap blocks. depending on the size of the aobj this list
60: * of allocated swap blocks is either stored in an array (small objects)
61: * or in a hash table (large objects).
62: */
63:
64: /*
65: * local structures
66: */
67:
68: /*
69: * for hash tables, we break the address space of the aobj into blocks
70: * of UAO_SWHASH_CLUSTER_SIZE pages. we require the cluster size to
71: * be a power of two.
72: */
73:
74: #define UAO_SWHASH_CLUSTER_SHIFT 4
75: #define UAO_SWHASH_CLUSTER_SIZE (1 << UAO_SWHASH_CLUSTER_SHIFT)
76:
77: /* get the "tag" for this page index */
78: #define UAO_SWHASH_ELT_TAG(PAGEIDX) \
79: ((PAGEIDX) >> UAO_SWHASH_CLUSTER_SHIFT)
80:
81: /* given an ELT and a page index, find the swap slot */
82: #define UAO_SWHASH_ELT_PAGESLOT(ELT, PAGEIDX) \
83: ((ELT)->slots[(PAGEIDX) & (UAO_SWHASH_CLUSTER_SIZE - 1)])
84:
85: /* given an ELT, return its pageidx base */
86: #define UAO_SWHASH_ELT_PAGEIDX_BASE(ELT) \
87: ((ELT)->tag << UAO_SWHASH_CLUSTER_SHIFT)
88:
89: /*
90: * the swhash hash function
91: */
92: #define UAO_SWHASH_HASH(AOBJ, PAGEIDX) \
93: (&(AOBJ)->u_swhash[(((PAGEIDX) >> UAO_SWHASH_CLUSTER_SHIFT) \
94: & (AOBJ)->u_swhashmask)])
95:
96: /*
97: * the swhash threshold determines if we will use an array or a
98: * hash table to store the list of allocated swap blocks.
99: */
100:
101: #define UAO_SWHASH_THRESHOLD (UAO_SWHASH_CLUSTER_SIZE * 4)
102: #define UAO_USES_SWHASH(AOBJ) \
103: ((AOBJ)->u_pages > UAO_SWHASH_THRESHOLD) /* use hash? */
104:
105: /*
106: * the number of buckets in a swhash, with an upper bound
107: */
108: #define UAO_SWHASH_MAXBUCKETS 256
109: #define UAO_SWHASH_BUCKETS(AOBJ) \
110: (min((AOBJ)->u_pages >> UAO_SWHASH_CLUSTER_SHIFT, \
111: UAO_SWHASH_MAXBUCKETS))
112:
113:
114: /*
115: * uao_swhash_elt: when a hash table is being used, this structure defines
116: * the format of an entry in the bucket list.
117: */
118:
119: struct uao_swhash_elt {
120: LIST_ENTRY(uao_swhash_elt) list; /* the hash list */
121: voff_t tag; /* our 'tag' */
122: int count; /* our number of active slots */
123: int slots[UAO_SWHASH_CLUSTER_SIZE]; /* the slots */
124: };
125:
126: /*
127: * uao_swhash: the swap hash table structure
128: */
129:
130: LIST_HEAD(uao_swhash, uao_swhash_elt);
131:
132: /*
133: * uao_swhash_elt_pool: pool of uao_swhash_elt structures
134: */
135:
136: struct pool uao_swhash_elt_pool;
137:
138: /*
139: * uvm_aobj: the actual anon-backed uvm_object
140: *
141: * => the uvm_object is at the top of the structure, this allows
142: * (struct uvm_device *) == (struct uvm_object *)
143: * => only one of u_swslots and u_swhash is used in any given aobj
144: */
145:
146: struct uvm_aobj {
147: struct uvm_object u_obj; /* has: lock, pgops, memq, #pages, #refs */
148: int u_pages; /* number of pages in entire object */
149: int u_flags; /* the flags (see uvm_aobj.h) */
150: int *u_swslots; /* array of offset->swapslot mappings */
151: /*
152: * hashtable of offset->swapslot mappings
153: * (u_swhash is an array of bucket heads)
154: */
155: struct uao_swhash *u_swhash;
156: u_long u_swhashmask; /* mask for hashtable */
157: LIST_ENTRY(uvm_aobj) u_list; /* global list of aobjs */
158: };
159:
160: /*
161: * uvm_aobj_pool: pool of uvm_aobj structures
162: */
163:
164: struct pool uvm_aobj_pool;
165:
166: /*
167: * local functions
168: */
169:
170: static struct uao_swhash_elt *uao_find_swhash_elt(struct uvm_aobj *,
171: int, boolean_t);
172: static int uao_find_swslot(struct uvm_aobj *, int);
173: static boolean_t uao_flush(struct uvm_object *,
174: voff_t, voff_t, int);
175: static void uao_free(struct uvm_aobj *);
176: static int uao_get(struct uvm_object *, voff_t,
177: vm_page_t *, int *, int,
178: vm_prot_t, int, int);
179: static boolean_t uao_releasepg(struct vm_page *,
180: struct vm_page **);
181: static boolean_t uao_pagein(struct uvm_aobj *, int, int);
182: static boolean_t uao_pagein_page(struct uvm_aobj *, int);
183:
184: /*
185: * aobj_pager
186: *
187: * note that some functions (e.g. put) are handled elsewhere
188: */
189:
190: struct uvm_pagerops aobj_pager = {
191: NULL, /* init */
192: uao_reference, /* reference */
193: uao_detach, /* detach */
194: NULL, /* fault */
195: uao_flush, /* flush */
196: uao_get, /* get */
197: NULL, /* put (done by pagedaemon) */
198: NULL, /* cluster */
199: NULL, /* mk_pcluster */
200: uao_releasepg /* releasepg */
201: };
202:
203: /*
204: * uao_list: global list of active aobjs, locked by uao_list_lock
205: */
206:
207: static LIST_HEAD(aobjlist, uvm_aobj) uao_list;
208: static simple_lock_data_t uao_list_lock;
209:
210:
211: /*
212: * functions
213: */
214:
215: /*
216: * hash table/array related functions
217: */
218:
219: /*
220: * uao_find_swhash_elt: find (or create) a hash table entry for a page
221: * offset.
222: *
223: * => the object should be locked by the caller
224: */
225:
226: static struct uao_swhash_elt *
227: uao_find_swhash_elt(aobj, pageidx, create)
228: struct uvm_aobj *aobj;
229: int pageidx;
230: boolean_t create;
231: {
232: struct uao_swhash *swhash;
233: struct uao_swhash_elt *elt;
234: voff_t page_tag;
235:
236: swhash = UAO_SWHASH_HASH(aobj, pageidx); /* first hash to get bucket */
237: page_tag = UAO_SWHASH_ELT_TAG(pageidx); /* tag to search for */
238:
239: /*
240: * now search the bucket for the requested tag
241: */
242: LIST_FOREACH(elt, swhash, list) {
243: if (elt->tag == page_tag)
244: return(elt);
245: }
246:
247: /* fail now if we are not allowed to create a new entry in the bucket */
248: if (!create)
249: return NULL;
250:
251:
252: /*
253: * allocate a new entry for the bucket and init/insert it in
254: */
255: elt = pool_get(&uao_swhash_elt_pool, PR_WAITOK);
256: LIST_INSERT_HEAD(swhash, elt, list);
257: elt->tag = page_tag;
258: elt->count = 0;
259: memset(elt->slots, 0, sizeof(elt->slots));
260:
261: return(elt);
262: }
263:
264: /*
265: * uao_find_swslot: find the swap slot number for an aobj/pageidx
266: *
267: * => object must be locked by caller
268: */
269: __inline static int
270: uao_find_swslot(aobj, pageidx)
271: struct uvm_aobj *aobj;
272: int pageidx;
273: {
274:
275: /*
276: * if noswap flag is set, then we never return a slot
277: */
278:
279: if (aobj->u_flags & UAO_FLAG_NOSWAP)
280: return(0);
281:
282: /*
283: * if hashing, look in hash table.
284: */
285:
286: if (UAO_USES_SWHASH(aobj)) {
287: struct uao_swhash_elt *elt =
288: uao_find_swhash_elt(aobj, pageidx, FALSE);
289:
290: if (elt)
291: return(UAO_SWHASH_ELT_PAGESLOT(elt, pageidx));
292: else
293: return(0);
294: }
295:
296: /*
297: * otherwise, look in the array
298: */
299: return(aobj->u_swslots[pageidx]);
300: }
301:
302: /*
303: * uao_set_swslot: set the swap slot for a page in an aobj.
304: *
305: * => setting a slot to zero frees the slot
306: * => object must be locked by caller
307: */
308: int
309: uao_set_swslot(uobj, pageidx, slot)
310: struct uvm_object *uobj;
311: int pageidx, slot;
312: {
313: struct uvm_aobj *aobj = (struct uvm_aobj *)uobj;
314: int oldslot;
315: UVMHIST_FUNC("uao_set_swslot"); UVMHIST_CALLED(pdhist);
316: UVMHIST_LOG(pdhist, "aobj %p pageidx %ld slot %ld",
317: aobj, pageidx, slot, 0);
318:
319: /*
320: * if noswap flag is set, then we can't set a slot
321: */
322:
323: if (aobj->u_flags & UAO_FLAG_NOSWAP) {
324:
325: if (slot == 0)
326: return(0); /* a clear is ok */
327:
328: /* but a set is not */
329: printf("uao_set_swslot: uobj = %p\n", uobj);
330: panic("uao_set_swslot: attempt to set a slot on a NOSWAP object");
331: }
332:
333: /*
334: * are we using a hash table? if so, add it in the hash.
335: */
336:
337: if (UAO_USES_SWHASH(aobj)) {
338:
339: /*
340: * Avoid allocating an entry just to free it again if
341: * the page had not swap slot in the first place, and
342: * we are freeing.
343: */
344:
345: struct uao_swhash_elt *elt =
346: uao_find_swhash_elt(aobj, pageidx, slot ? TRUE : FALSE);
347: if (elt == NULL) {
348: KASSERT(slot == 0);
349: return (0);
350: }
351:
352: oldslot = UAO_SWHASH_ELT_PAGESLOT(elt, pageidx);
353: UAO_SWHASH_ELT_PAGESLOT(elt, pageidx) = slot;
354:
355: /*
356: * now adjust the elt's reference counter and free it if we've
357: * dropped it to zero.
358: */
359:
360: /* an allocation? */
361: if (slot) {
362: if (oldslot == 0)
363: elt->count++;
364: } else { /* freeing slot ... */
365: if (oldslot) /* to be safe */
366: elt->count--;
367:
368: if (elt->count == 0) {
369: LIST_REMOVE(elt, list);
370: pool_put(&uao_swhash_elt_pool, elt);
371: }
372: }
373: } else {
374: /* we are using an array */
375: oldslot = aobj->u_swslots[pageidx];
376: aobj->u_swslots[pageidx] = slot;
377: }
378: return (oldslot);
379: }
380:
381: /*
382: * end of hash/array functions
383: */
384:
385: /*
386: * uao_free: free all resources held by an aobj, and then free the aobj
387: *
388: * => the aobj should be dead
389: */
390: static void
391: uao_free(aobj)
392: struct uvm_aobj *aobj;
393: {
394:
395: simple_unlock(&aobj->u_obj.vmobjlock);
396:
397: if (UAO_USES_SWHASH(aobj)) {
398: int i, hashbuckets = aobj->u_swhashmask + 1;
399:
400: /*
401: * free the swslots from each hash bucket,
402: * then the hash bucket, and finally the hash table itself.
403: */
404: for (i = 0; i < hashbuckets; i++) {
405: struct uao_swhash_elt *elt, *next;
406:
407: for (elt = LIST_FIRST(&aobj->u_swhash[i]);
408: elt != NULL;
409: elt = next) {
410: int j;
411:
412: for (j = 0; j < UAO_SWHASH_CLUSTER_SIZE; j++) {
413: int slot = elt->slots[j];
414:
415: if (slot == 0) {
416: continue;
417: }
418: uvm_swap_free(slot, 1);
419:
420: /*
421: * this page is no longer
422: * only in swap.
423: */
424: simple_lock(&uvm.swap_data_lock);
425: uvmexp.swpgonly--;
426: simple_unlock(&uvm.swap_data_lock);
427: }
428:
429: next = LIST_NEXT(elt, list);
430: pool_put(&uao_swhash_elt_pool, elt);
431: }
432: }
433: free(aobj->u_swhash, M_UVMAOBJ);
434: } else {
435: int i;
436:
437: /*
438: * free the array
439: */
440:
441: for (i = 0; i < aobj->u_pages; i++) {
442: int slot = aobj->u_swslots[i];
443:
444: if (slot) {
445: uvm_swap_free(slot, 1);
446:
447: /* this page is no longer only in swap. */
448: simple_lock(&uvm.swap_data_lock);
449: uvmexp.swpgonly--;
450: simple_unlock(&uvm.swap_data_lock);
451: }
452: }
453: free(aobj->u_swslots, M_UVMAOBJ);
454: }
455:
456: /*
457: * finally free the aobj itself
458: */
459: pool_put(&uvm_aobj_pool, aobj);
460: }
461:
462: /*
463: * pager functions
464: */
465:
466: /*
467: * uao_create: create an aobj of the given size and return its uvm_object.
468: *
469: * => for normal use, flags are always zero
470: * => for the kernel object, the flags are:
471: * UAO_FLAG_KERNOBJ - allocate the kernel object (can only happen once)
472: * UAO_FLAG_KERNSWAP - enable swapping of kernel object (" ")
473: */
474: struct uvm_object *
475: uao_create(size, flags)
476: vsize_t size;
477: int flags;
478: {
479: static struct uvm_aobj kernel_object_store; /* home of kernel_object */
480: static int kobj_alloced = 0; /* not allocated yet */
481: int pages = round_page(size) >> PAGE_SHIFT;
482: struct uvm_aobj *aobj;
483:
484: /*
485: * malloc a new aobj unless we are asked for the kernel object
486: */
487: if (flags & UAO_FLAG_KERNOBJ) { /* want kernel object? */
488: if (kobj_alloced)
489: panic("uao_create: kernel object already allocated");
490:
491: aobj = &kernel_object_store;
492: aobj->u_pages = pages;
493: aobj->u_flags = UAO_FLAG_NOSWAP; /* no swap to start */
494: /* we are special, we never die */
495: aobj->u_obj.uo_refs = UVM_OBJ_KERN;
496: kobj_alloced = UAO_FLAG_KERNOBJ;
497: } else if (flags & UAO_FLAG_KERNSWAP) {
498: aobj = &kernel_object_store;
499: if (kobj_alloced != UAO_FLAG_KERNOBJ)
500: panic("uao_create: asked to enable swap on kernel object");
501: kobj_alloced = UAO_FLAG_KERNSWAP;
502: } else { /* normal object */
503: aobj = pool_get(&uvm_aobj_pool, PR_WAITOK);
504: aobj->u_pages = pages;
505: aobj->u_flags = 0; /* normal object */
506: aobj->u_obj.uo_refs = 1; /* start with 1 reference */
507: }
508:
509: /*
510: * allocate hash/array if necessary
511: *
512: * note: in the KERNSWAP case no need to worry about locking since
513: * we are still booting we should be the only thread around.
514: */
515: if (flags == 0 || (flags & UAO_FLAG_KERNSWAP) != 0) {
516: int mflags = (flags & UAO_FLAG_KERNSWAP) != 0 ?
517: M_NOWAIT : M_WAITOK;
518:
519: /* allocate hash table or array depending on object size */
520: if (UAO_USES_SWHASH(aobj)) {
521: aobj->u_swhash = hashinit(UAO_SWHASH_BUCKETS(aobj),
522: M_UVMAOBJ, mflags, &aobj->u_swhashmask);
523: if (aobj->u_swhash == NULL)
524: panic("uao_create: hashinit swhash failed");
525: } else {
526: aobj->u_swslots = malloc(pages * sizeof(int),
527: M_UVMAOBJ, mflags);
528: if (aobj->u_swslots == NULL)
529: panic("uao_create: malloc swslots failed");
530: memset(aobj->u_swslots, 0, pages * sizeof(int));
531: }
532:
533: if (flags) {
534: aobj->u_flags &= ~UAO_FLAG_NOSWAP; /* clear noswap */
535: return(&aobj->u_obj);
536: /* done! */
537: }
538: }
539:
540: /*
541: * init aobj fields
542: */
543: simple_lock_init(&aobj->u_obj.vmobjlock);
544: aobj->u_obj.pgops = &aobj_pager;
545: TAILQ_INIT(&aobj->u_obj.memq);
546: aobj->u_obj.uo_npages = 0;
547:
548: /*
549: * now that aobj is ready, add it to the global list
550: */
551: simple_lock(&uao_list_lock);
552: LIST_INSERT_HEAD(&uao_list, aobj, u_list);
553: simple_unlock(&uao_list_lock);
554:
555: /*
556: * done!
557: */
558: return(&aobj->u_obj);
559: }
560:
561:
562:
563: /*
564: * uao_init: set up aobj pager subsystem
565: *
566: * => called at boot time from uvm_pager_init()
567: */
568: void
569: uao_init()
570: {
571: static int uao_initialized;
572:
573: if (uao_initialized)
574: return;
575: uao_initialized = TRUE;
576:
577: LIST_INIT(&uao_list);
578: simple_lock_init(&uao_list_lock);
579:
580: /*
581: * NOTE: Pages fror this pool must not come from a pageable
582: * kernel map!
583: */
584: pool_init(&uao_swhash_elt_pool, sizeof(struct uao_swhash_elt),
585: 0, 0, 0, "uaoeltpl", &pool_allocator_nointr);
586:
587: pool_init(&uvm_aobj_pool, sizeof(struct uvm_aobj), 0, 0, 0,
588: "aobjpl", &pool_allocator_nointr);
589: }
590:
591: /*
592: * uao_reference: add a ref to an aobj
593: *
594: * => aobj must be unlocked
595: * => just lock it and call the locked version
596: */
597: void
598: uao_reference(uobj)
599: struct uvm_object *uobj;
600: {
601: simple_lock(&uobj->vmobjlock);
602: uao_reference_locked(uobj);
603: simple_unlock(&uobj->vmobjlock);
604: }
605:
606: /*
607: * uao_reference_locked: add a ref to an aobj that is already locked
608: *
609: * => aobj must be locked
610: * this needs to be separate from the normal routine
611: * since sometimes we need to add a reference to an aobj when
612: * it's already locked.
613: */
614: void
615: uao_reference_locked(uobj)
616: struct uvm_object *uobj;
617: {
618: UVMHIST_FUNC("uao_reference"); UVMHIST_CALLED(maphist);
619:
620: /*
621: * kernel_object already has plenty of references, leave it alone.
622: */
623:
624: if (UVM_OBJ_IS_KERN_OBJECT(uobj))
625: return;
626:
627: uobj->uo_refs++; /* bump! */
628: UVMHIST_LOG(maphist, "<- done (uobj=%p, ref = %ld)",
629: uobj, uobj->uo_refs,0,0);
630: }
631:
632:
633: /*
634: * uao_detach: drop a reference to an aobj
635: *
636: * => aobj must be unlocked
637: * => just lock it and call the locked version
638: */
639: void
640: uao_detach(uobj)
641: struct uvm_object *uobj;
642: {
643: simple_lock(&uobj->vmobjlock);
644: uao_detach_locked(uobj);
645: }
646:
647:
648: /*
649: * uao_detach_locked: drop a reference to an aobj
650: *
651: * => aobj must be locked, and is unlocked (or freed) upon return.
652: * this needs to be separate from the normal routine
653: * since sometimes we need to detach from an aobj when
654: * it's already locked.
655: */
656: void
657: uao_detach_locked(uobj)
658: struct uvm_object *uobj;
659: {
660: struct uvm_aobj *aobj = (struct uvm_aobj *)uobj;
661: struct vm_page *pg, *next;
662: boolean_t busybody;
663: UVMHIST_FUNC("uao_detach"); UVMHIST_CALLED(maphist);
664:
665: /*
666: * detaching from kernel_object is a noop.
667: */
668: if (UVM_OBJ_IS_KERN_OBJECT(uobj)) {
669: simple_unlock(&uobj->vmobjlock);
670: return;
671: }
672:
673: UVMHIST_LOG(maphist," (uobj=%p) ref=%ld", uobj,uobj->uo_refs,0,0);
674: uobj->uo_refs--; /* drop ref! */
675: if (uobj->uo_refs) { /* still more refs? */
676: simple_unlock(&uobj->vmobjlock);
677: UVMHIST_LOG(maphist, "<- done (rc>0)", 0,0,0,0);
678: return;
679: }
680:
681: /*
682: * remove the aobj from the global list.
683: */
684: simple_lock(&uao_list_lock);
685: LIST_REMOVE(aobj, u_list);
686: simple_unlock(&uao_list_lock);
687:
688: /*
689: * free all the pages that aren't PG_BUSY,
690: * mark for release any that are.
691: */
692: busybody = FALSE;
693: for (pg = TAILQ_FIRST(&uobj->memq); pg != NULL; pg = next) {
694: next = TAILQ_NEXT(pg, listq);
695: if (pg->pg_flags & PG_BUSY) {
696: atomic_setbits_int(&pg->pg_flags, PG_RELEASED);
697: busybody = TRUE;
698: continue;
699: }
700:
701: /* zap the mappings, free the swap slot, free the page */
702: pmap_page_protect(pg, VM_PROT_NONE);
703: uao_dropswap(&aobj->u_obj, pg->offset >> PAGE_SHIFT);
704: uvm_lock_pageq();
705: uvm_pagefree(pg);
706: uvm_unlock_pageq();
707: }
708:
709: /*
710: * if we found any busy pages, we're done for now.
711: * mark the aobj for death, releasepg will finish up for us.
712: */
713: if (busybody) {
714: aobj->u_flags |= UAO_FLAG_KILLME;
715: simple_unlock(&aobj->u_obj.vmobjlock);
716: return;
717: }
718:
719: /*
720: * finally, free the rest.
721: */
722: uao_free(aobj);
723: }
724:
725: /*
726: * uao_flush: "flush" pages out of a uvm object
727: *
728: * => object should be locked by caller. we may _unlock_ the object
729: * if (and only if) we need to clean a page (PGO_CLEANIT).
730: * XXXJRT Currently, however, we don't. In the case of cleaning
731: * XXXJRT a page, we simply just deactivate it. Should probably
732: * XXXJRT handle this better, in the future (although "flushing"
733: * XXXJRT anonymous memory isn't terribly important).
734: * => if PGO_CLEANIT is not set, then we will neither unlock the object
735: * or block.
736: * => if PGO_ALLPAGE is set, then all pages in the object are valid targets
737: * for flushing.
738: * => NOTE: we rely on the fact that the object's memq is a TAILQ and
739: * that new pages are inserted on the tail end of the list. thus,
740: * we can make a complete pass through the object in one go by starting
741: * at the head and working towards the tail (new pages are put in
742: * front of us).
743: * => NOTE: we are allowed to lock the page queues, so the caller
744: * must not be holding the lock on them [e.g. pagedaemon had
745: * better not call us with the queues locked]
746: * => we return TRUE unless we encountered some sort of I/O error
747: * XXXJRT currently never happens, as we never directly initiate
748: * XXXJRT I/O
749: *
750: * comment on "cleaning" object and PG_BUSY pages:
751: * this routine is holding the lock on the object. the only time
752: * that is can run into a PG_BUSY page that it does not own is if
753: * some other process has started I/O on the page (e.g. either
754: * a pagein or a pageout). if the PG_BUSY page is being paged
755: * in, then it can not be dirty (!PG_CLEAN) because no one has
756: * had a change to modify it yet. if the PG_BUSY page is being
757: * paged out then it means that someone else has already started
758: * cleaning the page for us (how nice!). in this case, if we
759: * have syncio specified, then after we make our pass through the
760: * object we need to wait for the other PG_BUSY pages to clear
761: * off (i.e. we need to do an iosync). also note that once a
762: * page is PG_BUSY is must stary in its object until it is un-busyed.
763: * XXXJRT We never actually do this, as we are "flushing" anonymous
764: * XXXJRT memory, which doesn't have persistent backing store.
765: *
766: * note on page traversal:
767: * we can traverse the pages in an object either by going down the
768: * linked list in "uobj->memq", or we can go over the address range
769: * by page doing hash table lookups for each address. depending
770: * on how many pages are in the object it may be cheaper to do one
771: * or the other. we set "by_list" to true if we are using memq.
772: * if the cost of a hash lookup was equal to the cost of the list
773: * traversal we could compare the number of pages in the start->stop
774: * range to the total number of pages in the object. however, it
775: * seems that a hash table lookup is more expensive than the linked
776: * list traversal, so we multiply the number of pages in the
777: * start->stop range by a penalty which we define below.
778: */
779:
780: #define UAO_HASH_PENALTY 4 /* XXX: a guess */
781:
782: boolean_t
783: uao_flush(uobj, start, stop, flags)
784: struct uvm_object *uobj;
785: voff_t start, stop;
786: int flags;
787: {
788: struct uvm_aobj *aobj = (struct uvm_aobj *) uobj;
789: struct vm_page *pp, *ppnext;
790: boolean_t retval, by_list;
791: voff_t curoff;
792: UVMHIST_FUNC("uao_flush"); UVMHIST_CALLED(maphist);
793:
794: curoff = 0; /* XXX: shut up gcc */
795:
796: retval = TRUE; /* default to success */
797:
798: if (flags & PGO_ALLPAGES) {
799: start = 0;
800: stop = aobj->u_pages << PAGE_SHIFT;
801: by_list = TRUE; /* always go by the list */
802: } else {
803: start = trunc_page(start);
804: stop = round_page(stop);
805: if (stop > (aobj->u_pages << PAGE_SHIFT)) {
806: printf("uao_flush: strange, got an out of range "
807: "flush (fixed)\n");
808: stop = aobj->u_pages << PAGE_SHIFT;
809: }
810: by_list = (uobj->uo_npages <=
811: ((stop - start) >> PAGE_SHIFT) * UAO_HASH_PENALTY);
812: }
813:
814: UVMHIST_LOG(maphist,
815: " flush start=0x%lx, stop=0x%lx, by_list=%ld, flags=0x%lx",
816: (u_long)start, (u_long)stop, by_list, flags);
817:
818: /*
819: * Don't need to do any work here if we're not freeing
820: * or deactivating pages.
821: */
822: if ((flags & (PGO_DEACTIVATE|PGO_FREE)) == 0) {
823: UVMHIST_LOG(maphist,
824: "<- done (no work to do)",0,0,0,0);
825: return (retval);
826: }
827:
828: /*
829: * now do it. note: we must update ppnext in the body of loop or we
830: * will get stuck. we need to use ppnext because we may free "pp"
831: * before doing the next loop.
832: */
833:
834: if (by_list) {
835: pp = TAILQ_FIRST(&uobj->memq);
836: } else {
837: curoff = start;
838: pp = uvm_pagelookup(uobj, curoff);
839: }
840:
841: ppnext = NULL; /* XXX: shut up gcc */
842: uvm_lock_pageq(); /* page queues locked */
843:
844: /* locked: both page queues and uobj */
845: for ( ; (by_list && pp != NULL) ||
846: (!by_list && curoff < stop) ; pp = ppnext) {
847: if (by_list) {
848: ppnext = TAILQ_NEXT(pp, listq);
849:
850: /* range check */
851: if (pp->offset < start || pp->offset >= stop)
852: continue;
853: } else {
854: curoff += PAGE_SIZE;
855: if (curoff < stop)
856: ppnext = uvm_pagelookup(uobj, curoff);
857:
858: /* null check */
859: if (pp == NULL)
860: continue;
861: }
862:
863: switch (flags & (PGO_CLEANIT|PGO_FREE|PGO_DEACTIVATE)) {
864: /*
865: * XXX In these first 3 cases, we always just
866: * XXX deactivate the page. We may want to
867: * XXX handle the different cases more specifically
868: * XXX in the future.
869: */
870: case PGO_CLEANIT|PGO_FREE:
871: case PGO_CLEANIT|PGO_DEACTIVATE:
872: case PGO_DEACTIVATE:
873: deactivate_it:
874: /* skip the page if it's loaned or wired */
875: if (pp->loan_count != 0 ||
876: pp->wire_count != 0)
877: continue;
878:
879: #ifdef UBC
880: /* ...and deactivate the page. */
881: pmap_clear_reference(pp);
882: #else
883: /* zap all mappings for the page. */
884: pmap_page_protect(pp, VM_PROT_NONE);
885:
886: /* ...and deactivate the page. */
887: #endif
888: uvm_pagedeactivate(pp);
889:
890: continue;
891:
892: case PGO_FREE:
893: /*
894: * If there are multiple references to
895: * the object, just deactivate the page.
896: */
897: if (uobj->uo_refs > 1)
898: goto deactivate_it;
899:
900: /* XXX skip the page if it's loaned or wired */
901: if (pp->loan_count != 0 ||
902: pp->wire_count != 0)
903: continue;
904:
905: /*
906: * mark the page as released if its busy.
907: */
908: if (pp->pg_flags & PG_BUSY) {
909: atomic_setbits_int(&pp->pg_flags, PG_RELEASED);
910: continue;
911: }
912:
913: /* zap all mappings for the page. */
914: pmap_page_protect(pp, VM_PROT_NONE);
915:
916: uao_dropswap(uobj, pp->offset >> PAGE_SHIFT);
917: uvm_pagefree(pp);
918:
919: continue;
920:
921: default:
922: panic("uao_flush: weird flags");
923: }
924: }
925:
926: uvm_unlock_pageq();
927:
928: UVMHIST_LOG(maphist,
929: "<- done, rv=%ld",retval,0,0,0);
930: return (retval);
931: }
932:
933: /*
934: * uao_get: fetch me a page
935: *
936: * we have three cases:
937: * 1: page is resident -> just return the page.
938: * 2: page is zero-fill -> allocate a new page and zero it.
939: * 3: page is swapped out -> fetch the page from swap.
940: *
941: * cases 1 and 2 can be handled with PGO_LOCKED, case 3 cannot.
942: * so, if the "center" page hits case 3 (or any page, with PGO_ALLPAGES),
943: * then we will need to return VM_PAGER_UNLOCK.
944: *
945: * => prefer map unlocked (not required)
946: * => object must be locked! we will _unlock_ it before starting any I/O.
947: * => flags: PGO_ALLPAGES: get all of the pages
948: * PGO_LOCKED: fault data structures are locked
949: * => NOTE: offset is the offset of pps[0], _NOT_ pps[centeridx]
950: * => NOTE: caller must check for released pages!!
951: */
952: static int
953: uao_get(uobj, offset, pps, npagesp, centeridx, access_type, advice, flags)
954: struct uvm_object *uobj;
955: voff_t offset;
956: struct vm_page **pps;
957: int *npagesp;
958: int centeridx, advice, flags;
959: vm_prot_t access_type;
960: {
961: struct uvm_aobj *aobj = (struct uvm_aobj *)uobj;
962: voff_t current_offset;
963: vm_page_t ptmp;
964: int lcv, gotpages, maxpages, swslot, rv, pageidx;
965: boolean_t done;
966: UVMHIST_FUNC("uao_get"); UVMHIST_CALLED(pdhist);
967:
968: UVMHIST_LOG(pdhist, "aobj=%p offset=%ld, flags=%ld",
969: aobj, (u_long)offset, flags,0);
970:
971: /*
972: * get number of pages
973: */
974: maxpages = *npagesp;
975:
976: /*
977: * step 1: handled the case where fault data structures are locked.
978: */
979:
980: if (flags & PGO_LOCKED) {
981: /*
982: * step 1a: get pages that are already resident. only do
983: * this if the data structures are locked (i.e. the first
984: * time through).
985: */
986:
987: done = TRUE; /* be optimistic */
988: gotpages = 0; /* # of pages we got so far */
989:
990: for (lcv = 0, current_offset = offset ; lcv < maxpages ;
991: lcv++, current_offset += PAGE_SIZE) {
992: /* do we care about this page? if not, skip it */
993: if (pps[lcv] == PGO_DONTCARE)
994: continue;
995:
996: ptmp = uvm_pagelookup(uobj, current_offset);
997:
998: /*
999: * if page is new, attempt to allocate the page,
1000: * zero-fill'd.
1001: */
1002: if (ptmp == NULL && uao_find_swslot(aobj,
1003: current_offset >> PAGE_SHIFT) == 0) {
1004: ptmp = uvm_pagealloc(uobj, current_offset,
1005: NULL, UVM_PGA_ZERO);
1006: if (ptmp) {
1007: /* new page */
1008: atomic_clearbits_int(&ptmp->pg_flags,
1009: PG_BUSY|PG_FAKE);
1010: atomic_setbits_int(&ptmp->pg_flags,
1011: PQ_AOBJ);
1012: UVM_PAGE_OWN(ptmp, NULL);
1013: }
1014: }
1015:
1016: /*
1017: * to be useful must get a non-busy, non-released page
1018: */
1019: if (ptmp == NULL ||
1020: (ptmp->pg_flags & (PG_BUSY|PG_RELEASED)) != 0) {
1021: if (lcv == centeridx ||
1022: (flags & PGO_ALLPAGES) != 0)
1023: /* need to do a wait or I/O! */
1024: done = FALSE;
1025: continue;
1026: }
1027:
1028: /*
1029: * useful page: busy/lock it and plug it in our
1030: * result array
1031: */
1032: /* caller must un-busy this page */
1033: atomic_setbits_int(&ptmp->pg_flags, PG_BUSY);
1034: UVM_PAGE_OWN(ptmp, "uao_get1");
1035: pps[lcv] = ptmp;
1036: gotpages++;
1037:
1038: } /* "for" lcv loop */
1039:
1040: /*
1041: * step 1b: now we've either done everything needed or we
1042: * to unlock and do some waiting or I/O.
1043: */
1044:
1045: UVMHIST_LOG(pdhist, "<- done (done=%ld)", done, 0,0,0);
1046:
1047: *npagesp = gotpages;
1048: if (done)
1049: /* bingo! */
1050: return(VM_PAGER_OK);
1051: else
1052: /* EEK! Need to unlock and I/O */
1053: return(VM_PAGER_UNLOCK);
1054: }
1055:
1056: /*
1057: * step 2: get non-resident or busy pages.
1058: * object is locked. data structures are unlocked.
1059: */
1060:
1061: for (lcv = 0, current_offset = offset ; lcv < maxpages ;
1062: lcv++, current_offset += PAGE_SIZE) {
1063:
1064: /*
1065: * - skip over pages we've already gotten or don't want
1066: * - skip over pages we don't _have_ to get
1067: */
1068:
1069: if (pps[lcv] != NULL ||
1070: (lcv != centeridx && (flags & PGO_ALLPAGES) == 0))
1071: continue;
1072:
1073: pageidx = current_offset >> PAGE_SHIFT;
1074:
1075: /*
1076: * we have yet to locate the current page (pps[lcv]). we
1077: * first look for a page that is already at the current offset.
1078: * if we find a page, we check to see if it is busy or
1079: * released. if that is the case, then we sleep on the page
1080: * until it is no longer busy or released and repeat the lookup.
1081: * if the page we found is neither busy nor released, then we
1082: * busy it (so we own it) and plug it into pps[lcv]. this
1083: * 'break's the following while loop and indicates we are
1084: * ready to move on to the next page in the "lcv" loop above.
1085: *
1086: * if we exit the while loop with pps[lcv] still set to NULL,
1087: * then it means that we allocated a new busy/fake/clean page
1088: * ptmp in the object and we need to do I/O to fill in the data.
1089: */
1090:
1091: /* top of "pps" while loop */
1092: while (pps[lcv] == NULL) {
1093: /* look for a resident page */
1094: ptmp = uvm_pagelookup(uobj, current_offset);
1095:
1096: /* not resident? allocate one now (if we can) */
1097: if (ptmp == NULL) {
1098:
1099: ptmp = uvm_pagealloc(uobj, current_offset,
1100: NULL, 0);
1101:
1102: /* out of RAM? */
1103: if (ptmp == NULL) {
1104: simple_unlock(&uobj->vmobjlock);
1105: UVMHIST_LOG(pdhist,
1106: "sleeping, ptmp == NULL\n",0,0,0,0);
1107: uvm_wait("uao_getpage");
1108: simple_lock(&uobj->vmobjlock);
1109: /* goto top of pps while loop */
1110: continue;
1111: }
1112:
1113: /*
1114: * safe with PQ's unlocked: because we just
1115: * alloc'd the page
1116: */
1117: atomic_setbits_int(&ptmp->pg_flags, PQ_AOBJ);
1118:
1119: /*
1120: * got new page ready for I/O. break pps while
1121: * loop. pps[lcv] is still NULL.
1122: */
1123: break;
1124: }
1125:
1126: /* page is there, see if we need to wait on it */
1127: if ((ptmp->pg_flags & (PG_BUSY|PG_RELEASED)) != 0) {
1128: atomic_setbits_int(&ptmp->pg_flags, PG_WANTED);
1129: UVMHIST_LOG(pdhist,
1130: "sleeping, ptmp->flags 0x%lx\n",
1131: ptmp->pg_flags,0,0,0);
1132: UVM_UNLOCK_AND_WAIT(ptmp, &uobj->vmobjlock,
1133: FALSE, "uao_get", 0);
1134: simple_lock(&uobj->vmobjlock);
1135: continue; /* goto top of pps while loop */
1136: }
1137:
1138: /*
1139: * if we get here then the page has become resident and
1140: * unbusy between steps 1 and 2. we busy it now (so we
1141: * own it) and set pps[lcv] (so that we exit the while
1142: * loop).
1143: */
1144: /* we own it, caller must un-busy */
1145: atomic_setbits_int(&ptmp->pg_flags, PG_BUSY);
1146: UVM_PAGE_OWN(ptmp, "uao_get2");
1147: pps[lcv] = ptmp;
1148: }
1149:
1150: /*
1151: * if we own the valid page at the correct offset, pps[lcv] will
1152: * point to it. nothing more to do except go to the next page.
1153: */
1154: if (pps[lcv])
1155: continue; /* next lcv */
1156:
1157: /*
1158: * we have a "fake/busy/clean" page that we just allocated.
1159: * do the needed "i/o", either reading from swap or zeroing.
1160: */
1161: swslot = uao_find_swslot(aobj, pageidx);
1162:
1163: /*
1164: * just zero the page if there's nothing in swap.
1165: */
1166: if (swslot == 0)
1167: {
1168: /*
1169: * page hasn't existed before, just zero it.
1170: */
1171: uvm_pagezero(ptmp);
1172: } else {
1173: UVMHIST_LOG(pdhist, "pagein from swslot %ld",
1174: swslot, 0,0,0);
1175:
1176: /*
1177: * page in the swapped-out page.
1178: * unlock object for i/o, relock when done.
1179: */
1180: simple_unlock(&uobj->vmobjlock);
1181: rv = uvm_swap_get(ptmp, swslot, PGO_SYNCIO);
1182: simple_lock(&uobj->vmobjlock);
1183:
1184: /*
1185: * I/O done. check for errors.
1186: */
1187: if (rv != VM_PAGER_OK)
1188: {
1189: UVMHIST_LOG(pdhist, "<- done (error=%ld)",
1190: rv,0,0,0);
1191: if (ptmp->pg_flags & PG_WANTED)
1192: wakeup(ptmp);
1193:
1194: /*
1195: * remove the swap slot from the aobj
1196: * and mark the aobj as having no real slot.
1197: * don't free the swap slot, thus preventing
1198: * it from being used again.
1199: */
1200: swslot = uao_set_swslot(&aobj->u_obj, pageidx,
1201: SWSLOT_BAD);
1202: uvm_swap_markbad(swslot, 1);
1203:
1204: atomic_clearbits_int(&ptmp->pg_flags,
1205: PG_WANTED|PG_BUSY);
1206: UVM_PAGE_OWN(ptmp, NULL);
1207: uvm_lock_pageq();
1208: uvm_pagefree(ptmp);
1209: uvm_unlock_pageq();
1210:
1211: simple_unlock(&uobj->vmobjlock);
1212: return (rv);
1213: }
1214: }
1215:
1216: /*
1217: * we got the page! clear the fake flag (indicates valid
1218: * data now in page) and plug into our result array. note
1219: * that page is still busy.
1220: *
1221: * it is the callers job to:
1222: * => check if the page is released
1223: * => unbusy the page
1224: * => activate the page
1225: */
1226:
1227: /* data is valid ... */
1228: atomic_clearbits_int(&ptmp->pg_flags, PG_FAKE);
1229: pmap_clear_modify(ptmp); /* ... and clean */
1230: pps[lcv] = ptmp;
1231:
1232: } /* lcv loop */
1233:
1234: /*
1235: * finally, unlock object and return.
1236: */
1237:
1238: simple_unlock(&uobj->vmobjlock);
1239: UVMHIST_LOG(pdhist, "<- done (OK)",0,0,0,0);
1240: return(VM_PAGER_OK);
1241: }
1242:
1243: /*
1244: * uao_releasepg: handle released page in an aobj
1245: *
1246: * => "pg" is a PG_BUSY [caller owns it], PG_RELEASED page that we need
1247: * to dispose of.
1248: * => caller must handle PG_WANTED case
1249: * => called with page's object locked, pageq's unlocked
1250: * => returns TRUE if page's object is still alive, FALSE if we
1251: * killed the page's object. if we return TRUE, then we
1252: * return with the object locked.
1253: * => if (nextpgp != NULL) => we return the next page on the queue, and return
1254: * with the page queues locked [for pagedaemon]
1255: * => if (nextpgp == NULL) => we return with page queues unlocked [normal case]
1256: * => we kill the aobj if it is not referenced and we are suppose to
1257: * kill it ("KILLME").
1258: */
1259: static boolean_t
1260: uao_releasepg(pg, nextpgp)
1261: struct vm_page *pg;
1262: struct vm_page **nextpgp; /* OUT */
1263: {
1264: struct uvm_aobj *aobj = (struct uvm_aobj *) pg->uobject;
1265:
1266: KASSERT(pg->pg_flags & PG_RELEASED);
1267:
1268: /*
1269: * dispose of the page [caller handles PG_WANTED] and swap slot.
1270: */
1271: pmap_page_protect(pg, VM_PROT_NONE);
1272: uao_dropswap(&aobj->u_obj, pg->offset >> PAGE_SHIFT);
1273: uvm_lock_pageq();
1274: if (nextpgp)
1275: *nextpgp = TAILQ_NEXT(pg, pageq); /* next page for daemon */
1276: uvm_pagefree(pg);
1277: if (!nextpgp)
1278: uvm_unlock_pageq(); /* keep locked for daemon */
1279:
1280: /*
1281: * if we're not killing the object, we're done.
1282: */
1283: if ((aobj->u_flags & UAO_FLAG_KILLME) == 0)
1284: return TRUE;
1285: KASSERT(aobj->u_obj.uo_refs == 0);
1286:
1287: /*
1288: * if there are still pages in the object, we're done for now.
1289: */
1290: if (aobj->u_obj.uo_npages != 0)
1291: return TRUE;
1292:
1293: KASSERT(TAILQ_EMPTY(&aobj->u_obj.memq));
1294:
1295: /*
1296: * finally, free the rest.
1297: */
1298: uao_free(aobj);
1299:
1300: return FALSE;
1301: }
1302:
1303:
1304: /*
1305: * uao_dropswap: release any swap resources from this aobj page.
1306: *
1307: * => aobj must be locked or have a reference count of 0.
1308: */
1309:
1310: void
1311: uao_dropswap(uobj, pageidx)
1312: struct uvm_object *uobj;
1313: int pageidx;
1314: {
1315: int slot;
1316:
1317: slot = uao_set_swslot(uobj, pageidx, 0);
1318: if (slot) {
1319: uvm_swap_free(slot, 1);
1320: }
1321: }
1322:
1323:
1324: /*
1325: * page in every page in every aobj that is paged-out to a range of swslots.
1326: *
1327: * => nothing should be locked.
1328: * => returns TRUE if pagein was aborted due to lack of memory.
1329: */
1330: boolean_t
1331: uao_swap_off(startslot, endslot)
1332: int startslot, endslot;
1333: {
1334: struct uvm_aobj *aobj, *nextaobj;
1335:
1336: /*
1337: * walk the list of all aobjs.
1338: */
1339:
1340: restart:
1341: simple_lock(&uao_list_lock);
1342:
1343: for (aobj = LIST_FIRST(&uao_list);
1344: aobj != NULL;
1345: aobj = nextaobj) {
1346: boolean_t rv;
1347:
1348: /*
1349: * try to get the object lock,
1350: * start all over if we fail.
1351: * most of the time we'll get the aobj lock,
1352: * so this should be a rare case.
1353: */
1354: if (!simple_lock_try(&aobj->u_obj.vmobjlock)) {
1355: simple_unlock(&uao_list_lock);
1356: goto restart;
1357: }
1358:
1359: /*
1360: * add a ref to the aobj so it doesn't disappear
1361: * while we're working.
1362: */
1363: uao_reference_locked(&aobj->u_obj);
1364:
1365: /*
1366: * now it's safe to unlock the uao list.
1367: */
1368: simple_unlock(&uao_list_lock);
1369:
1370: /*
1371: * page in any pages in the swslot range.
1372: * if there's an error, abort and return the error.
1373: */
1374: rv = uao_pagein(aobj, startslot, endslot);
1375: if (rv) {
1376: uao_detach_locked(&aobj->u_obj);
1377: return rv;
1378: }
1379:
1380: /*
1381: * we're done with this aobj.
1382: * relock the list and drop our ref on the aobj.
1383: */
1384: simple_lock(&uao_list_lock);
1385: nextaobj = LIST_NEXT(aobj, u_list);
1386: uao_detach_locked(&aobj->u_obj);
1387: }
1388:
1389: /*
1390: * done with traversal, unlock the list
1391: */
1392: simple_unlock(&uao_list_lock);
1393: return FALSE;
1394: }
1395:
1396:
1397: /*
1398: * page in any pages from aobj in the given range.
1399: *
1400: * => aobj must be locked and is returned locked.
1401: * => returns TRUE if pagein was aborted due to lack of memory.
1402: */
1403: static boolean_t
1404: uao_pagein(aobj, startslot, endslot)
1405: struct uvm_aobj *aobj;
1406: int startslot, endslot;
1407: {
1408: boolean_t rv;
1409:
1410: if (UAO_USES_SWHASH(aobj)) {
1411: struct uao_swhash_elt *elt;
1412: int bucket;
1413:
1414: restart:
1415: for (bucket = aobj->u_swhashmask; bucket >= 0; bucket--) {
1416: for (elt = LIST_FIRST(&aobj->u_swhash[bucket]);
1417: elt != NULL;
1418: elt = LIST_NEXT(elt, list)) {
1419: int i;
1420:
1421: for (i = 0; i < UAO_SWHASH_CLUSTER_SIZE; i++) {
1422: int slot = elt->slots[i];
1423:
1424: /*
1425: * if the slot isn't in range, skip it.
1426: */
1427: if (slot < startslot ||
1428: slot >= endslot) {
1429: continue;
1430: }
1431:
1432: /*
1433: * process the page,
1434: * the start over on this object
1435: * since the swhash elt
1436: * may have been freed.
1437: */
1438: rv = uao_pagein_page(aobj,
1439: UAO_SWHASH_ELT_PAGEIDX_BASE(elt) + i);
1440: if (rv) {
1441: return rv;
1442: }
1443: goto restart;
1444: }
1445: }
1446: }
1447: } else {
1448: int i;
1449:
1450: for (i = 0; i < aobj->u_pages; i++) {
1451: int slot = aobj->u_swslots[i];
1452:
1453: /*
1454: * if the slot isn't in range, skip it
1455: */
1456: if (slot < startslot || slot >= endslot) {
1457: continue;
1458: }
1459:
1460: /*
1461: * process the page.
1462: */
1463: rv = uao_pagein_page(aobj, i);
1464: if (rv) {
1465: return rv;
1466: }
1467: }
1468: }
1469:
1470: return FALSE;
1471: }
1472:
1473: /*
1474: * page in a page from an aobj. used for swap_off.
1475: * returns TRUE if pagein was aborted due to lack of memory.
1476: *
1477: * => aobj must be locked and is returned locked.
1478: */
1479: static boolean_t
1480: uao_pagein_page(aobj, pageidx)
1481: struct uvm_aobj *aobj;
1482: int pageidx;
1483: {
1484: struct vm_page *pg;
1485: int rv, slot, npages;
1486:
1487: pg = NULL;
1488: npages = 1;
1489: /* locked: aobj */
1490: rv = uao_get(&aobj->u_obj, pageidx << PAGE_SHIFT,
1491: &pg, &npages, 0, VM_PROT_READ|VM_PROT_WRITE, 0, 0);
1492: /* unlocked: aobj */
1493:
1494: /*
1495: * relock and finish up.
1496: */
1497: simple_lock(&aobj->u_obj.vmobjlock);
1498:
1499: switch (rv) {
1500: case VM_PAGER_OK:
1501: break;
1502:
1503: case VM_PAGER_ERROR:
1504: case VM_PAGER_REFAULT:
1505: /*
1506: * nothing more to do on errors.
1507: * VM_PAGER_REFAULT can only mean that the anon was freed,
1508: * so again there's nothing to do.
1509: */
1510: return FALSE;
1511:
1512: }
1513: KASSERT((pg->pg_flags & PG_RELEASED) == 0);
1514:
1515: /*
1516: * ok, we've got the page now.
1517: * mark it as dirty, clear its swslot and un-busy it.
1518: */
1519: slot = uao_set_swslot(&aobj->u_obj, pageidx, 0);
1520: uvm_swap_free(slot, 1);
1521: atomic_clearbits_int(&pg->pg_flags, PG_BUSY|PG_CLEAN|PG_FAKE);
1522: UVM_PAGE_OWN(pg, NULL);
1523:
1524: /*
1525: * deactivate the page (to put it on a page queue).
1526: */
1527: pmap_clear_reference(pg);
1528: #ifndef UBC
1529: pmap_page_protect(pg, VM_PROT_NONE);
1530: #endif
1531: uvm_lock_pageq();
1532: uvm_pagedeactivate(pg);
1533: uvm_unlock_pageq();
1534:
1535: return FALSE;
1536: }
CVSweb