The branch main has been updated by dougm:

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

commit a880104a21bf41ebbb4ead26e6d4adda32bad76c
Author:     Doug Moore <[email protected]>
AuthorDate: 2024-06-12 03:51:40 +0000
Commit:     Doug Moore <[email protected]>
CommitDate: 2024-06-12 03:54:39 +0000

    swap_pager: add new page range struct
    
    Define a page_range struct to pair up the two values passed to
    freerange functions. Have swp_pager_freeswapspace also take a
    page_range argument rather than a pair of arguments.
    
    In swp_pager_meta_free_all, drop a needless test and use a new
    helper function to do the cleanup for each swap block.
    
    Reviewed by:    kib
    Differential Revision:  https://reviews.freebsd.org/D45562
---
 sys/vm/swap_pager.c | 99 ++++++++++++++++++++++++++++++-----------------------
 1 file changed, 56 insertions(+), 43 deletions(-)

diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c
index 15f227457bba..3bfda3eea169 100644
--- a/sys/vm/swap_pager.c
+++ b/sys/vm/swap_pager.c
@@ -142,6 +142,15 @@ struct swblk {
        daddr_t         d[SWAP_META_PAGES];
 };
 
+/*
+ * A page_range structure records the start address and length of a sequence of
+ * mapped page addresses.
+ */
+struct page_range {
+       daddr_t start;
+       daddr_t num;
+};
+
 static MALLOC_DEFINE(M_VMPGDATA, "vm_pgdata", "swap pager private data");
 static struct mtx sw_dev_mtx;
 static TAILQ_HEAD(, swdevt) swtailq = TAILQ_HEAD_INITIALIZER(swtailq);
