git: 8370e9dfa188 - main - vm: Remove kernel stack swapping support, part 3

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Mon, 29 Jul 2024 01:49:55 UTC
The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=8370e9dfa188da4716c209a475e360d2b1a842f7

commit 8370e9dfa188da4716c209a475e360d2b1a842f7
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2024-07-29 01:39:49 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2024-07-29 01:39:49 +0000

    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
---
 .../opensolaris/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);
-}