git: 686aa9287c6b - main - swap_pager: Handle large swap_pager_reserve() requests
Mark Johnston
markj at FreeBSD.org
Tue Sep 7 18:05:46 UTC 2021
The branch main has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=686aa9287c6b3658daa2ca0ef1917f2e70a6c07e
commit 686aa9287c6b3658daa2ca0ef1917f2e70a6c07e
Author: Mark Johnston <markj at FreeBSD.org>
AuthorDate: 2021-09-07 18:03:52 +0000
Commit: Mark Johnston <markj at FreeBSD.org>
CommitDate: 2021-09-07 18:04:50 +0000
swap_pager: Handle large swap_pager_reserve() requests
This interface is used solely by md(4) when the MD_RESERVE flag is
specified, as in `mdconfig -a -t swap -s 1G -o reserve`. It
pre-allocates swap blocks for the entire object.
The number of blocks to be reserved is specified as a vm_size_t, but
swp_pager_getswapspace() can allocate at most INT_MAX blocks. vm_size_t
also seems like the incorrect type to use here it refers only to the
size of the VM object, not the size of a mapping. So:
- change the type of "size" in swap_pager_reserve() to vm_pindex_t, and
- clamp the requested number of blocks for a single
swp_pager_getswapspace() call to INT_MAX.
Reported by: syzkaller
Reviewed by: dougm, alc, kib
MFC after: 2 weeks
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D31875
---
sys/vm/swap_pager.c | 8 +++++---
sys/vm/swap_pager.h | 2 +-
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c
index 63f0d22ed705..6d64ff883966 100644
--- a/sys/vm/swap_pager.c
+++ b/sys/vm/swap_pager.c
@@ -82,6 +82,7 @@ __FBSDID("$FreeBSD$");
#include <sys/disklabel.h>
#include <sys/eventhandler.h>
#include <sys/fcntl.h>
+#include <sys/limits.h>
#include <sys/lock.h>
#include <sys/kernel.h>
#include <sys/mount.h>
@@ -977,15 +978,16 @@ swap_pager_freespace(vm_object_t object, vm_pindex_t start, vm_size_t size)
* Returns 0 on success, -1 on failure.
*/
int
-swap_pager_reserve(vm_object_t object, vm_pindex_t start, vm_size_t size)
+swap_pager_reserve(vm_object_t object, vm_pindex_t start, vm_pindex_t size)
{
daddr_t addr, blk, n_free, s_free;
- int i, j, n;
+ vm_pindex_t i, j;
+ int n;
swp_pager_init_freerange(&s_free, &n_free);
VM_OBJECT_WLOCK(object);
for (i = 0; i < size; i += n) {
- n = size - i;
+ n = MIN(size - i, INT_MAX);
blk = swp_pager_getswapspace(&n);
if (blk == SWAPBLK_NONE) {
swp_pager_meta_free(object, start, i);
diff --git a/sys/vm/swap_pager.h b/sys/vm/swap_pager.h
index 20ff70acc3d8..6761d4f99ee4 100644
--- a/sys/vm/swap_pager.h
+++ b/sys/vm/swap_pager.h
@@ -78,7 +78,7 @@ void swap_pager_copy(vm_object_t, vm_object_t, vm_pindex_t, int);
vm_pindex_t swap_pager_find_least(vm_object_t object, vm_pindex_t pindex);
void swap_pager_swap_init(void);
int swap_pager_nswapdev(void);
-int swap_pager_reserve(vm_object_t, vm_pindex_t, vm_size_t);
+int swap_pager_reserve(vm_object_t, vm_pindex_t, vm_pindex_t);
void swap_pager_status(int *total, int *used);
u_long swap_pager_swapped_pages(vm_object_t object);
void swapoff_all(void);
More information about the dev-commits-src-all
mailing list