From owner-svn-src-stable-11@freebsd.org Thu Jan 18 12:06:03 2018 Return-Path: Delivered-To: svn-src-stable-11@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 0C45FE745DA; Thu, 18 Jan 2018 12:06:03 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id D7F6069041; Thu, 18 Jan 2018 12:06:02 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 28F9E1E49A; Thu, 18 Jan 2018 12:06:02 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w0IC62vk066572; Thu, 18 Jan 2018 12:06:02 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w0IC62W4066571; Thu, 18 Jan 2018 12:06:02 GMT (envelope-from kib@FreeBSD.org) Message-Id: <201801181206.w0IC62W4066571@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov Date: Thu, 18 Jan 2018 12:06:02 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r328122 - stable/11/sys/vm X-SVN-Group: stable-11 X-SVN-Commit-Author: kib X-SVN-Commit-Paths: stable/11/sys/vm X-SVN-Commit-Revision: 328122 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-11@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: SVN commit messages for only the 11-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 18 Jan 2018 12:06:03 -0000 Author: kib Date: Thu Jan 18 12:06:01 2018 New Revision: 328122 URL: https://svnweb.freebsd.org/changeset/base/328122 Log: MFC r327555: Restructure swapout tests after vm map locking was removed. Modified: stable/11/sys/vm/vm_swapout.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/vm/vm_swapout.c ============================================================================== --- stable/11/sys/vm/vm_swapout.c Thu Jan 18 12:04:45 2018 (r328121) +++ stable/11/sys/vm/vm_swapout.c Thu Jan 18 12:06:01 2018 (r328122) @@ -732,126 +732,73 @@ swapout_procs(int action) struct proc *p; struct thread *td; int slptime; - bool didswap; + bool didswap, doswap; + MPASS((action & (VM_SWAP_NORMAL | VM_SWAP_IDLE)) != 0); + didswap = false; -retry: sx_slock(&allproc_lock); FOREACH_PROC_IN_SYSTEM(p) { - PROC_LOCK(p); /* - * Watch out for a process in - * creation. It may have no - * address space or lock yet. + * Filter out not yet fully constructed processes. Do + * not swap out held processes. Avoid processes which + * are system, exiting, execing, traced, already swapped + * out or are in the process of being swapped in or out. */ - if (p->p_state == PRS_NEW) { + PROC_LOCK(p); + if (p->p_state != PRS_NORMAL || p->p_lock != 0 || (p->p_flag & + (P_SYSTEM | P_WEXIT | P_INEXEC | P_STOPPED_SINGLE | + P_TRACED | P_SWAPPINGOUT | P_SWAPPINGIN | P_INMEM)) != + P_INMEM) { PROC_UNLOCK(p); continue; } + /* - * An aio daemon switches its - * address space while running. - * Perform a quick check whether - * a process has P_SYSTEM. - * Filter out exiting processes. + * Further consideration of this process for swap out + * requires iterating over its threads. We release + * allproc_lock here so that process creation and + * destruction are not blocked while we iterate. + * + * To later reacquire allproc_lock and resume + * iteration over the allproc list, we will first have + * to release the lock on the process. We place a + * hold on the process so that it remains in the + * allproc list while it is unlocked. */ - if ((p->p_flag & (P_SYSTEM | P_WEXIT)) != 0) { - PROC_UNLOCK(p); - continue; - } _PHOLD_LITE(p); - PROC_UNLOCK(p); sx_sunlock(&allproc_lock); - PROC_LOCK(p); - if (p->p_lock != 1 || (p->p_flag & (P_STOPPED_SINGLE | - P_TRACED | P_SYSTEM)) != 0) - goto nextproc; - /* - * Only aiod changes vmspace. However, it will be - * skipped because of the if statement above checking - * for P_SYSTEM. + * Do not swapout a realtime process. + * Guarantee swap_idle_threshold1 time in memory. + * If the system is under memory stress, or if we are + * swapping idle processes >= swap_idle_threshold2, + * then swap the process out. */ - if ((p->p_flag & (P_INMEM | P_SWAPPINGOUT | P_SWAPPINGIN)) != - P_INMEM) - goto nextproc; - - switch (p->p_state) { - default: - /* - * Don't swap out processes in any sort - * of 'special' state. - */ - break; - - case PRS_NORMAL: - /* - * do not swapout a realtime process - * Check all the thread groups.. - */ - FOREACH_THREAD_IN_PROC(p, td) { - thread_lock(td); - if (PRI_IS_REALTIME(td->td_pri_class)) { - thread_unlock(td); - goto nextproc; - } - slptime = (ticks - td->td_slptick) / hz; - /* - * Guarantee swap_idle_threshold1 - * time in memory. - */ - if (slptime < swap_idle_threshold1) { - thread_unlock(td); - goto nextproc; - } - - /* - * Do not swapout a process if it is - * waiting on a critical event of some - * kind or there is a thread whose - * pageable memory may be accessed. - * - * This could be refined to support - * swapping out a thread. - */ - if (!thread_safetoswapout(td)) { - thread_unlock(td); - goto nextproc; - } - /* - * If the system is under memory stress, - * or if we are swapping - * idle processes >= swap_idle_threshold2, - * then swap the process out. - */ - if ((action & VM_SWAP_NORMAL) == 0 && - ((action & VM_SWAP_IDLE) == 0 || - slptime < swap_idle_threshold2)) { - thread_unlock(td); - goto nextproc; - } - - thread_unlock(td); - } - - /* - * If the pageout daemon didn't free enough pages, - * or if this process is idle and the system is - * configured to swap proactively, swap it out. - */ - _PRELE(p); - if (swapout(p) == 0) - didswap = true; - PROC_UNLOCK(p); - goto retry; + doswap = true; + FOREACH_THREAD_IN_PROC(p, td) { + thread_lock(td); + slptime = (ticks - td->td_slptick) / hz; + if (PRI_IS_REALTIME(td->td_pri_class) || + slptime < swap_idle_threshold1 || + !thread_safetoswapout(td) || + ((action & VM_SWAP_NORMAL) == 0 && + slptime < swap_idle_threshold2)) + doswap = false; + thread_unlock(td); + if (!doswap) + break; } -nextproc: + if (doswap && swapout(p) == 0) + didswap = true; + PROC_UNLOCK(p); sx_slock(&allproc_lock); PRELE(p); } sx_sunlock(&allproc_lock); + /* * If we swapped something out, and another process needed memory, * then wakeup the sched process.