|
|
1.1 root 1: /*
2: * Mach Operating System
3: * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University.
4: * Copyright (c) 1993,1994 The University of Utah and
5: * the Computer Systems Laboratory (CSL).
6: * All rights reserved.
7: *
8: * Permission to use, copy, modify and distribute this software and its
9: * documentation is hereby granted, provided that both the copyright
10: * notice and this permission notice appear in all copies of the
11: * software, derivative works or modified versions, and any portions
12: * thereof, and that both notices appear in supporting documentation.
13: *
14: * CARNEGIE MELLON, THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF
15: * THIS SOFTWARE IN ITS "AS IS" CONDITION, AND DISCLAIM ANY LIABILITY
16: * OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF
17: * THIS SOFTWARE.
18: *
19: * Carnegie Mellon requests users of this software to return to
20: *
21: * Software Distribution Coordinator or [email protected]
22: * School of Computer Science
23: * Carnegie Mellon University
24: * Pittsburgh PA 15213-3890
25: *
26: * any improvements or extensions that they make and grant Carnegie Mellon
27: * the rights to redistribute these changes.
28: */
29: /*
30: * File: vm/vm_pageout.c
31: * Author: Avadis Tevanian, Jr., Michael Wayne Young
32: * Date: 1985
33: *
34: * The proverbial page-out daemon.
35: */
36:
37: #include <mach_pagemap.h>
38: #include <norma_vm.h>
39:
40: #include <mach/mach_types.h>
41: #include <mach/memory_object.h>
42: #include "memory_object_default.h"
43: #include "memory_object_user.h"
44: #include <mach/vm_param.h>
45: #include <mach/vm_statistics.h>
46: #include <kern/counters.h>
47: #include <kern/thread.h>
48: #include <vm/pmap.h>
49: #include <vm/vm_map.h>
50: #include <vm/vm_object.h>
51: #include <vm/vm_page.h>
52: #include <vm/vm_pageout.h>
53: #include <machine/vm_tuning.h>
54:
55:
56:
57: #ifndef VM_PAGEOUT_BURST_MAX
58: #define VM_PAGEOUT_BURST_MAX 10 /* number of pages */
59: #endif /* VM_PAGEOUT_BURST_MAX */
60:
61: #ifndef VM_PAGEOUT_BURST_MIN
62: #define VM_PAGEOUT_BURST_MIN 5 /* number of pages */
63: #endif /* VM_PAGEOUT_BURST_MIN */
64:
65: #ifndef VM_PAGEOUT_BURST_WAIT
66: #define VM_PAGEOUT_BURST_WAIT 10 /* milliseconds per page */
67: #endif /* VM_PAGEOUT_BURST_WAIT */
68:
69: #ifndef VM_PAGEOUT_EMPTY_WAIT
70: #define VM_PAGEOUT_EMPTY_WAIT 75 /* milliseconds */
71: #endif /* VM_PAGEOUT_EMPTY_WAIT */
72:
73: #ifndef VM_PAGEOUT_PAUSE_MAX
74: #define VM_PAGEOUT_PAUSE_MAX 10 /* number of pauses */
75: #endif /* VM_PAGEOUT_PAUSE_MAX */
76:
77: /*
78: * To obtain a reasonable LRU approximation, the inactive queue
79: * needs to be large enough to give pages on it a chance to be
80: * referenced a second time. This macro defines the fraction
81: * of active+inactive pages that should be inactive.
82: * The pageout daemon uses it to update vm_page_inactive_target.
83: *
84: * If vm_page_free_count falls below vm_page_free_target and
85: * vm_page_inactive_count is below vm_page_inactive_target,
86: * then the pageout daemon starts running.
87: */
88:
89: #ifndef VM_PAGE_INACTIVE_TARGET
90: #define VM_PAGE_INACTIVE_TARGET(avail) ((avail) * 2 / 3)
91: #endif /* VM_PAGE_INACTIVE_TARGET */
92:
93: /*
94: * Once the pageout daemon starts running, it keeps going
95: * until vm_page_free_count meets or exceeds vm_page_free_target.
96: */
97:
98: #ifndef VM_PAGE_FREE_TARGET
99: #define VM_PAGE_FREE_TARGET(free) (15 + (free) / 80)
100: #endif /* VM_PAGE_FREE_TARGET */
101:
102: /*
103: * The pageout daemon always starts running once vm_page_free_count
104: * falls below vm_page_free_min.
105: */
106:
107: #ifndef VM_PAGE_FREE_MIN
108: #define VM_PAGE_FREE_MIN(free) (10 + (free) / 100)
109: #endif /* VM_PAGE_FREE_MIN */
110:
111: /* When vm_page_external_count exceeds vm_page_external_limit,
112: * allocations of externally paged pages stops.
113: */
114:
115: #ifndef VM_PAGE_EXTERNAL_LIMIT
116: #define VM_PAGE_EXTERNAL_LIMIT(free) ((free) / 2)
117: #endif /* VM_PAGE_EXTERNAL_LIMIT */
118:
119: /* Attempt to keep the number of externally paged pages less
120: * than vm_pages_external_target.
121: */
122: #ifndef VM_PAGE_EXTERNAL_TARGET
123: #define VM_PAGE_EXTERNAL_TARGET(free) ((free) / 4)
124: #endif /* VM_PAGE_EXTERNAL_TARGET */
125:
126: /*
127: * When vm_page_free_count falls below vm_page_free_reserved,
128: * only vm-privileged threads can allocate pages. vm-privilege
129: * allows the pageout daemon and default pager (and any other
130: * associated threads needed for default pageout) to continue
131: * operation by dipping into the reserved pool of pages. */
132:
133: #ifndef VM_PAGE_FREE_RESERVED
134: #define VM_PAGE_FREE_RESERVED 50
135: #endif /* VM_PAGE_FREE_RESERVED */
136:
137: /*
138: * When vm_page_free_count falls below vm_pageout_reserved_internal,
139: * the pageout daemon no longer trusts external pagers to clean pages.
140: * External pagers are probably all wedged waiting for a free page.
141: * It forcibly double-pages dirty pages belonging to external objects,
142: * getting the pages to the default pager to clean.
143: */
144:
145: #ifndef VM_PAGEOUT_RESERVED_INTERNAL
146: #define VM_PAGEOUT_RESERVED_INTERNAL(reserve) ((reserve) - 25)
147: #endif /* VM_PAGEOUT_RESERVED_INTERNAL */
148:
149: /*
150: * When vm_page_free_count falls below vm_pageout_reserved_really,
151: * the pageout daemon stops work entirely to let the default pager
152: * catch up (assuming the default pager has pages to clean).
153: * Beyond this point, it is too dangerous to consume memory
154: * even for memory_object_data_write messages to the default pager.
155: */
156:
157: #ifndef VM_PAGEOUT_RESERVED_REALLY
158: #define VM_PAGEOUT_RESERVED_REALLY(reserve) ((reserve) - 40)
159: #endif /* VM_PAGEOUT_RESERVED_REALLY */
160:
161: extern void vm_pageout_continue();
162: extern void vm_pageout_scan_continue();
163:
164: unsigned int vm_pageout_reserved_internal = 0;
165: unsigned int vm_pageout_reserved_really = 0;
166:
167: unsigned int vm_page_external_target = 0;
168:
169: unsigned int vm_pageout_burst_max = 0;
170: unsigned int vm_pageout_burst_min = 0;
171: unsigned int vm_pageout_burst_wait = 0; /* milliseconds per page */
172: unsigned int vm_pageout_empty_wait = 0; /* milliseconds */
173: unsigned int vm_pageout_pause_count = 0;
174: unsigned int vm_pageout_pause_max = 0;
175:
176: /*
177: * These variables record the pageout daemon's actions:
178: * how many pages it looks at and what happens to those pages.
179: * No locking needed because only one thread modifies the variables.
180: */
181:
182: unsigned int vm_pageout_active = 0; /* debugging */
183: unsigned int vm_pageout_inactive = 0; /* debugging */
184: unsigned int vm_pageout_inactive_nolock = 0; /* debugging */
185: unsigned int vm_pageout_inactive_busy = 0; /* debugging */
186: unsigned int vm_pageout_inactive_absent = 0; /* debugging */
187: unsigned int vm_pageout_inactive_used = 0; /* debugging */
188: unsigned int vm_pageout_inactive_clean = 0; /* debugging */
189: unsigned int vm_pageout_inactive_dirty = 0; /* debugging */
190: unsigned int vm_pageout_inactive_double = 0; /* debugging */
191: unsigned int vm_pageout_inactive_cleaned_external = 0;
192:
193: #if NORMA_VM
194: /*
195: * Define them here, since they won't be defined by memory_object_user.h.
196: */
197: extern kern_return_t memory_object_data_initialize();
198: extern kern_return_t memory_object_data_write();
199: #endif /* NORMA_VM */
200:
201: /*
202: * Routine: vm_pageout_setup
203: * Purpose:
204: * Set up a page for pageout.
205: *
206: * Move or copy the page to a new object, as part
207: * of which it will be sent to its memory manager
208: * in a memory_object_data_write or memory_object_initialize
209: * message.
210: *
211: * The "paging_offset" argument specifies the offset
212: * of the page within its external memory object.
213: *
214: * The "new_object" and "new_offset" arguments
215: * indicate where the page should be moved.
216: *
217: * The "flush" argument specifies whether the page
218: * should be flushed from its object. If not, a
219: * copy of the page is moved to the new object.
220: *
221: * In/Out conditions:
222: * The page in question must not be on any pageout queues,
223: * and must be busy. The object to which it belongs
224: * must be unlocked, and the caller must hold a paging
225: * reference to it. The new_object must not be locked.
226: *
227: * If the page is flushed from its original object,
228: * this routine returns a pointer to a place-holder page,
229: * inserted at the same offset, to block out-of-order
230: * requests for the page. The place-holder page must
231: * be freed after the data_write or initialize message
232: * has been sent. If the page is copied,
233: * the holding page is VM_PAGE_NULL.
234: *
235: * The original page is put on a paging queue and marked
236: * not busy on exit.
237: */
238: vm_page_t
239: vm_pageout_setup(m, paging_offset, new_object, new_offset, flush)
240: register vm_page_t m;
241: vm_offset_t paging_offset;
242: register vm_object_t new_object;
243: vm_offset_t new_offset;
244: boolean_t flush;
245: {
246: register vm_object_t old_object = m->object;
247: register vm_page_t holding_page = 0; /*'=0'to quiet gcc warnings*/
248: register vm_page_t new_m;
249:
250: assert(m->busy && !m->absent && !m->fictitious);
251:
252: /*
253: * If we are not flushing the page, allocate a
254: * page in the object. If we cannot get the
255: * page, flush instead.
256: */
257: if (!flush) {
258: vm_object_lock(new_object);
259: new_m = vm_page_alloc(new_object, new_offset);
260: if (new_m == VM_PAGE_NULL)
261: flush = TRUE;
262: vm_object_unlock(new_object);
263: }
264:
265: if (flush) {
266: /*
267: * Create a place-holder page where the old one was,
268: * to prevent anyone from attempting to page in this
269: * page while we`re unlocked.
270: */
271: while ((holding_page = vm_page_grab_fictitious())
272: == VM_PAGE_NULL)
273: vm_page_more_fictitious();
274:
275: vm_object_lock(old_object);
276: vm_page_lock_queues();
277: vm_page_remove(m);
278: vm_page_unlock_queues();
279: PAGE_WAKEUP_DONE(m);
280:
281: vm_page_lock_queues();
282: vm_page_insert(holding_page, old_object, m->offset);
283: vm_page_unlock_queues();
284:
285: /*
286: * Record that this page has been written out
287: */
288: #if MACH_PAGEMAP
289: vm_external_state_set(old_object->existence_info,
290: paging_offset,
291: VM_EXTERNAL_STATE_EXISTS);
292: #endif /* MACH_PAGEMAP */
293:
294: vm_object_unlock(old_object);
295:
296: vm_object_lock(new_object);
297:
298: /*
299: * Move this page into the new object
300: */
301:
302: vm_page_lock_queues();
303: vm_page_insert(m, new_object, new_offset);
304: vm_page_unlock_queues();
305:
306: m->dirty = TRUE;
307: m->precious = FALSE;
308: m->page_lock = VM_PROT_NONE;
309: m->unlock_request = VM_PROT_NONE;
310: }
311: else {
312: /*
313: * Copy the data into the new page,
314: * and mark the new page as clean.
315: */
316: vm_page_copy(m, new_m);
317:
318: vm_object_lock(old_object);
319: m->dirty = FALSE;
320: pmap_clear_modify(m->phys_addr);
321:
322: /*
323: * Deactivate old page.
324: */
325: vm_page_lock_queues();
326: vm_page_deactivate(m);
327: vm_page_unlock_queues();
328:
329: PAGE_WAKEUP_DONE(m);
330:
331: /*
332: * Record that this page has been written out
333: */
334:
335: #if MACH_PAGEMAP
336: vm_external_state_set(old_object->existence_info,
337: paging_offset,
338: VM_EXTERNAL_STATE_EXISTS);
339: #endif /* MACH_PAGEMAP */
340:
341: vm_object_unlock(old_object);
342:
343: vm_object_lock(new_object);
344:
345: /*
346: * Use the new page below.
347: */
348: m = new_m;
349: m->dirty = TRUE;
350: assert(!m->precious);
351: PAGE_WAKEUP_DONE(m);
352: }
353:
354: /*
355: * Make the old page eligible for replacement again; if a
356: * user-supplied memory manager fails to release the page,
357: * it will be paged out again to the default memory manager.
358: *
359: * Note that pages written to the default memory manager
360: * must be wired down -- in return, it guarantees to free
361: * this page, rather than reusing it.
362: */
363:
364: vm_page_lock_queues();
365: vm_stat.pageouts++;
366: if (m->laundry) {
367: /*
368: * vm_pageout_scan is telling us to put this page
369: * at the front of the inactive queue, so it will
370: * be immediately paged out to the default pager.
371: */
372:
373: assert(!old_object->internal);
374: m->laundry = FALSE;
375:
376: queue_enter_first(&vm_page_queue_inactive, m,
377: vm_page_t, pageq);
378: m->inactive = TRUE;
379: vm_page_inactive_count++;
380: } else if (old_object->internal) {
381: m->laundry = TRUE;
382: vm_page_laundry_count++;
383:
384: vm_page_wire(m);
385: } else
386: vm_page_activate(m);
387: vm_page_unlock_queues();
388:
389: /*
390: * Since IPC operations may block, we drop locks now.
391: * [The placeholder page is busy, and we still have
392: * paging_in_progress incremented.]
393: */
394:
395: vm_object_unlock(new_object);
396:
397: /*
398: * Return the placeholder page to simplify cleanup.
399: */
400: return (flush ? holding_page : VM_PAGE_NULL);
401: }
402:
403: /*
404: * Routine: vm_pageout_page
405: * Purpose:
406: * Causes the specified page to be written back to
407: * the appropriate memory object.
408: *
409: * The "initial" argument specifies whether this
410: * data is an initialization only, and should use
411: * memory_object_data_initialize instead of
412: * memory_object_data_write.
413: *
414: * The "flush" argument specifies whether the page
415: * should be flushed from the object. If not, a
416: * copy of the data is sent to the memory object.
417: *
418: * In/out conditions:
419: * The page in question must not be on any pageout queues.
420: * The object to which it belongs must be locked.
421: * Implementation:
422: * Move this page to a completely new object, if flushing;
423: * copy to a new page in a new object, if not.
424: */
425: void
426: vm_pageout_page(m, initial, flush)
427: register vm_page_t m;
428: boolean_t initial;
429: boolean_t flush;
430: {
431: vm_map_copy_t copy;
432: register vm_object_t old_object;
433: register vm_object_t new_object;
434: register vm_page_t holding_page;
435: vm_offset_t paging_offset;
436: kern_return_t rc;
437: boolean_t precious_clean;
438:
439: assert(m->busy);
440:
441: /*
442: * Cleaning but not flushing a clean precious page is a
443: * no-op. Remember whether page is clean and precious now
444: * because vm_pageout_setup will mark it dirty and not precious.
445: *
446: * XXX Check if precious_clean && !flush can really happen.
447: */
448: precious_clean = (!m->dirty) && m->precious;
449: if (precious_clean && !flush) {
450: PAGE_WAKEUP_DONE(m);
451: return;
452: }
453:
454: /*
455: * Verify that we really want to clean this page.
456: */
457: if (m->absent || m->error || (!m->dirty && !m->precious)) {
458: VM_PAGE_FREE(m);
459: return;
460: }
461:
462: /*
463: * Create a paging reference to let us play with the object.
464: */
465: old_object = m->object;
466: paging_offset = m->offset + old_object->paging_offset;
467: vm_object_paging_begin(old_object);
468: vm_object_unlock(old_object);
469:
470: /*
471: * Allocate a new object into which we can put the page.
472: */
473: new_object = vm_object_allocate(PAGE_SIZE);
474:
475: /*
476: * Move the page into the new object.
477: */
478: holding_page = vm_pageout_setup(m,
479: paging_offset,
480: new_object,
481: 0, /* new offset */
482: flush); /* flush */
483:
484: rc = vm_map_copyin_object(new_object, 0, PAGE_SIZE, ©);
485: assert(rc == KERN_SUCCESS);
486:
487: if (initial || old_object->use_old_pageout) {
488: rc = (*(initial ? memory_object_data_initialize
489: : memory_object_data_write))
490: (old_object->pager,
491: old_object->pager_request,
492: paging_offset, (pointer_t) copy, PAGE_SIZE);
493: }
494: else {
495: rc = memory_object_data_return(
496: old_object->pager,
497: old_object->pager_request,
498: paging_offset, (pointer_t) copy, PAGE_SIZE,
499: !precious_clean, !flush);
500: }
501:
502: if (rc != KERN_SUCCESS)
503: vm_map_copy_discard(copy);
504:
505: /*
506: * Clean up.
507: */
508: vm_object_lock(old_object);
509: if (holding_page != VM_PAGE_NULL)
510: VM_PAGE_FREE(holding_page);
511: vm_object_paging_end(old_object);
512: }
513:
514: /*
515: * vm_pageout_scan does the dirty work for the pageout daemon.
516: * It returns with vm_page_queue_free_lock held and
517: * vm_page_free_wanted == 0.
518: */
519:
520: void vm_pageout_scan()
521: {
522: unsigned int burst_count;
523: unsigned int want_pages;
524:
525: /*
526: * We want to gradually dribble pages from the active queue
527: * to the inactive queue. If we let the inactive queue get
528: * very small, and then suddenly dump many pages into it,
529: * those pages won't get a sufficient chance to be referenced
530: * before we start taking them from the inactive queue.
531: *
532: * We must limit the rate at which we send pages to the pagers.
533: * data_write messages consume memory, for message buffers and
534: * for map-copy objects. If we get too far ahead of the pagers,
535: * we can potentially run out of memory.
536: *
537: * We can use the laundry count to limit directly the number
538: * of pages outstanding to the default pager. A similar
539: * strategy for external pagers doesn't work, because
540: * external pagers don't have to deallocate the pages sent them,
541: * and because we might have to send pages to external pagers
542: * even if they aren't processing writes. So we also
543: * use a burst count to limit writes to external pagers.
544: *
545: * When memory is very tight, we can't rely on external pagers to
546: * clean pages. They probably aren't running, because they
547: * aren't vm-privileged. If we kept sending dirty pages to them,
548: * we could exhaust the free list. However, we can't just ignore
549: * pages belonging to external objects, because there might be no
550: * pages belonging to internal objects. Hence, we get the page
551: * into an internal object and then immediately double-page it,
552: * sending it to the default pager.
553: *
554: * consider_zone_gc should be last, because the other operations
555: * might return memory to zones. When we pause we use
556: * vm_pageout_scan_continue as our continuation, so we will
557: * reenter vm_pageout_scan periodically and attempt to reclaim
558: * internal memory even if we never reach vm_page_free_target.
559: */
560:
561: Restart:
562: stack_collect();
563: net_kmsg_collect();
564: consider_lmm_collect();
565: consider_task_collect();
566: consider_thread_collect();
567: consider_zone_gc();
568:
569: for (burst_count = 0;;) {
570: register vm_page_t m;
571: register vm_object_t object;
572: unsigned int free_count;
573:
574: /*
575: * Recalculate vm_page_inactivate_target.
576: */
577:
578: vm_page_lock_queues();
579: vm_page_inactive_target =
580: VM_PAGE_INACTIVE_TARGET(vm_page_active_count +
581: vm_page_inactive_count);
582:
583: /*
584: * Move pages from active to inactive.
585: */
586:
587: while ((vm_page_inactive_count < vm_page_inactive_target) &&
588: !queue_empty(&vm_page_queue_active)) {
589: register vm_object_t obj;
590:
591: vm_pageout_active++;
592: m = (vm_page_t) queue_first(&vm_page_queue_active);
593: assert(m->active && !m->inactive);
594:
595: obj = m->object;
596: if (!vm_object_lock_try(obj)) {
597: /*
598: * Move page to end and continue.
599: */
600:
601: queue_remove(&vm_page_queue_active, m,
602: vm_page_t, pageq);
603: queue_enter(&vm_page_queue_active, m,
604: vm_page_t, pageq);
605: vm_page_unlock_queues();
606: vm_page_lock_queues();
607: continue;
608: }
609:
610: /*
611: * If the page is busy, then we pull it
612: * off the active queue and leave it alone.
613: */
614:
615: if (m->busy) {
616: vm_object_unlock(obj);
617: queue_remove(&vm_page_queue_active, m,
618: vm_page_t, pageq);
619: m->active = FALSE;
620: vm_page_active_count--;
621: continue;
622: }
623:
624: /*
625: * Deactivate the page while holding the object
626: * locked, so we know the page is still not busy.
627: * This should prevent races between pmap_enter
628: * and pmap_clear_reference. The page might be
629: * absent or fictitious, but vm_page_deactivate
630: * can handle that.
631: */
632:
633: vm_page_deactivate(m);
634: vm_object_unlock(obj);
635: }
636:
637: /*
638: * We are done if we have met our targets *and*
639: * nobody is still waiting for a page.
640: */
641:
642: simple_lock(&vm_page_queue_free_lock);
643: free_count = vm_page_free_count;
644: if ((free_count >= vm_page_free_target) &&
645: (vm_page_external_count <= vm_page_external_target) &&
646: (vm_page_free_wanted == 0)) {
647: vm_page_unlock_queues();
648: break;
649: }
650: want_pages = ((free_count < vm_page_free_target) ||
651: vm_page_free_wanted);
652: simple_unlock(&vm_page_queue_free_lock);
653:
654: /*
655: * Sometimes we have to pause:
656: * 1) No inactive pages - nothing to do.
657: * 2) Flow control - wait for pagers to catch up.
658: * 3) Extremely low memory - sending out dirty pages
659: * consumes memory. We don't take the risk of doing
660: * this if the default pager already has work to do.
661: */
662: pause:
663: if (queue_empty(&vm_page_queue_inactive) ||
664: (burst_count >= vm_pageout_burst_max) ||
665: (vm_page_laundry_count >= vm_pageout_burst_max) ||
666: ((free_count < vm_pageout_reserved_really) &&
667: (vm_page_laundry_count > 0))) {
668: unsigned int pages, msecs;
669:
670: /*
671: * vm_pageout_burst_wait is msecs/page.
672: * If there is nothing for us to do, we wait
673: * at least vm_pageout_empty_wait msecs.
674: */
675:
676: if (vm_page_laundry_count > burst_count)
677: pages = vm_page_laundry_count;
678: else
679: pages = burst_count;
680: msecs = pages * vm_pageout_burst_wait;
681:
682: if (queue_empty(&vm_page_queue_inactive) &&
683: (msecs < vm_pageout_empty_wait))
684: msecs = vm_pageout_empty_wait;
685: vm_page_unlock_queues();
686:
687: thread_will_wait_with_timeout(current_thread(), msecs);
688: counter(c_vm_pageout_scan_block++);
689: thread_block(vm_pageout_scan_continue);
690: #ifndef CONTINUATIONS
691: /*
692: * Unfortunately, we don't have call_continuation
693: * so we can't rely on tail-recursion.
694: */
695:
696: vm_pageout_scan_continue();
697: goto Restart;
698: #else /* CONTINUATIONS */
699: call_continuation(vm_pageout_scan_continue);
700: /*NOTREACHED*/
701: #endif /* CONTINUATIONS */
702: }
703:
704: vm_pageout_inactive++;
705:
706: /* Find a page we are interested in paging out. If we
707: need pages, then we'll page anything out; otherwise
708: we only page out external pages. */
709: m = (vm_page_t) queue_first (&vm_page_queue_inactive);
710: while (1)
711: {
712: assert (!m->active && m->inactive);
713: if (want_pages || m->external)
714: break;
715:
716: m = (vm_page_t) queue_next (m);
717: if (!m)
718: goto pause;
719: }
720:
721: object = m->object;
722:
723: /*
724: * Try to lock object; since we've got the
725: * page queues lock, we can only try for this one.
726: */
727:
728: if (!vm_object_lock_try(object)) {
729: /*
730: * Move page to end and continue.
731: */
732:
733: queue_remove(&vm_page_queue_inactive, m,
734: vm_page_t, pageq);
735: queue_enter(&vm_page_queue_inactive, m,
736: vm_page_t, pageq);
737: vm_page_unlock_queues();
738: vm_pageout_inactive_nolock++;
739: continue;
740: }
741:
742: /*
743: * Remove the page from the inactive list.
744: */
745:
746: queue_remove(&vm_page_queue_inactive, m, vm_page_t, pageq);
747: vm_page_inactive_count--;
748: m->inactive = FALSE;
749:
750: if (m->busy || !object->alive) {
751: /*
752: * Somebody is already playing with this page.
753: * Leave it off the pageout queues.
754: */
755:
756: vm_page_unlock_queues();
757: vm_object_unlock(object);
758: vm_pageout_inactive_busy++;
759: continue;
760: }
761:
762: /*
763: * If it's absent, we can reclaim the page.
764: */
765:
766: if (want_pages && m->absent) {
767: vm_pageout_inactive_absent++;
768: reclaim_page:
769: vm_page_free(m);
770: vm_page_unlock_queues();
771: vm_object_unlock(object);
772: continue;
773: }
774:
775: /*
776: * If it's being used, reactivate.
777: * (Fictitious pages are either busy or absent.)
778: */
779:
780: assert(!m->fictitious);
781: if (m->reference || pmap_is_referenced(m->phys_addr)) {
782: vm_object_unlock(object);
783: vm_page_activate(m);
784: vm_stat.reactivations++;
785: vm_page_unlock_queues();
786: vm_pageout_inactive_used++;
787: continue;
788: }
789:
790: /*
791: * Eliminate all mappings.
792: */
793:
794: m->busy = TRUE;
795: pmap_page_protect(m->phys_addr, VM_PROT_NONE);
796: if (!m->dirty)
797: m->dirty = pmap_is_modified(m->phys_addr);
798:
799: if (m->external) {
800: /* Figure out if we still care about this
801: page in the limit of externally managed pages.
802: Clean pages don't actually cause system hosage,
803: so it's ok to stop considering them as
804: "consumers" of memory. */
805: if (m->dirty && !m->extcounted) {
806: m->extcounted = TRUE;
807: vm_page_external_count++;
808: } else if (!m->dirty && m->extcounted) {
809: m->extcounted = FALSE;
810: vm_page_external_count--;
811: }
812: }
813:
814: /* If we don't actually need more memory, and the page
815: is not dirty, put it on the tail of the inactive queue
816: and move on to the next page. */
817: if (!want_pages && !m->dirty) {
818: queue_remove (&vm_page_queue_inactive, m,
819: vm_page_t, pageq);
820: queue_enter (&vm_page_queue_inactive, m,
821: vm_page_t, pageq);
822: vm_page_unlock_queues();
823: vm_pageout_inactive_cleaned_external++;
824: continue;
825: }
826:
827: /*
828: * If it's clean and not precious, we can free the page.
829: */
830:
831: if (!m->dirty && !m->precious) {
832: vm_pageout_inactive_clean++;
833: goto reclaim_page;
834: }
835:
836: /*
837: * If we are very low on memory, then we can't
838: * rely on an external pager to clean a dirty page,
839: * because external pagers are not vm-privileged.
840: *
841: * The laundry bit tells vm_pageout_setup to
842: * put the page back at the front of the inactive
843: * queue instead of activating the page. Hence,
844: * we will pick the page up again immediately and
845: * resend it to the default pager.
846: */
847:
848: assert(!m->laundry);
849: if ((free_count < vm_pageout_reserved_internal) &&
850: !object->internal) {
851: m->laundry = TRUE;
852: vm_pageout_inactive_double++;
853: }
854: vm_page_unlock_queues();
855:
856: /*
857: * If there is no memory object for the page, create
858: * one and hand it to the default pager.
859: * [First try to collapse, so we don't create
860: * one unnecessarily.]
861: */
862:
863: if (!object->pager_initialized)
864: vm_object_collapse(object);
865: if (!object->pager_initialized)
866: vm_object_pager_create(object);
867: if (!object->pager_initialized)
868: panic("vm_pageout_scan");
869:
870: vm_pageout_inactive_dirty++;
871: vm_pageout_page(m, FALSE, TRUE); /* flush it */
872: vm_object_unlock(object);
873: burst_count++;
874: }
875: }
876:
877: void vm_pageout_scan_continue()
878: {
879: /*
880: * We just paused to let the pagers catch up.
881: * If vm_page_laundry_count is still high,
882: * then we aren't waiting long enough.
883: * If we have paused some vm_pageout_pause_max times without
884: * adjusting vm_pageout_burst_wait, it might be too big,
885: * so we decrease it.
886: */
887:
888: vm_page_lock_queues();
889: if (vm_page_laundry_count > vm_pageout_burst_min) {
890: vm_pageout_burst_wait++;
891: vm_pageout_pause_count = 0;
892: } else if (++vm_pageout_pause_count > vm_pageout_pause_max) {
893: vm_pageout_burst_wait = (vm_pageout_burst_wait * 3) / 4;
894: if (vm_pageout_burst_wait < 1)
895: vm_pageout_burst_wait = 1;
896: vm_pageout_pause_count = 0;
897: }
898: vm_page_unlock_queues();
899:
900: #ifdef CONTINUATIONS
901: vm_pageout_continue();
902: /*NOTREACHED*/
903: #endif /* CONTINUATIONS */
904: }
905:
906: /*
907: * vm_pageout is the high level pageout daemon.
908: */
909:
910: void vm_pageout_continue()
911: {
912: /*
913: * The pageout daemon is never done, so loop forever.
914: * We should call vm_pageout_scan at least once each
915: * time we are woken, even if vm_page_free_wanted is
916: * zero, to check vm_page_free_target and
917: * vm_page_inactive_target.
918: */
919:
920: for (;;) {
921: vm_pageout_scan();
922: /* we hold vm_page_queue_free_lock now */
923: assert(vm_page_free_wanted == 0);
924:
925: assert_wait(&vm_page_free_wanted, FALSE);
926: simple_unlock(&vm_page_queue_free_lock);
927: counter(c_vm_pageout_block++);
928: thread_block(vm_pageout_continue);
929: }
930: }
931:
932: void vm_pageout()
933: {
934: int free_after_reserve;
935:
936: current_thread()->vm_privilege = TRUE;
937: stack_privilege(current_thread());
938:
939: /*
940: * Initialize some paging parameters.
941: */
942:
943: if (vm_pageout_burst_max == 0)
944: vm_pageout_burst_max = VM_PAGEOUT_BURST_MAX;
945:
946: if (vm_pageout_burst_min == 0)
947: vm_pageout_burst_min = VM_PAGEOUT_BURST_MIN;
948:
949: if (vm_pageout_burst_wait == 0)
950: vm_pageout_burst_wait = VM_PAGEOUT_BURST_WAIT;
951:
952: if (vm_pageout_empty_wait == 0)
953: vm_pageout_empty_wait = VM_PAGEOUT_EMPTY_WAIT;
954:
955: if (vm_page_free_reserved == 0)
956: vm_page_free_reserved = VM_PAGE_FREE_RESERVED;
957:
958: if (vm_pageout_pause_max == 0)
959: vm_pageout_pause_max = VM_PAGEOUT_PAUSE_MAX;
960:
961: if (vm_pageout_reserved_internal == 0)
962: vm_pageout_reserved_internal =
963: VM_PAGEOUT_RESERVED_INTERNAL(vm_page_free_reserved);
964:
965: if (vm_pageout_reserved_really == 0)
966: vm_pageout_reserved_really =
967: VM_PAGEOUT_RESERVED_REALLY(vm_page_free_reserved);
968:
969: free_after_reserve = vm_page_free_count - vm_page_free_reserved;
970:
971: if (vm_page_external_limit == 0)
972: vm_page_external_limit =
973: VM_PAGE_EXTERNAL_LIMIT (free_after_reserve);
974:
975: if (vm_page_external_target == 0)
976: vm_page_external_target =
977: VM_PAGE_EXTERNAL_TARGET (free_after_reserve);
978:
979: if (vm_page_free_min == 0)
980: vm_page_free_min = vm_page_free_reserved +
981: VM_PAGE_FREE_MIN(free_after_reserve);
982:
983: if (vm_page_free_target == 0)
984: vm_page_free_target = vm_page_free_reserved +
985: VM_PAGE_FREE_TARGET(free_after_reserve);
986:
987: if (vm_page_free_target < vm_page_free_min + 5)
988: vm_page_free_target = vm_page_free_min + 5;
989:
990: /*
991: * vm_pageout_scan will set vm_page_inactive_target.
992: */
993:
994: vm_pageout_continue();
995: /*NOTREACHED*/
996: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.