@@ -471,7 +480,7 @@ static int  swapoff_one(struct swdevt *sp, struct ucred 
*cred,
 /*
  * Swap bitmap functions
  */
-static void    swp_pager_freeswapspace(daddr_t blk, daddr_t npages);
+static void    swp_pager_freeswapspace(const struct page_range *range);
 static daddr_t swp_pager_getswapspace(int *npages);
 
 /*
@@ -486,23 +495,21 @@ static void swp_pager_meta_free_all(vm_object_t);
 static daddr_t swp_pager_meta_lookup(vm_object_t, vm_pindex_t);
 
 static void
-swp_pager_init_freerange(daddr_t *start, daddr_t *num)
+swp_pager_init_freerange(struct page_range *range)
 {
-
-       *start = SWAPBLK_NONE;
-       *num = 0;
+       range->start = SWAPBLK_NONE;
+       range->num = 0;
 }
 
 static void
-swp_pager_update_freerange(daddr_t *start, daddr_t *num, daddr_t addr)
+swp_pager_update_freerange(struct page_range *range, daddr_t addr)
 {
-
-       if (*start + *num == addr) {
-               (*num)++;
+       if (range->start + range->num == addr) {
+               range->num++;
        } else {
-               swp_pager_freeswapspace(*start, *num);
-               *start = addr;
-               *num = 1;
+               swp_pager_freeswapspace(range);
+               range->start = addr;
+               range->num = 1;
        }
 }
 
@@ -906,10 +913,13 @@ swp_pager_strategy(struct buf *bp)
  *     This routine may not sleep.
  */
 static void
-swp_pager_freeswapspace(daddr_t blk, daddr_t npages)
+swp_pager_freeswapspace(const struct page_range *range)
 {
+       daddr_t blk, npages;
        struct swdevt *sp;
 
+       blk = range->start;
+       npages = range->num;
        if (npages == 0)
                return;
        mtx_lock(&sw_dev_mtx);
@@ -1004,11 +1014,12 @@ swap_pager_freespace_pgo(vm_object_t object, 
vm_pindex_t start, vm_size_t size)
 int
 swap_pager_reserve(vm_object_t object, vm_pindex_t start, vm_pindex_t size)
 {
-       daddr_t addr, blk, n_free, s_free;
+       struct page_range range;
+       daddr_t addr, blk;
        vm_pindex_t i, j;
        int n;
 
-       swp_pager_init_freerange(&s_free, &n_free);
+       swp_pager_init_freerange(&range);
        VM_OBJECT_WLOCK(object);
        for (i = 0; i < size; i += n) {
                n = MIN(size - i, INT_MAX);
@@ -1022,11 +1033,10 @@ swap_pager_reserve(vm_object_t object, vm_pindex_t 
start, vm_pindex_t size)
                        addr = swp_pager_meta_build(object,
                            start + i + j, blk + j);
                        if (addr != SWAPBLK_NONE)
-                               swp_pager_update_freerange(&s_free, &n_free,
-                                   addr);
+                               swp_pager_update_freerange(&range, addr);
                }
        }
-       swp_pager_freeswapspace(s_free, n_free);
+       swp_pager_freeswapspace(&range);
        VM_OBJECT_WUNLOCK(object);
        return (0);
 }
@@ -1195,6 +1205,7 @@ swap_pager_haspage(vm_object_t object, vm_pindex_t 
pindex, int *before,
 static void
 swap_pager_unswapped(vm_page_t m)
 {
+       struct page_range range;
        struct swblk *sb;
        vm_object_t obj;
 
@@ -1233,9 +1244,11 @@ swap_pager_unswapped(vm_page_t m)
            rounddown(m->pindex, SWAP_META_PAGES));
        if (sb == NULL)
                return;
-       if (sb->d[m->pindex % SWAP_META_PAGES] == SWAPBLK_NONE)
+       range.start = sb->d[m->pindex % SWAP_META_PAGES];
+       if (range.start == SWAPBLK_NONE)
                return;
-       swp_pager_freeswapspace(sb->d[m->pindex % SWAP_META_PAGES], 1);
+       range.num = 1;
+       swp_pager_freeswapspace(&range);
        sb->d[m->pindex % SWAP_META_PAGES] = SWAPBLK_NONE;
        swp_pager_free_empty_swblk(m->object, sb);
 }
@@ -1480,8 +1493,9 @@ static void
 swap_pager_putpages(vm_object_t object, vm_page_t *ma, int count,
     int flags, int *rtvals)
 {
+       struct page_range range;
        struct buf *bp;
-       daddr_t addr, blk, n_free, s_free;
+       daddr_t addr, blk;
        vm_page_t mreq;
        int i, j, n;
        bool async;
@@ -1492,7 +1506,7 @@ swap_pager_putpages(vm_object_t object, vm_page_t *ma, 
int count,
 
        VM_OBJECT_WUNLOCK(object);
        async = curproc == pageproc && (flags & VM_PAGER_PUT_SYNC) == 0;
-       swp_pager_init_freerange(&s_free, &n_free);
+       swp_pager_init_freerange(&range);
 
        /*
         * Assign swap blocks and issue I/O.  We reallocate swap on the fly.
@@ -1530,8 +1544,7 @@ swap_pager_putpages(vm_object_t object, vm_page_t *ma, 
int count,
                        addr = swp_pager_meta_build(mreq->object, mreq->pindex,
                            blk + j);
                        if (addr != SWAPBLK_NONE)
-                               swp_pager_update_freerange(&s_free, &n_free,
-                                   addr);
+                               swp_pager_update_freerange(&range, addr);
                        MPASS(mreq->dirty == VM_PAGE_BITS_ALL);
                        mreq->oflags |= VPO_SWAPINPROG;
                }
@@ -1603,7 +1616,7 @@ swap_pager_putpages(vm_object_t object, vm_page_t *ma, 
int count,
                 */
                swp_pager_async_iodone(bp);
        }
-       swp_pager_freeswapspace(s_free, n_free);
+       swp_pager_freeswapspace(&range);
        VM_OBJECT_WLOCK(object);
 }
 
@@ -2131,9 +2144,9 @@ static void
 swp_pager_meta_transfer(vm_object_t srcobject, vm_object_t dstobject,
     vm_pindex_t pindex, vm_pindex_t count, vm_size_t *moved)
 {
+       struct page_range range;
        struct swblk *sb;
        vm_page_t m;
-       daddr_t n_free, s_free;
        vm_pindex_t offset, last;
        vm_size_t mc;
        int i, limit, start;
@@ -2146,7 +2159,7 @@ swp_pager_meta_transfer(vm_object_t srcobject, 
vm_object_t dstobject,
        if (count == 0 || pctrie_is_empty(&srcobject->un_pager.swp.swp_blks))
                goto out;
 
-       swp_pager_init_freerange(&s_free, &n_free);
+       swp_pager_init_freerange(&range);
        offset = pindex;
        last = pindex + count;
        for (;;) {
@@ -2163,8 +2176,7 @@ swp_pager_meta_transfer(vm_object_t srcobject, 
vm_object_t dstobject,
                        if (dstobject == NULL ||
                            !swp_pager_xfer_source(srcobject, dstobject, 
                            sb->p + i - offset, sb->d[i])) {
-                               swp_pager_update_freerange(&s_free, &n_free,
-                                   sb->d[i]);
+                               swp_pager_update_freerange(&range, sb->d[i]);
                        }
                        if (moved != NULL) {
                                if (m != NULL && m->pindex != pindex + i - 1)
@@ -2184,7 +2196,7 @@ swp_pager_meta_transfer(vm_object_t srcobject, 
vm_object_t dstobject,
                        uma_zfree(swblk_zone, sb);
                }
        }
-       swp_pager_freeswapspace(s_free, n_free);
+       swp_pager_freeswapspace(&range);
 out:
        if (moved != NULL)
                *moved = mc;
@@ -2207,6 +2219,16 @@ swp_pager_meta_free(vm_object_t object, vm_pindex_t 
pindex, vm_pindex_t count,
        swp_pager_meta_transfer(object, NULL, pindex, count, freed);
 }
 
+static void
+swp_pager_meta_free_block(struct swblk *sb, struct page_range *range)
+{
+       for (int i = 0; i < SWAP_META_PAGES; i++) {
+               if (sb->d[i] != SWAPBLK_NONE)
+                       swp_pager_update_freerange(range, sb->d[i]);
+       }
+       uma_zfree(swblk_zone, sb);
+}
+
 /*
  * SWP_PAGER_META_FREE_ALL() - destroy all swap metadata associated with object
  *
@@ -2217,28 +2239,19 @@ static void
 swp_pager_meta_free_all(vm_object_t object)
 {
        struct swblk *sb;
-       daddr_t n_free, s_free;
+       struct page_range range;
        vm_pindex_t pindex;
-       int i;
 
        VM_OBJECT_ASSERT_WLOCKED(object);
 
-       if (pctrie_is_empty(&object->un_pager.swp.swp_blks))
-               return;
-
-       swp_pager_init_freerange(&s_free, &n_free);
+       swp_pager_init_freerange(&range);
        for (pindex = 0; (sb = SWAP_PCTRIE_LOOKUP_GE(
            &object->un_pager.swp.swp_blks, pindex)) != NULL;) {
                pindex = sb->p + SWAP_META_PAGES;
-               for (i = 0; i < SWAP_META_PAGES; i++) {
-                       if (sb->d[i] == SWAPBLK_NONE)
-                               continue;
-                       swp_pager_update_freerange(&s_free, &n_free, sb->d[i]);
-               }
                SWAP_PCTRIE_REMOVE(&object->un_pager.swp.swp_blks, sb->p);
-               uma_zfree(swblk_zone, sb);
+               swp_pager_meta_free_block(sb, &range);
        }
-       swp_pager_freeswapspace(s_free, n_free);
+       swp_pager_freeswapspace(&range);
 }
 
 /*

Reply via email to