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 172207 2007-09-17 05:31:39Z 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 int swapout(struct proc *); 116static void swapclear(struct proc *); |
117#endif 118 119 120static volatile int proc0_rescan; 121 122 123/* 124 * MPSAFE --- 472 unchanged lines hidden (view full) --- 597 598void 599faultin(p) 600 struct proc *p; 601{ 602#ifdef NO_SWAPPING 603 604 PROC_LOCK_ASSERT(p, MA_OWNED); |
605 if ((p->p_flag & P_INMEM) == 0) |
606 panic("faultin: proc swapped out with NO_SWAPPING!"); 607#else /* !NO_SWAPPING */ 608 struct thread *td; 609 610 PROC_LOCK_ASSERT(p, MA_OWNED); 611 /* 612 * If another process is swapping in this process, 613 * just wait until it finishes. 614 */ |
615 if (p->p_flag & P_SWAPPINGIN) { 616 while (p->p_flag & P_SWAPPINGIN) 617 msleep(&p->p_flag, &p->p_mtx, PVM, "faultin", 0); 618 return; 619 } 620 if ((p->p_flag & P_INMEM) == 0) { |
621 /* 622 * Don't let another thread swap process p out while we are 623 * busy swapping it in. 624 */ 625 ++p->p_lock; |
626 p->p_flag |= P_SWAPPINGIN; |
627 PROC_UNLOCK(p); 628 |
629 /* 630 * We hold no lock here because the list of threads 631 * can not change while all threads in the process are 632 * swapped out. 633 */ |
634 FOREACH_THREAD_IN_PROC(p, td) 635 vm_thread_swapin(td); |
636 PROC_LOCK(p); 637 PROC_SLOCK(p); |
638 swapclear(p); 639 p->p_swtime = 0; |
640 PROC_SUNLOCK(p); 641 |
642 wakeup(&p->p_flag); |
643 644 /* Allow other threads to swap p out now. */ 645 --p->p_lock; 646 } 647#endif /* NO_SWAPPING */ 648} 649 650/* --- 27 unchanged lines hidden (view full) --- 678 thread_unlock(&thread0); 679 goto loop; 680 } 681 682 pp = NULL; 683 ppri = INT_MIN; 684 sx_slock(&allproc_lock); 685 FOREACH_PROC_IN_SYSTEM(p) { |
686 PROC_LOCK(p); 687 if (p->p_flag & (P_SWAPPINGOUT | P_SWAPPINGIN | P_INMEM)) { 688 PROC_UNLOCK(p); |
689 continue; 690 } 691 PROC_SLOCK(p); 692 FOREACH_THREAD_IN_PROC(p, td) { 693 /* 694 * An otherwise runnable thread of a process 695 * swapped out has only the TDI_SWAPPED bit set. 696 * 697 */ 698 thread_lock(td); 699 if (td->td_inhibitors == TDI_SWAPPED) { 700 pri = p->p_swtime + td->td_slptime; |
701 if ((td->td_flags & TDF_SWAPINREQ) == 0) |
702 pri -= p->p_nice * 8; |
703 /* 704 * if this thread is higher priority 705 * and there is enough space, then select 706 * this process instead of the previous 707 * selection. 708 */ 709 if (pri > ppri) { 710 pp = p; 711 ppri = pri; 712 } 713 } 714 thread_unlock(td); 715 } 716 PROC_SUNLOCK(p); |
717 PROC_UNLOCK(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_flag & (P_INMEM | P_SWAPPINGOUT | P_SWAPPINGIN)) { |
742 PROC_UNLOCK(p); 743 thread_lock(&thread0); 744 proc0_rescan = 0; 745 thread_unlock(&thread0); 746 goto loop; 747 } 748 |
749 /* 750 * We would like to bring someone in. (only if there is space). 751 * [What checks the space? ] 752 */ 753 faultin(p); 754 PROC_UNLOCK(p); |
755 thread_lock(&thread0); 756 proc0_rescan = 0; 757 thread_unlock(&thread0); 758 goto loop; 759} 760 761void kick_proc0(void) 762{ --- 29 unchanged lines hidden (view full) --- 792 * it will be swapped out, if idle swapping is enabled. 793 */ 794static int swap_idle_threshold2 = 10; 795SYSCTL_INT(_vm, OID_AUTO, swap_idle_threshold2, CTLFLAG_RW, 796 &swap_idle_threshold2, 0, "Time before a process will be swapped out"); 797 798/* 799 * Swapout is driven by the pageout daemon. Very simple, we find eligible |
800 * procs and swap out their stacks. We try to always "swap" at least one |
801 * process in case we need the room for a swapin. 802 * If any procs have been sleeping/stopped for at least maxslp seconds, 803 * they are swapped. Else, we swap the longest-sleeping or stopped process, 804 * if any, otherwise the longest-resident process. 805 */ 806void 807swapout_procs(action) 808int action; --- 8 unchanged lines hidden (view full) --- 817 struct vmspace *vm; 818 int minslptime = 100000; 819 820 /* 821 * Watch out for a process in 822 * creation. It may have no 823 * address space or lock yet. 824 */ |
825 if (p->p_state == PRS_NEW) |
826 continue; |
827 /* 828 * An aio daemon switches its 829 * address space while running. 830 * Perform a quick check whether 831 * a process has P_SYSTEM. 832 */ 833 if ((p->p_flag & P_SYSTEM) != 0) 834 continue; |
835 /* 836 * Do not swapout a process that 837 * is waiting for VM data 838 * structures as there is a possible 839 * deadlock. Test this first as 840 * this may block. 841 * 842 * Lock the map until swapout --- 13 unchanged lines hidden (view full) --- 856 ) != 0) { 857 goto nextproc2; 858 } 859 /* 860 * only aiod changes vmspace, however it will be 861 * skipped because of the if statement above checking 862 * for P_SYSTEM 863 */ |
864 if ((p->p_flag & (P_INMEM|P_SWAPPINGOUT|P_SWAPPINGIN)) != P_INMEM) |
865 goto nextproc2; 866 867 switch (p->p_state) { 868 default: 869 /* Don't swap out processes in any sort 870 * of 'special' state. */ 871 break; 872 873 case PRS_NORMAL: 874 PROC_SLOCK(p); 875 /* 876 * do not swapout a realtime process 877 * Check all the thread groups.. 878 */ 879 FOREACH_THREAD_IN_PROC(p, td) { |
880 thread_lock(td); 881 if (PRI_IS_REALTIME(td->td_pri_class)) { 882 thread_unlock(td); |
883 goto nextproc; |
884 } |
885 886 /* 887 * Guarantee swap_idle_threshold1 888 * time in memory. 889 */ |
890 if (td->td_slptime < swap_idle_threshold1) { 891 thread_unlock(td); |
892 goto nextproc; |
893 } |
894 895 /* 896 * Do not swapout a process if it is 897 * waiting on a critical event of some 898 * kind or there is a thread whose 899 * pageable memory may be accessed. 900 * 901 * This could be refined to support 902 * swapping out a thread. 903 */ 904 if ((td->td_priority) < PSOCK || |
905 !thread_safetoswapout(td)) { 906 thread_unlock(td); |
907 goto nextproc; |
908 } |
909 /* 910 * If the system is under memory stress, 911 * or if we are swapping 912 * idle processes >= swap_idle_threshold2, 913 * then swap the process out. 914 */ 915 if (((action & VM_SWAP_NORMAL) == 0) && 916 (((action & VM_SWAP_IDLE) == 0) || |
917 (td->td_slptime < swap_idle_threshold2))) { 918 thread_unlock(td); |
919 goto nextproc; |
920 } |
921 922 if (minslptime > td->td_slptime) 923 minslptime = td->td_slptime; |
924 thread_unlock(td); |
925 } 926 927 /* 928 * If the pageout daemon didn't free enough pages, 929 * or if this process is idle and the system is 930 * configured to swap proactively, swap it out. 931 */ 932 if ((action & VM_SWAP_NORMAL) || 933 ((action & VM_SWAP_IDLE) && 934 (minslptime > swap_idle_threshold2))) { |
935 if (swapout(p) == 0) 936 didswap++; |
937 PROC_SUNLOCK(p); 938 PROC_UNLOCK(p); 939 vm_map_unlock(&vm->vm_map); 940 vmspace_free(vm); 941 sx_sunlock(&allproc_lock); 942 goto retry; 943 } 944nextproc: --- 11 unchanged lines hidden (view full) --- 956 * If we swapped something out, and another process needed memory, 957 * then wakeup the sched process. 958 */ 959 if (didswap) 960 wakeup(&proc0); 961} 962 963static void |
964swapclear(p) 965 struct proc *p; 966{ 967 struct thread *td; 968 969 PROC_LOCK_ASSERT(p, MA_OWNED); 970 PROC_SLOCK_ASSERT(p, MA_OWNED); 971 972 FOREACH_THREAD_IN_PROC(p, td) { 973 thread_lock(td); 974 td->td_flags |= TDF_INMEM; 975 td->td_flags &= ~TDF_SWAPINREQ; 976 TD_CLR_SWAPPED(td); 977 if (TD_CAN_RUN(td)) 978 setrunnable(td); 979 thread_unlock(td); 980 } 981 p->p_flag &= ~(P_SWAPPINGIN|P_SWAPPINGOUT); 982 p->p_flag |= P_INMEM; 983} 984 985static int |
986swapout(p) 987 struct proc *p; 988{ 989 struct thread *td; 990 991 PROC_LOCK_ASSERT(p, MA_OWNED); |
992 PROC_SLOCK_ASSERT(p, MA_OWNED | MA_NOTRECURSED); |
993#if defined(SWAP_DEBUG) 994 printf("swapping out %d\n", p->p_pid); 995#endif 996 997 /* 998 * The states of this process and its threads may have changed 999 * by now. Assuming that there is only one pageout daemon thread, 1000 * this process should still be in memory. 1001 */ |
1002 KASSERT((p->p_flag & (P_INMEM|P_SWAPPINGOUT|P_SWAPPINGIN)) == P_INMEM, |
1003 ("swapout: lost a swapout race?")); 1004 |
1005 /* |
1006 * remember the process resident count 1007 */ 1008 p->p_vmspace->vm_swrss = vmspace_resident_count(p->p_vmspace); |
1009 /* 1010 * Check and mark all threads before we proceed. 1011 */ 1012 p->p_flag &= ~P_INMEM; 1013 p->p_flag |= P_SWAPPINGOUT; |
1014 FOREACH_THREAD_IN_PROC(p, td) { 1015 thread_lock(td); |
1016 if (!thread_safetoswapout(td)) { 1017 thread_unlock(td); 1018 swapclear(p); 1019 return (EBUSY); 1020 } 1021 td->td_flags &= ~TDF_INMEM; |
1022 TD_SET_SWAPPED(td); 1023 thread_unlock(td); 1024 } |
1025 td = FIRST_THREAD_IN_PROC(p); 1026 ++td->td_ru.ru_nswap; |
1027 PROC_SUNLOCK(p); |
1028 PROC_UNLOCK(p); |
1029 |
1030 /* 1031 * This list is stable because all threads are now prevented from 1032 * running. The list is only modified in the context of a running 1033 * thread in this process. 1034 */ |
1035 FOREACH_THREAD_IN_PROC(p, td) 1036 vm_thread_swapout(td); 1037 1038 PROC_LOCK(p); |
1039 p->p_flag &= ~P_SWAPPINGOUT; |
1040 PROC_SLOCK(p); |
1041 p->p_swtime = 0; |
1042 return (0); |
1043} 1044#endif /* !NO_SWAPPING */ |