git: 983723943a5b - main - vm_pageout: rewrite cluster()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 17 Apr 2025 15:54:13 UTC
The branch main has been updated by dougm:
URL: https://cgit.FreeBSD.org/src/commit/?id=983723943a5b7f1f249ba8f646b20e57ad524fed
commit 983723943a5b7f1f249ba8f646b20e57ad524fed
Author: Doug Moore <dougm@FreeBSD.org>
AuthorDate: 2025-04-17 15:52:34 +0000
Commit: Doug Moore <dougm@FreeBSD.org>
CommitDate: 2025-04-17 15:52:34 +0000
vm_pageout: rewrite cluster()
Implement vm_pageout_cluster using iterators instead of vm_page_next()
and vm_page_prev(), and without gotos.
Reviewed by: kib
Differential Revision: https://reviews.freebsd.org/D49848
---
sys/vm/vm_pageout.c | 64 +++++++++++++++++++++++++++--------------------------
1 file changed, 33 insertions(+), 31 deletions(-)
diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c
index e2efa11842b5..7b303d7d905f 100644
--- a/sys/vm/vm_pageout.c
+++ b/sys/vm/vm_pageout.c
@@ -108,6 +108,7 @@
#include <vm/vm_pager.h>
#include <vm/vm_phys.h>
#include <vm/vm_pagequeue.h>
+#include <vm/vm_radix.h>
#include <vm/swap_pager.h>
#include <vm/vm_extern.h>
#include <vm/uma.h>
@@ -366,15 +367,16 @@ vm_pageout_flushable(vm_page_t m)
static int
vm_pageout_cluster(vm_page_t m)
{
+ struct pctrie_iter pages;
vm_page_t mc[2 * vm_pageout_page_count - 1];
- int alignment, num_ends, page_base, pageout_count;
+ int alignment, page_base, pageout_count;
VM_OBJECT_ASSERT_WLOCKED(m->object);
vm_page_assert_xbusied(m);
+ vm_page_iter_init(&pages, m->object);
alignment = m->pindex % vm_pageout_page_count;
- num_ends = 0;
page_base = nitems(mc) / 2;
pageout_count = 1;
mc[page_base] = m;
@@ -387,37 +389,37 @@ vm_pageout_cluster(vm_page_t m)
* holes). To solve this problem we do the reverse scan
* first and attempt to align our cluster, then do a
* forward scan if room remains.
+ *
+ * If we are at an alignment boundary, stop here, and switch directions.
*/
-more:
- m = mc[page_base];
- while (pageout_count < vm_pageout_page_count) {
- /*
- * If we are at an alignment boundary, and haven't reached the
- * last flushable page forward, stop here, and switch
- * directions.
- */
- if (alignment == pageout_count - 1 && num_ends == 0)
- break;
-
- m = vm_page_prev(m);
- if (m == NULL || !vm_pageout_flushable(m)) {
- num_ends++;
- break;
- }
- mc[--page_base] = m;
- ++pageout_count;
+ if (alignment > 0) {
+ pages.index = mc[page_base]->pindex;
+ do {
+ m = vm_radix_iter_prev(&pages);
+ if (m == NULL || !vm_pageout_flushable(m))
+ break;
+ mc[--page_base] = m;
+ } while (pageout_count++ < alignment);
}
- m = mc[page_base + pageout_count - 1];
- while (num_ends != 2 && pageout_count < vm_pageout_page_count) {
- m = vm_page_next(m);
- if (m == NULL || !vm_pageout_flushable(m)) {
- if (num_ends++ == 0)
- /* Resume the reverse scan. */
- goto more;
- break;
- }
- mc[page_base + pageout_count] = m;
- ++pageout_count;
+ if (pageout_count < vm_pageout_page_count) {
+ pages.index = mc[page_base + pageout_count - 1]->pindex;
+ do {
+ m = vm_radix_iter_next(&pages);
+ if (m == NULL || !vm_pageout_flushable(m))
+ break;
+ mc[page_base + pageout_count] = m;
+ } while (++pageout_count < vm_pageout_page_count);
+ }
+ if (pageout_count < vm_pageout_page_count &&
+ alignment == nitems(mc) / 2 - page_base) {
+ /* Resume the reverse scan. */
+ pages.index = mc[page_base]->pindex;
+ do {
+ m = vm_radix_iter_prev(&pages);
+ if (m == NULL || !vm_pageout_flushable(m))
+ break;
+ mc[--page_base] = m;
+ } while (++pageout_count < vm_pageout_page_count);
}
return (vm_pageout_flush(&mc[page_base], pageout_count,