git: e8dc2ba29c62 - main - swapoff(2): add a SWAPOFF_FORCE flag

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Sat, 04 Dec 2021 22:21:08 UTC
The branch main has been updated by kib:

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

commit e8dc2ba29c62f3be2bdeb1a09321d73644a84475
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2021-11-29 16:28:19 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2021-12-04 22:20:58 +0000

    swapoff(2): add a SWAPOFF_FORCE flag
    
    The flag requests skipping the heuristic which tries to avoid leaving
    system with more allocated memory than available from RAM and remanining
    swap.
    
    Reviewed by:    markj
    Discussed with: alc
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D33165
---
 sys/vm/swap_pager.c | 12 ++++++------
 sys/vm/swap_pager.h |  2 ++
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c
index dc1df79f4fcd..99addb2c8e53 100644
--- a/sys/vm/swap_pager.c
+++ b/sys/vm/swap_pager.c
@@ -470,7 +470,7 @@ static void	swp_pager_free_empty_swblk(vm_object_t, struct swblk *sb);
 static int	swapongeom(struct vnode *);
 static int	swaponvp(struct thread *, struct vnode *, u_long);
 static int	swapoff_one(struct swdevt *sp, struct ucred *cred,
-		    bool ignore_check);
+		    u_int flags);
 
 /*
  * Swap bitmap functions
@@ -2511,7 +2511,7 @@ sys_swapoff(struct thread *td, struct swapoff_args *uap)
 		error = copyin(uap->name, &sa, sizeof(sa));
 		if (error != 0)
 			return (error);
-		if (sa.flags != 0)
+		if ((sa.flags & ~(SWAPOFF_FORCE)) != 0)
 			return (EINVAL);
 		break;
 	default:
@@ -2539,14 +2539,14 @@ sys_swapoff(struct thread *td, struct swapoff_args *uap)
 		error = EINVAL;
 		goto done;
 	}
-	error = swapoff_one(sp, td->td_ucred, false);
+	error = swapoff_one(sp, td->td_ucred, sa.flags);
 done:
 	sx_xunlock(&swdev_syscall_lock);
 	return (error);
 }
 
 static int
-swapoff_one(struct swdevt *sp, struct ucred *cred, bool ignore_check)
+swapoff_one(struct swdevt *sp, struct ucred *cred, u_int flags)
 {
 	u_long nblks;
 #ifdef MAC
@@ -2576,7 +2576,7 @@ swapoff_one(struct swdevt *sp, struct ucred *cred, bool ignore_check)
 	 * means that we can lose swap data when filesystems go away,
 	 * which is arguably worse.
 	 */
-	if (!ignore_check &&
+	if ((flags & SWAPOFF_FORCE) == 0 &&
 	    vm_free_count() + swap_pager_avail < nblks + nswap_lowat)
 		return (ENOMEM);
 
@@ -2627,7 +2627,7 @@ swapoff_all(void)
 			devname = devtoname(sp->sw_vp->v_rdev);
 		else
 			devname = "[file]";
-		error = swapoff_one(sp, thread0.td_ucred, true);
+		error = swapoff_one(sp, thread0.td_ucred, SWAPOFF_FORCE);
 		if (error != 0) {
 			printf("Cannot remove swap device %s (error=%d), "
 			    "skipping.\n", devname, error);
diff --git a/sys/vm/swap_pager.h b/sys/vm/swap_pager.h
index 469de3e8eaf4..59322d49cbc9 100644
--- a/sys/vm/swap_pager.h
+++ b/sys/vm/swap_pager.h
@@ -77,6 +77,8 @@ struct swapoff_new_args {
 	uintptr_t pad1[8];
 };
 
+#define	SWAPOFF_FORCE	0x00000001
+
 #ifdef _KERNEL
 
 extern int swap_pager_avail;