The branch main has been updated by markj:

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

commit 4c6c1dd8f7cef09afd03fa873487aba0c5dd13ba
Author:     Mark Johnston <ma...@freebsd.org>
AuthorDate: 2025-06-18 21:14:51 +0000
Commit:     Mark Johnston <ma...@freebsd.org>
CommitDate: 2025-06-18 23:48:07 +0000

    vm_page: Fix nofree page accounting
    
    In commit ae10431c9833 ("vm_page: Allow PG_NOFREE pages to be freed"), I
    changed the v_nofree_count counter to instead count the size of the
    nofree queue, on the basis that with the ability to free nofree pages,
    the size of the queue is unbounded.
    
    The use of a counter(9) for this purpose is not really correct, as early
    initialization of per-CPU counters interferes with precise accounting
    that we want here.  Instead, add a global tracker for this purpose,
    expose it elsewhere in the sysctl tree, and restore v_free_nofree's
    original use as a counter of allocated nofree pages.
    
    Reviewed by:    bnovkov, alc, kib
    Reported by:    alc
    Fixes:          ae10431c9833 ("vm_page: Allow PG_NOFREE pages to be freed")
    Differential Revision:  https://reviews.freebsd.org/D50877
---
 sys/vm/vm_page.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
index b00f775de6e7..66aae45cb37e 100644
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -140,6 +140,11 @@ SYSCTL_COUNTER_U64(_vm_stats_page, OID_AUTO, queue_nops,
     CTLFLAG_RD, &queue_nops,
     "Number of batched queue operations with no effects");
 
+static unsigned long nofreeq_size;
+SYSCTL_ULONG(_vm_stats_page, OID_AUTO, nofreeq_size, CTLFLAG_RD,
+    &nofreeq_size, 0,
+    "Size of the nofree queue");
+
 /*
  * bogus page -- for I/O to/from partially complete buffers,
  * or for paging into sparsely invalid regions.
@@ -2540,7 +2545,7 @@ vm_page_alloc_nofree_domain(int domain, int req)
                }
                m->ref_count = count - 1;
                TAILQ_INSERT_HEAD(&vmd->vmd_nofreeq, m, plinks.q);
-               VM_CNT_ADD(v_nofree_count, count);
+               atomic_add_long(&nofreeq_size, count);
        }
        m = TAILQ_FIRST(&vmd->vmd_nofreeq);
        TAILQ_REMOVE(&vmd->vmd_nofreeq, m, plinks.q);
@@ -2554,7 +2559,8 @@ vm_page_alloc_nofree_domain(int domain, int req)
                m->ref_count = 0;
        }
        vm_domain_free_unlock(vmd);
-       VM_CNT_ADD(v_nofree_count, -1);
+       atomic_add_long(&nofreeq_size, -1);
+       VM_CNT_INC(v_nofree_count);
 
        return (m);
 }
@@ -2568,11 +2574,12 @@ vm_page_alloc_nofree_domain(int domain, int req)
 static void __noinline
 vm_page_free_nofree(struct vm_domain *vmd, vm_page_t m)
 {
+       VM_CNT_ADD(v_nofree_count, -1);
+       atomic_add_long(&nofreeq_size, 1);
        vm_domain_free_lock(vmd);
        MPASS(m->ref_count == 0);
        TAILQ_INSERT_HEAD(&vmd->vmd_nofreeq, m, plinks.q);
        vm_domain_free_unlock(vmd);
-       VM_CNT_ADD(v_nofree_count, 1);
 }
 
 vm_page_t

Reply via email to