From 8370e9dfa188da4716c209a475e360d2b1a842f7 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Mon, 29 Jul 2024 01:39:49 +0000 Subject: [PATCH] vm: Remove kernel stack swapping support, part 3 - Modify PHOLD() to no longer fault in the process. - Remove _PHOLD_LITE(), which is now the same as _PHOLD(), fix up consumers. - Remove faultin() and its callees. Tested by: pho Reviewed by: imp, kib Differential Revision: https://reviews.freebsd.org/D46114 --- .../uts/intel/dtrace/fasttrap_isa.c | 2 +- sys/fs/tmpfs/tmpfs_vfsops.c | 2 +- sys/kern/kern_procctl.c | 4 +- sys/sys/proc.h | 23 +-- sys/vm/vm_pageout.c | 2 +- sys/vm/vm_swapout.c | 140 +----------------- sys/vm/vm_swapout_dummy.c | 9 -- 7 files changed, 10 insertions(+), 172 deletions(-) diff --git a/sys/cddl/contrib/opensolaris/uts/intel/dtrace/fasttrap_isa.c b/sys/cddl/contrib/opensolaris/uts/intel/dtrace/fasttrap_isa.c index 43766f52bfe7..a65f6720bd0e 100644 --- a/sys/cddl/contrib/opensolaris/uts/intel/dtrace/fasttrap_isa.c +++ b/sys/cddl/contrib/opensolaris/uts/intel/dtrace/fasttrap_isa.c @@ -981,7 +981,7 @@ fasttrap_pid_probe(struct trapframe *tf) sx_sunlock(&proctree_lock); return (-1); } - _PHOLD_LITE(pp); + _PHOLD(pp); PROC_UNLOCK(pp); } sx_sunlock(&proctree_lock); diff --git a/sys/fs/tmpfs/tmpfs_vfsops.c b/sys/fs/tmpfs/tmpfs_vfsops.c index 32eb9c958df1..dd48a24dab2f 100644 --- a/sys/fs/tmpfs/tmpfs_vfsops.c +++ b/sys/fs/tmpfs/tmpfs_vfsops.c @@ -208,7 +208,7 @@ again: continue; } vm = vmspace_acquire_ref(p); - _PHOLD_LITE(p); + _PHOLD(p); PROC_UNLOCK(p); if (vm == NULL) { PRELE(p); diff --git a/sys/kern/kern_procctl.c b/sys/kern/kern_procctl.c index 2c8c638a2956..888feb94bb8d 100644 --- a/sys/kern/kern_procctl.c +++ b/sys/kern/kern_procctl.c @@ -337,7 +337,7 @@ reap_kill_sched(struct reap_kill_tracker_head *tracker, struct proc *p2) PROC_UNLOCK(p2); return; } - _PHOLD_LITE(p2); + _PHOLD(p2); PROC_UNLOCK(p2); t = malloc(sizeof(struct reap_kill_tracker), M_TEMP, M_WAITOK); t->parent = p2; @@ -463,7 +463,7 @@ reap_kill_subtree_once(struct thread *td, struct proc *p, struct proc *reaper, } else { PROC_LOCK(p2); if ((p2->p_flag2 & P2_WEXIT) == 0) { - _PHOLD_LITE(p2); + _PHOLD(p2); p2->p_flag2 |= P2_REAPKILLED; PROC_UNLOCK(p2); w->target = p2; diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 1b542d1374b4..c492cd10e712 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -704,7 +704,7 @@ struct proc { struct vnode *p_textvp; /* (b) Vnode of executable. */ struct vnode *p_textdvp; /* (b) Dir containing textvp. */ char *p_binname; /* (b) Binary hardlink name. */ - u_int p_lock; /* (c) Proclock (prevent swap) count. */ + u_int p_lock; /* (c) Prevent exit. */ struct sigiolst p_sigiolst; /* (c) List of sigio sources. */ int p_sigparent; /* (c) Signal to parent on exit. */ int p_sig; /* (n) For core dump/debugger XXX. */ @@ -986,18 +986,12 @@ extern pid_t pid_max; #define SESS_LOCK_ASSERT(s, type) mtx_assert(&(s)->s_mtx, (type)) /* - * Non-zero p_lock ensures that: - * - exit1() is not performed until p_lock reaches zero; - * - the process' threads stack are not swapped out if they are currently - * not (P_INMEM). + * A non-zero p_lock prevents the process from exiting; it will sleep in exit1() + * until the count reaches zero. * * PHOLD() asserts that the process (except the current process) is - * not exiting, increments p_lock and swaps threads stacks into memory, - * if needed. + * not exiting and increments p_lock. * _PHOLD() is same as PHOLD(), it takes the process locked. - * _PHOLD_LITE() also takes the process locked, but comparing with - * _PHOLD(), it only guarantees that exit1() is not executed, - * faultin() is not called. */ #define PHOLD(p) do { \ PROC_LOCK(p); \ @@ -1009,14 +1003,6 @@ extern pid_t pid_max; KASSERT(!((p)->p_flag & P_WEXIT) || (p) == curproc, \ ("PHOLD of exiting process %p", p)); \ (p)->p_lock++; \ - if (((p)->p_flag & P_INMEM) == 0) \ - faultin((p)); \ -} while (0) -#define _PHOLD_LITE(p) do { \ - PROC_LOCK_ASSERT((p), MA_OWNED); \ - KASSERT(!((p)->p_flag & P_WEXIT) || (p) == curproc, \ - ("PHOLD of exiting process %p", p)); \ - (p)->p_lock++; \ } while (0) #define PROC_ASSERT_HELD(p) do { \ KASSERT((p)->p_lock > 0, ("process %p not held", p)); \ @@ -1174,7 +1160,6 @@ int cr_cansignal(struct ucred *cred, struct proc *proc, int signum); int enterpgrp(struct proc *p, pid_t pgid, struct pgrp *pgrp, struct session *sess); int enterthispgrp(struct proc *p, struct pgrp *pgrp); -void faultin(struct proc *p); int fork1(struct thread *, struct fork_req *); void fork_exit(void (*)(void *, struct trapframe *), void *, struct trapframe *); diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c index cdc97637bbef..e32d27f2300a 100644 --- a/sys/vm/vm_pageout.c +++ b/sys/vm/vm_pageout.c @@ -1980,7 +1980,7 @@ vm_pageout_oom(int shortage) PROC_UNLOCK(p); continue; } - _PHOLD_LITE(p); + _PHOLD(p); PROC_UNLOCK(p); sx_sunlock(&allproc_lock); if (!vm_map_trylock_read(&vm->vm_map)) { diff --git a/sys/vm/vm_swapout.c b/sys/vm/vm_swapout.c index b97f6904ab5a..1f3b3a8532f1 100644 --- a/sys/vm/vm_swapout.c +++ b/sys/vm/vm_swapout.c @@ -159,11 +159,6 @@ static struct mtx vm_daemon_mtx; /* Allow for use by vm_pageout before vm_daemon is initialized. */ MTX_SYSINIT(vm_daemon, &vm_daemon_mtx, "vm daemon", MTX_DEF); -static int swapped_cnt; -static int swap_inprogress; /* Pending swap-ins done outside swapper. */ -static int last_swapin; - -static void swapclear(struct proc *); static void vm_swapout_map_deactivate_pages(vm_map_t, long); static void vm_swapout_object_deactivate(pmap_t, vm_object_t, long); @@ -396,7 +391,7 @@ again: if ((p->p_flag & P_INMEM) == 0) limit = 0; /* XXX */ vm = vmspace_acquire_ref(p); - _PHOLD_LITE(p); + _PHOLD(p); PROC_UNLOCK(p); if (vm == NULL) { PRELE(p); @@ -460,136 +455,3 @@ again: } } } - -/* - * Bring the kernel stack for a specified thread back in. - */ -static void -vm_thread_swapin(struct thread *td, int oom_alloc) -{ - vm_page_t ma[KSTACK_MAX_PAGES]; - vm_offset_t kaddr; - vm_object_t obj; - int a, count, i, j, pages, rv __diagused; - - kaddr = td->td_kstack; - pages = td->td_kstack_pages; - obj = vm_thread_kstack_size_to_obj(pages); - while (vm_thread_stack_back(kaddr, ma, pages, oom_alloc, - td->td_kstack_domain) == ENOMEM) - ; - for (i = 0; i < pages;) { - vm_page_assert_xbusied(ma[i]); - if (vm_page_all_valid(ma[i])) { - i++; - continue; - } - vm_object_pip_add(obj, 1); - for (j = i + 1; j < pages; j++) - if (vm_page_all_valid(ma[j])) - break; - VM_OBJECT_WLOCK(obj); - rv = vm_pager_has_page(obj, ma[i]->pindex, NULL, &a); - VM_OBJECT_WUNLOCK(obj); - KASSERT(rv == 1, ("%s: missing page %p", __func__, ma[i])); - count = min(a + 1, j - i); - rv = vm_pager_get_pages(obj, ma + i, count, NULL, NULL); - KASSERT(rv == VM_PAGER_OK, ("%s: cannot get kstack for proc %d", - __func__, td->td_proc->p_pid)); - vm_object_pip_wakeup(obj); - i += count; - } - pmap_qenter(kaddr, ma, pages); - cpu_thread_swapin(td); -} - -void -faultin(struct proc *p) -{ - struct thread *td; - int oom_alloc; - - PROC_LOCK_ASSERT(p, MA_OWNED); - - /* - * If another process is swapping in this process, - * just wait until it finishes. - */ - if (p->p_flag & P_SWAPPINGIN) { - while (p->p_flag & P_SWAPPINGIN) - msleep(&p->p_flag, &p->p_mtx, PVM, "faultin", 0); - return; - } - - if ((p->p_flag & P_INMEM) == 0) { - oom_alloc = (p->p_flag & P_WKILLED) != 0 ? VM_ALLOC_SYSTEM : - VM_ALLOC_NORMAL; - - /* - * Don't let another thread swap process p out while we are - * busy swapping it in. - */ - ++p->p_lock; - p->p_flag |= P_SWAPPINGIN; - PROC_UNLOCK(p); - sx_xlock(&allproc_lock); - MPASS(swapped_cnt > 0); - swapped_cnt--; - if (curthread != &thread0) - swap_inprogress++; - sx_xunlock(&allproc_lock); - - /* - * We hold no lock here because the list of threads - * can not change while all threads in the process are - * swapped out. - */ - FOREACH_THREAD_IN_PROC(p, td) - vm_thread_swapin(td, oom_alloc); - - if (curthread != &thread0) { - sx_xlock(&allproc_lock); - MPASS(swap_inprogress > 0); - swap_inprogress--; - last_swapin = ticks; - sx_xunlock(&allproc_lock); - } - PROC_LOCK(p); - swapclear(p); - p->p_swtick = ticks; - - /* Allow other threads to swap p out now. */ - wakeup(&p->p_flag); - --p->p_lock; - } -} - -static void -swapclear(struct proc *p) -{ - struct thread *td; - - PROC_LOCK_ASSERT(p, MA_OWNED); - - FOREACH_THREAD_IN_PROC(p, td) { - thread_lock(td); - td->td_flags |= TDF_INMEM; - td->td_flags &= ~TDF_SWAPINREQ; - TD_CLR_SWAPPED(td); - if (TD_CAN_RUN(td)) { - if (setrunnable(td, 0)) { -#ifdef INVARIANTS - /* - * XXX: We just cleared TDI_SWAPPED - * above and set TDF_INMEM, so this - * should never happen. - */ - panic("not waking up swapper"); -#endif - } - } else - thread_unlock(td); - } - p->p_flag &= ~(P_SWAPPINGIN | P_SWAPPINGOUT); - p->p_flag |= P_INMEM; -} diff --git a/sys/vm/vm_swapout_dummy.c b/sys/vm/vm_swapout_dummy.c index 7697a86f9d0b..6fe15ad44f11 100644 --- a/sys/vm/vm_swapout_dummy.c +++ b/sys/vm/vm_swapout_dummy.c @@ -90,12 +90,3 @@ static int vm_swap_idle_enabled = 0; SYSCTL_INT(_vm, OID_AUTO, swap_idle_enabled, CTLFLAG_RD, &vm_swap_idle_enabled, 0, "Allow swapout on idle criteria"); - -void -faultin(struct proc *p) -{ - - PROC_LOCK_ASSERT(p, MA_OWNED); - if ((p->p_flag & P_INMEM) == 0) - panic("faultin: proc %p swapped out with NO_SWAPPING", p); -}