Date: Thu, 24 Apr 2025 19:16:20 GMT From: Doug Moore <dougm@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 896dccb1c122 - main - vm_page: make grab_valid() with iter param Message-ID: <202504241916.53OJGKJO000680@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by dougm: URL: https://cgit.FreeBSD.org/src/commit/?id=896dccb1c1225d13ecb88a872204e2f80bcda453 commit 896dccb1c1225d13ecb88a872204e2f80bcda453 Author: Doug Moore <dougm@FreeBSD.org> AuthorDate: 2025-04-24 19:14:45 +0000 Commit: Doug Moore <dougm@FreeBSD.org> CommitDate: 2025-04-24 19:14:45 +0000 vm_page: make grab_valid() with iter param Define vm_page_grab_valid_iter() to be the function that does the work of vm_page_grab(), but has an iterator parameter passed to it. In a couple of places, this can be called directly to let an iterator get reused. Reviewed by: markj Differential Revision: https://reviews.freebsd.org/D49942 --- sys/kern/uipc_shm.c | 7 +++++-- sys/vm/vm_page.c | 51 ++++++++++++++++++++++++++++++++++++--------------- sys/vm/vm_page.h | 2 ++ 3 files changed, 43 insertions(+), 17 deletions(-) diff --git a/sys/kern/uipc_shm.c b/sys/kern/uipc_shm.c index 7004e4f1c6ea..28e90b73aa8d 100644 --- a/sys/kern/uipc_shm.c +++ b/sys/kern/uipc_shm.c @@ -100,6 +100,7 @@ #include <vm/vm_page.h> #include <vm/vm_pageout.h> #include <vm/vm_pager.h> +#include <vm/vm_radix.h> #include <vm/swap_pager.h> struct shm_mapping { @@ -195,6 +196,7 @@ SYSCTL_INT(_vm_largepages, OID_AUTO, reclaim_tries, static int uiomove_object_page(vm_object_t obj, size_t len, struct uio *uio) { + struct pctrie_iter pages; vm_page_t m; vm_pindex_t idx; size_t tlen; @@ -214,8 +216,9 @@ uiomove_object_page(vm_object_t obj, size_t len, struct uio *uio) * page: use zero_region. This is intended to avoid instantiating * pages on read from a sparse region. */ + vm_page_iter_init(&pages, obj); VM_OBJECT_WLOCK(obj); - m = vm_page_lookup(obj, idx); + m = vm_radix_iter_lookup(&pages, idx); if (uio->uio_rw == UIO_READ && m == NULL && !vm_pager_has_page(obj, idx, NULL, NULL)) { VM_OBJECT_WUNLOCK(obj); @@ -229,7 +232,7 @@ uiomove_object_page(vm_object_t obj, size_t len, struct uio *uio) * lock to page out tobj's pages because tobj is a OBJT_SWAP * type object. */ - rv = vm_page_grab_valid(&m, obj, idx, + rv = vm_page_grab_valid_iter(&m, obj, &pages, idx, VM_ALLOC_NORMAL | VM_ALLOC_SBUSY | VM_ALLOC_IGN_SBUSY); if (rv != VM_PAGER_OK) { VM_OBJECT_WUNLOCK(obj); diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c index 6601ea23bf0e..9e41735460db 100644 --- a/sys/vm/vm_page.c +++ b/sys/vm/vm_page.c @@ -4946,17 +4946,17 @@ vm_page_grab_unlocked(vm_object_t object, vm_pindex_t pindex, int allocflags) } /* - * Grab a page and make it valid, paging in if necessary. Pages missing from - * their pager are zero filled and validated. If a VM_ALLOC_COUNT is supplied - * and the page is not valid as many as VM_INITIAL_PAGEIN pages can be brought - * in simultaneously. Additional pages will be left on a paging queue but - * will neither be wired nor busy regardless of allocflags. + * Grab a page and make it valid, paging in if necessary. Use an iterator + * parameter. Pages missing from their pager are zero filled and validated. If + * a VM_ALLOC_COUNT is supplied and the page is not valid as many as + * VM_INITIAL_PAGEIN pages can be brought in simultaneously. Additional pages + * will be left on a paging queue but will neither be wired nor busy regardless + * of allocflags. */ int -vm_page_grab_valid(vm_page_t *mp, vm_object_t object, vm_pindex_t pindex, - int allocflags) +vm_page_grab_valid_iter(vm_page_t *mp, vm_object_t object, + struct pctrie_iter *pages, vm_pindex_t pindex, int allocflags) { - struct pctrie_iter pages; vm_page_t m, mpred; vm_page_t ma[VM_INITIAL_PAGEIN]; int after, i, pflags, rv; @@ -4971,10 +4971,9 @@ vm_page_grab_valid(vm_page_t *mp, vm_object_t object, vm_pindex_t pindex, pflags = allocflags & ~(VM_ALLOC_NOBUSY | VM_ALLOC_SBUSY | VM_ALLOC_WIRED | VM_ALLOC_IGN_SBUSY); pflags |= VM_ALLOC_WAITFAIL; - vm_page_iter_init(&pages, object); retrylookup: - if ((m = vm_radix_iter_lookup(&pages, pindex)) != NULL) { + if ((m = vm_radix_iter_lookup(pages, pindex)) != NULL) { /* * If the page is fully valid it can only become invalid * with the object lock held. If it is not valid it can @@ -4988,7 +4987,7 @@ retrylookup: vm_page_all_valid(m) ? allocflags : 0)) { (void)vm_page_grab_sleep(object, m, pindex, "pgrbwt", allocflags, true); - pctrie_iter_reset(&pages); + pctrie_iter_reset(pages); goto retrylookup; } if (vm_page_all_valid(m)) @@ -5002,13 +5001,14 @@ retrylookup: *mp = NULL; return (VM_PAGER_FAIL); } else { - mpred = vm_radix_iter_lookup_lt(&pages, pindex); - m = vm_page_alloc_after(object, &pages, pindex, pflags, mpred); + mpred = vm_radix_iter_lookup_lt(pages, pindex); + m = vm_page_alloc_after(object, pages, pindex, pflags, mpred); if (m == NULL) { if (!vm_pager_can_alloc_page(object, pindex)) { *mp = NULL; return (VM_PAGER_AGAIN); } + pctrie_iter_reset(pages); goto retrylookup; } } @@ -5019,10 +5019,11 @@ retrylookup: after = MIN(after, allocflags >> VM_ALLOC_COUNT_SHIFT); after = MAX(after, 1); ma[0] = mpred = m; + pctrie_iter_reset(pages); for (i = 1; i < after; i++) { - m = vm_radix_iter_lookup(&pages, pindex + i); + m = vm_radix_iter_lookup(pages, pindex + i); if (m == NULL) { - m = vm_page_alloc_after(object, &pages, + m = vm_page_alloc_after(object, pages, pindex + i, VM_ALLOC_NORMAL, mpred); if (m == NULL) break; @@ -5054,6 +5055,7 @@ retrylookup: } else { vm_page_zero_invalid(m, TRUE); } + pctrie_iter_reset(pages); out: if ((allocflags & VM_ALLOC_WIRED) != 0) vm_page_wire(m); @@ -5065,6 +5067,25 @@ out: return (VM_PAGER_OK); } +/* + * Grab a page and make it valid, paging in if necessary. Pages missing from + * their pager are zero filled and validated. If a VM_ALLOC_COUNT is supplied + * and the page is not valid as many as VM_INITIAL_PAGEIN pages can be brought + * in simultaneously. Additional pages will be left on a paging queue but + * will neither be wired nor busy regardless of allocflags. + */ +int +vm_page_grab_valid(vm_page_t *mp, vm_object_t object, vm_pindex_t pindex, + int allocflags) +{ + struct pctrie_iter pages; + + VM_OBJECT_ASSERT_WLOCKED(object); + vm_page_iter_init(&pages, object); + return (vm_page_grab_valid_iter(mp, object, &pages, pindex, + allocflags)); +} + /* * Grab a page. Keep on waiting, as long as the page exists in the object. If * the page doesn't exist, and the pager has it, allocate it and zero part of diff --git a/sys/vm/vm_page.h b/sys/vm/vm_page.h index bf2e850612d7..c24ae8b64d28 100644 --- a/sys/vm/vm_page.h +++ b/sys/vm/vm_page.h @@ -641,6 +641,8 @@ int vm_page_grab_pages_unlocked(vm_object_t object, vm_pindex_t pindex, int allocflags, vm_page_t *ma, int count); int vm_page_grab_valid(vm_page_t *mp, vm_object_t object, vm_pindex_t pindex, int allocflags); +int vm_page_grab_valid_iter(vm_page_t *mp, vm_object_t object, + struct pctrie_iter *, vm_pindex_t pindex, int allocflags); int vm_page_grab_valid_unlocked(vm_page_t *mp, vm_object_t object, vm_pindex_t pindex, int allocflags); void vm_page_deactivate(vm_page_t);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202504241916.53OJGKJO000680>