Deleted Added
sdiff udiff text old ( 170307 ) new ( 172207 )
full compact
1/*-
2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * The Mach Operating System project at Carnegie-Mellon University.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 43 unchanged lines hidden (view full) ---

52 * Carnegie Mellon University
53 * Pittsburgh PA 15213-3890
54 *
55 * any improvements or extensions that they make and grant Carnegie the
56 * rights to redistribute these changes.
57 */
58
59#include <sys/cdefs.h>
60__FBSDID("$FreeBSD: head/sys/vm/vm_glue.c 170307 2007-06-05 00:00:57Z jeff $");
61
62#include "opt_vm.h"
63#include "opt_kstack_pages.h"
64#include "opt_kstack_max_pages.h"
65
66#include <sys/param.h>
67#include <sys/systm.h>
68#include <sys/limits.h>

--- 38 unchanged lines hidden (view full) ---

107 * THIS MUST BE THE LAST INITIALIZATION ITEM!!!
108 *
109 * Note: run scheduling should be divorced from the vm system.
110 */
111static void scheduler(void *);
112SYSINIT(scheduler, SI_SUB_RUN_SCHEDULER, SI_ORDER_ANY, scheduler, NULL)
113
114#ifndef NO_SWAPPING
115static void swapout(struct proc *);
116#endif
117
118
119static volatile int proc0_rescan;
120
121
122/*
123 * MPSAFE

--- 472 unchanged lines hidden (view full) ---

596
597void
598faultin(p)
599 struct proc *p;
600{
601#ifdef NO_SWAPPING
602
603 PROC_LOCK_ASSERT(p, MA_OWNED);
604 if ((p->p_sflag & PS_INMEM) == 0)
605 panic("faultin: proc swapped out with NO_SWAPPING!");
606#else /* !NO_SWAPPING */
607 struct thread *td;
608
609 PROC_LOCK_ASSERT(p, MA_OWNED);
610 /*
611 * If another process is swapping in this process,
612 * just wait until it finishes.
613 */
614 if (p->p_sflag & PS_SWAPPINGIN)
615 msleep(&p->p_sflag, &p->p_mtx, PVM, "faultin", 0);
616 else if ((p->p_sflag & PS_INMEM) == 0) {
617 /*
618 * Don't let another thread swap process p out while we are
619 * busy swapping it in.
620 */
621 ++p->p_lock;
622 PROC_SLOCK(p);
623 p->p_sflag |= PS_SWAPPINGIN;
624 PROC_SUNLOCK(p);
625 PROC_UNLOCK(p);
626
627 FOREACH_THREAD_IN_PROC(p, td)
628 vm_thread_swapin(td);
629
630 PROC_LOCK(p);
631 PROC_SLOCK(p);
632 p->p_sflag &= ~PS_SWAPPINGIN;
633 p->p_sflag |= PS_INMEM;
634 FOREACH_THREAD_IN_PROC(p, td) {
635 thread_lock(td);
636 TD_CLR_SWAPPED(td);
637 if (TD_CAN_RUN(td))
638 setrunnable(td);
639 thread_unlock(td);
640 }
641 PROC_SUNLOCK(p);
642
643 wakeup(&p->p_sflag);
644
645 /* Allow other threads to swap p out now. */
646 --p->p_lock;
647 }
648#endif /* NO_SWAPPING */
649}
650
651/*

--- 27 unchanged lines hidden (view full) ---

679 thread_unlock(&thread0);
680 goto loop;
681 }
682
683 pp = NULL;
684 ppri = INT_MIN;
685 sx_slock(&allproc_lock);
686 FOREACH_PROC_IN_SYSTEM(p) {
687 if (p->p_sflag & (PS_INMEM | PS_SWAPPINGOUT | PS_SWAPPINGIN)) {
688 continue;
689 }
690 PROC_SLOCK(p);
691 FOREACH_THREAD_IN_PROC(p, td) {
692 /*
693 * An otherwise runnable thread of a process
694 * swapped out has only the TDI_SWAPPED bit set.
695 *
696 */
697 thread_lock(td);
698 if (td->td_inhibitors == TDI_SWAPPED) {
699 pri = p->p_swtime + td->td_slptime;
700 if ((p->p_sflag & PS_SWAPINREQ) == 0) {
701 pri -= p->p_nice * 8;
702 }
703
704 /*
705 * if this thread is higher priority
706 * and there is enough space, then select
707 * this process instead of the previous
708 * selection.
709 */
710 if (pri > ppri) {
711 pp = p;
712 ppri = pri;
713 }
714 }
715 thread_unlock(td);
716 }
717 PROC_SUNLOCK(p);
718 }
719 sx_sunlock(&allproc_lock);
720
721 /*
722 * Nothing to do, back to sleep.
723 */
724 if ((p = pp) == NULL) {
725 thread_lock(&thread0);

--- 7 unchanged lines hidden (view full) ---

733 }
734 PROC_LOCK(p);
735
736 /*
737 * Another process may be bringing or may have already
738 * brought this process in while we traverse all threads.
739 * Or, this process may even be being swapped out again.
740 */
741 if (p->p_sflag & (PS_INMEM | PS_SWAPPINGOUT | PS_SWAPPINGIN)) {
742 PROC_UNLOCK(p);
743 thread_lock(&thread0);
744 proc0_rescan = 0;
745 thread_unlock(&thread0);
746 goto loop;
747 }
748
749 PROC_SLOCK(p);
750 p->p_sflag &= ~PS_SWAPINREQ;
751 PROC_SUNLOCK(p);
752
753 /*
754 * We would like to bring someone in. (only if there is space).
755 * [What checks the space? ]
756 */
757 faultin(p);
758 PROC_UNLOCK(p);
759 PROC_SLOCK(p);
760 p->p_swtime = 0;
761 PROC_SUNLOCK(p);
762 thread_lock(&thread0);
763 proc0_rescan = 0;
764 thread_unlock(&thread0);
765 goto loop;
766}
767
768void kick_proc0(void)
769{

--- 29 unchanged lines hidden (view full) ---

799 * it will be swapped out, if idle swapping is enabled.
800 */
801static int swap_idle_threshold2 = 10;
802SYSCTL_INT(_vm, OID_AUTO, swap_idle_threshold2, CTLFLAG_RW,
803 &swap_idle_threshold2, 0, "Time before a process will be swapped out");
804
805/*
806 * Swapout is driven by the pageout daemon. Very simple, we find eligible
807 * procs and unwire their u-areas. We try to always "swap" at least one
808 * process in case we need the room for a swapin.
809 * If any procs have been sleeping/stopped for at least maxslp seconds,
810 * they are swapped. Else, we swap the longest-sleeping or stopped process,
811 * if any, otherwise the longest-resident process.
812 */
813void
814swapout_procs(action)
815int action;

--- 8 unchanged lines hidden (view full) ---

824 struct vmspace *vm;
825 int minslptime = 100000;
826
827 /*
828 * Watch out for a process in
829 * creation. It may have no
830 * address space or lock yet.
831 */
832 PROC_SLOCK(p);
833 if (p->p_state == PRS_NEW) {
834 PROC_SUNLOCK(p);
835 continue;
836 }
837 PROC_SUNLOCK(p);
838
839 /*
840 * An aio daemon switches its
841 * address space while running.
842 * Perform a quick check whether
843 * a process has P_SYSTEM.
844 */
845 if ((p->p_flag & P_SYSTEM) != 0)
846 continue;
847
848 /*
849 * Do not swapout a process that
850 * is waiting for VM data
851 * structures as there is a possible
852 * deadlock. Test this first as
853 * this may block.
854 *
855 * Lock the map until swapout

--- 13 unchanged lines hidden (view full) ---

869 ) != 0) {
870 goto nextproc2;
871 }
872 /*
873 * only aiod changes vmspace, however it will be
874 * skipped because of the if statement above checking
875 * for P_SYSTEM
876 */
877 if ((p->p_sflag & (PS_INMEM|PS_SWAPPINGOUT|PS_SWAPPINGIN)) != PS_INMEM)
878 goto nextproc2;
879
880 switch (p->p_state) {
881 default:
882 /* Don't swap out processes in any sort
883 * of 'special' state. */
884 break;
885
886 case PRS_NORMAL:
887 PROC_SLOCK(p);
888 /*
889 * do not swapout a realtime process
890 * Check all the thread groups..
891 */
892 FOREACH_THREAD_IN_PROC(p, td) {
893 if (PRI_IS_REALTIME(td->td_pri_class))
894 goto nextproc;
895
896 /*
897 * Guarantee swap_idle_threshold1
898 * time in memory.
899 */
900 if (td->td_slptime < swap_idle_threshold1)
901 goto nextproc;
902
903 /*
904 * Do not swapout a process if it is
905 * waiting on a critical event of some
906 * kind or there is a thread whose
907 * pageable memory may be accessed.
908 *
909 * This could be refined to support
910 * swapping out a thread.
911 */
912 if ((td->td_priority) < PSOCK ||
913 !thread_safetoswapout(td))
914 goto nextproc;
915 /*
916 * If the system is under memory stress,
917 * or if we are swapping
918 * idle processes >= swap_idle_threshold2,
919 * then swap the process out.
920 */
921 if (((action & VM_SWAP_NORMAL) == 0) &&
922 (((action & VM_SWAP_IDLE) == 0) ||
923 (td->td_slptime < swap_idle_threshold2)))
924 goto nextproc;
925
926 if (minslptime > td->td_slptime)
927 minslptime = td->td_slptime;
928 }
929
930 /*
931 * If the pageout daemon didn't free enough pages,
932 * or if this process is idle and the system is
933 * configured to swap proactively, swap it out.
934 */
935 if ((action & VM_SWAP_NORMAL) ||
936 ((action & VM_SWAP_IDLE) &&
937 (minslptime > swap_idle_threshold2))) {
938 swapout(p);
939 didswap++;
940 PROC_SUNLOCK(p);
941 PROC_UNLOCK(p);
942 vm_map_unlock(&vm->vm_map);
943 vmspace_free(vm);
944 sx_sunlock(&allproc_lock);
945 goto retry;
946 }
947nextproc:

--- 11 unchanged lines hidden (view full) ---

959 * If we swapped something out, and another process needed memory,
960 * then wakeup the sched process.
961 */
962 if (didswap)
963 wakeup(&proc0);
964}
965
966static void
967swapout(p)
968 struct proc *p;
969{
970 struct thread *td;
971
972 PROC_LOCK_ASSERT(p, MA_OWNED);
973 mtx_assert(&p->p_slock, MA_OWNED | MA_NOTRECURSED);
974#if defined(SWAP_DEBUG)
975 printf("swapping out %d\n", p->p_pid);
976#endif
977
978 /*
979 * The states of this process and its threads may have changed
980 * by now. Assuming that there is only one pageout daemon thread,
981 * this process should still be in memory.
982 */
983 KASSERT((p->p_sflag & (PS_INMEM|PS_SWAPPINGOUT|PS_SWAPPINGIN)) == PS_INMEM,
984 ("swapout: lost a swapout race?"));
985
986#if defined(INVARIANTS)
987 /*
988 * Make sure that all threads are safe to be swapped out.
989 *
990 * Alternatively, we could swap out only safe threads.
991 */
992 FOREACH_THREAD_IN_PROC(p, td) {
993 KASSERT(thread_safetoswapout(td),
994 ("swapout: there is a thread not safe for swapout"));
995 }
996#endif /* INVARIANTS */
997 td = FIRST_THREAD_IN_PROC(p);
998 ++td->td_ru.ru_nswap;
999 /*
1000 * remember the process resident count
1001 */
1002 p->p_vmspace->vm_swrss = vmspace_resident_count(p->p_vmspace);
1003
1004 p->p_sflag &= ~PS_INMEM;
1005 p->p_sflag |= PS_SWAPPINGOUT;
1006 PROC_UNLOCK(p);
1007 FOREACH_THREAD_IN_PROC(p, td) {
1008 thread_lock(td);
1009 TD_SET_SWAPPED(td);
1010 thread_unlock(td);
1011 }
1012 PROC_SUNLOCK(p);
1013
1014 FOREACH_THREAD_IN_PROC(p, td)
1015 vm_thread_swapout(td);
1016
1017 PROC_LOCK(p);
1018 PROC_SLOCK(p);
1019 p->p_sflag &= ~PS_SWAPPINGOUT;
1020 p->p_swtime = 0;
1021}
1022#endif /* !NO_SWAPPING */