git: 18a8f4e586b1 - main - vm_page: correct page iterator patch
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 20 Nov 2024 18:04:09 UTC
The branch main has been updated by dougm: URL: https://cgit.FreeBSD.org/src/commit/?id=18a8f4e586b1a5f4e01da7e5f76099a69a3dd1f8 commit 18a8f4e586b1a5f4e01da7e5f76099a69a3dd1f8 Author: Doug Moore <dougm@FreeBSD.org> AuthorDate: 2024-11-20 18:00:57 +0000 Commit: Doug Moore <dougm@FreeBSD.org> CommitDate: 2024-11-20 18:00:57 +0000 vm_page: correct page iterator patch The previous change committed a preliminary version of the change to use iterators to free page sequences. This updates to what was intended to be the final version. Reviewed by: markj (previous version) Tested by: pho Differential Revision: https://reviews.freebsd.org/D46724 --- sys/vm/vm_page.c | 118 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 63 insertions(+), 55 deletions(-) diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c index 7d093579e35d..296d803ca0f0 100644 --- a/sys/vm/vm_page.c +++ b/sys/vm/vm_page.c @@ -170,7 +170,7 @@ static bool _vm_page_busy_sleep(vm_object_t obj, vm_page_t m, vm_pindex_t pindex, const char *wmesg, int allocflags, bool locked); static void vm_page_clear_dirty_mask(vm_page_t m, vm_page_bits_t pagebits); static void vm_page_enqueue(vm_page_t m, uint8_t queue); -static bool vm_page_free_prep(vm_page_t m, bool do_remove); +static bool vm_page_free_prep(vm_page_t m); static void vm_page_free_toq(vm_page_t m); static void vm_page_free_toq_impl(vm_page_t m, bool do_remove); static void vm_page_init(void *dummy); @@ -1387,22 +1387,6 @@ vm_page_free(vm_page_t m) vm_page_free_toq(m); } -/* - * vm_page_iter_free: - * - * Free the current page, as identified by iterator. - */ -void -vm_page_iter_free(struct pctrie_iter *pages) -{ - vm_page_t m; - - m = vm_radix_iter_page(pages); - vm_radix_iter_remove(pages); - m->flags &= ~PG_ZERO; - vm_page_free_toq_impl(m, false); -} - /* * vm_page_free_zero: * @@ -1699,6 +1683,52 @@ vm_page_remove_radixdone(vm_page_t m) vdrop(object->handle); } +/* + * vm_page_free_object_prep: + * + * Disassociates the given page from its VM object. + * + * The object must be locked, and the page must be xbusy. + */ +static void +vm_page_free_object_prep(vm_page_t m) +{ + KASSERT(((m->oflags & VPO_UNMANAGED) != 0) == + ((m->object->flags & OBJ_UNMANAGED) != 0), + ("%s: managed flag mismatch for page %p", + __func__, m)); + vm_page_assert_xbusied(m); + + /* + * The object reference can be released without an atomic + * operation. + */ + KASSERT((m->flags & PG_FICTITIOUS) != 0 || + m->ref_count == VPRC_OBJREF, + ("%s: page %p has unexpected ref_count %u", + __func__, m, m->ref_count)); + vm_page_remove_radixdone(m); + m->ref_count -= VPRC_OBJREF; +} + +/* + * vm_page_iter_free: + * + * Free the current page, as identified by iterator. + */ +void +vm_page_iter_free(struct pctrie_iter *pages) +{ + vm_page_t m; + + m = vm_radix_iter_page(pages); + vm_radix_iter_remove(pages); + vm_page_free_object_prep(m); + vm_page_xunbusy(m); + m->flags &= ~PG_ZERO; + vm_page_free_toq(m); +} + /* * vm_page_remove: * @@ -3180,7 +3210,7 @@ vm_page_reclaim_run(int req_class, int domain, u_long npages, vm_page_t m_run, vm_page_dequeue(m); if (vm_page_replace_hold(m_new, object, m->pindex, m) && - vm_page_free_prep(m, true)) + vm_page_free_prep(m)) SLIST_INSERT_HEAD(&free, m, plinks.s.ss); @@ -3192,7 +3222,7 @@ vm_page_reclaim_run(int req_class, int domain, u_long npages, vm_page_t m_run, } else { m->flags &= ~PG_ZERO; vm_page_dequeue(m); - if (vm_page_free_prep(m, true)) + if (vm_page_free_prep(m)) SLIST_INSERT_HEAD(&free, m, plinks.s.ss); KASSERT(m->dirty == 0, @@ -4131,7 +4161,7 @@ vm_page_enqueue(vm_page_t m, uint8_t queue) * page must be unmapped. */ static bool -vm_page_free_prep(vm_page_t m, bool do_remove) +vm_page_free_prep(vm_page_t m) { /* @@ -4164,24 +4194,8 @@ vm_page_free_prep(vm_page_t m, bool do_remove) VM_CNT_INC(v_tfree); if (m->object != NULL) { - KASSERT(((m->oflags & VPO_UNMANAGED) != 0) == - ((m->object->flags & OBJ_UNMANAGED) != 0), - ("vm_page_free_prep: managed flag mismatch for page %p", - m)); - vm_page_assert_xbusied(m); - - /* - * The object reference can be released without an atomic - * operation. - */ - KASSERT((m->flags & PG_FICTITIOUS) != 0 || - m->ref_count == VPRC_OBJREF, - ("vm_page_free_prep: page %p has unexpected ref_count %u", - m, m->ref_count)); - if (do_remove) - vm_page_radix_remove(m); - vm_page_remove_radixdone(m); - m->ref_count -= VPRC_OBJREF; + vm_page_radix_remove(m); + vm_page_free_object_prep(m); } else vm_page_assert_unbusied(m); @@ -4232,13 +4246,22 @@ vm_page_free_prep(vm_page_t m, bool do_remove) return (true); } +/* + * vm_page_free_toq: + * + * Returns the given page to the free list, disassociating it + * from any VM object. + * + * The object must be locked. The page must be exclusively busied if it + * belongs to an object. + */ static void -vm_page_free_toq_impl(vm_page_t m, bool do_remove) +vm_page_free_toq(vm_page_t m) { struct vm_domain *vmd; uma_zone_t zone; - if (!vm_page_free_prep(m, do_remove)) + if (!vm_page_free_prep(m)) return; vmd = vm_pagequeue_domain(m); @@ -4253,21 +4276,6 @@ vm_page_free_toq_impl(vm_page_t m, bool do_remove) vm_domain_freecnt_inc(vmd, 1); } -/* - * vm_page_free_toq: - * - * Returns the given page to the free list, disassociating it - * from any VM object. - * - * The object must be locked. The page must be exclusively busied if it - * belongs to an object. - */ -static void -vm_page_free_toq(vm_page_t m) -{ - vm_page_free_toq_impl(m, true); -} - /* * vm_page_free_pages_toq: *