From 1390a5cbeb1828b11584783c53f50b9679379651 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 1 May 2021 20:12:32 +0300 Subject: [PATCH] Add pgo_freespace method Makes the code in vm_object collapse/page_remove cleaner Reviewed by: markj Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D30070 --- sys/vm/swap_pager.c | 7 ++++--- sys/vm/swap_pager.h | 1 - sys/vm/vm_object.c | 24 ++++++++---------------- sys/vm/vm_pager.h | 14 ++++++++++++++ 4 files changed, 26 insertions(+), 20 deletions(-) diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c index 294f61e22cb1..f09a6ffc80dc 100644 --- a/sys/vm/swap_pager.c +++ b/sys/vm/swap_pager.c @@ -437,6 +437,8 @@ static void swap_pager_set_writeable_dirty(vm_object_t object); static bool swap_pager_mightbedirty(vm_object_t object); static void swap_pager_getvp(vm_object_t object, struct vnode **vpp, bool *vp_heldp); +static void swap_pager_freespace(vm_object_t object, vm_pindex_t start, + vm_size_t size); struct pagerops swappagerops = { .pgo_init = swap_pager_init, /* early system initialization of pager */ @@ -452,6 +454,7 @@ struct pagerops swappagerops = { .pgo_set_writeable_dirty = swap_pager_set_writeable_dirty, .pgo_mightbedirty = swap_pager_mightbedirty, .pgo_getvp = swap_pager_getvp, + .pgo_freespace = swap_pager_freespace, }; /* @@ -942,8 +945,6 @@ sysctl_swap_fragmentation(SYSCTL_HANDLER_ARGS) * SWAP_PAGER_FREESPACE() - frees swap blocks associated with a page * range within an object. * - * This is a globally accessible routine. - * * This routine removes swapblk assignments from swap metadata. * * The external callers of this routine typically have already destroyed @@ -952,7 +953,7 @@ sysctl_swap_fragmentation(SYSCTL_HANDLER_ARGS) * * The object must be locked. */ -void +static void swap_pager_freespace(vm_object_t object, vm_pindex_t start, vm_size_t size) { diff --git a/sys/vm/swap_pager.h b/sys/vm/swap_pager.h index 59ca2cc2cfdb..7a2ea12e887d 100644 --- a/sys/vm/swap_pager.h +++ b/sys/vm/swap_pager.h @@ -76,7 +76,6 @@ struct xswdev; int swap_dev_info(int name, struct xswdev *xs, char *devname, size_t len); void swap_pager_copy(vm_object_t, vm_object_t, vm_pindex_t, int); vm_pindex_t swap_pager_find_least(vm_object_t object, vm_pindex_t pindex); -void swap_pager_freespace(vm_object_t, vm_pindex_t, vm_size_t); void swap_pager_swap_init(void); int swap_pager_nswapdev(void); int swap_pager_reserve(vm_object_t, vm_pindex_t, vm_size_t); diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c index b601bff33ff4..7b380608cdf4 100644 --- a/sys/vm/vm_object.c +++ b/sys/vm/vm_object.c @@ -1277,8 +1277,8 @@ vm_object_madvise_freespace(vm_object_t object, int advice, vm_pindex_t pindex, vm_size_t size) { - if (advice == MADV_FREE && object->type == OBJT_SWAP) - swap_pager_freespace(object, pindex, size); + if (advice == MADV_FREE) + vm_pager_freespace(object, pindex, size); } /* @@ -1798,9 +1798,7 @@ vm_object_collapse_scan(vm_object_t object) if (p->pindex < backing_offset_index || new_pindex >= object->size) { - if (backing_object->type == OBJT_SWAP) - swap_pager_freespace(backing_object, p->pindex, - 1); + vm_pager_freespace(backing_object, p->pindex, 1); KASSERT(!pmap_page_is_mapped(p), ("freeing mapped page %p", p)); @@ -1849,9 +1847,7 @@ vm_object_collapse_scan(vm_object_t object) * page alone. Destroy the original page from the * backing object. */ - if (backing_object->type == OBJT_SWAP) - swap_pager_freespace(backing_object, p->pindex, - 1); + vm_pager_freespace(backing_object, p->pindex, 1); KASSERT(!pmap_page_is_mapped(p), ("freeing mapped page %p", p)); if (vm_page_remove(p)) @@ -1875,9 +1871,8 @@ vm_object_collapse_scan(vm_object_t object) } /* Use the old pindex to free the right page. */ - if (backing_object->type == OBJT_SWAP) - swap_pager_freespace(backing_object, - new_pindex + backing_offset_index, 1); + vm_pager_freespace(backing_object, new_pindex + + backing_offset_index, 1); #if VM_NRESERVLEVEL > 0 /* @@ -2138,11 +2133,8 @@ vm_object_page_remove(vm_object_t object, vm_pindex_t start, vm_pindex_t end, } vm_object_pip_wakeup(object); - if (object->type == OBJT_SWAP) { - if (end == 0) - end = object->size; - swap_pager_freespace(object, start, end - start); - } + vm_pager_freespace(object, start, (end == 0 ? object->size : end) - + start); } /* diff --git a/sys/vm/vm_pager.h b/sys/vm/vm_pager.h index cb2a896c8749..6a35c066bea6 100644 --- a/sys/vm/vm_pager.h +++ b/sys/vm/vm_pager.h @@ -67,6 +67,8 @@ typedef void pgo_set_writeable_dirty_t(vm_object_t); typedef bool pgo_mightbedirty_t(vm_object_t); typedef void pgo_getvp_t(vm_object_t object, struct vnode **vpp, bool *vp_heldp); +typedef void pgo_freespace_t(vm_object_t object, vm_pindex_t start, + vm_size_t size); struct pagerops { pgo_init_t *pgo_init; /* Initialize pager. */ @@ -83,6 +85,7 @@ struct pagerops { pgo_set_writeable_dirty_t *pgo_set_writeable_dirty; pgo_mightbedirty_t *pgo_mightbedirty; pgo_getvp_t *pgo_getvp; + pgo_freespace_t *pgo_freespace; }; extern struct pagerops defaultpagerops; @@ -236,6 +239,17 @@ vm_pager_getvp(vm_object_t object, struct vnode **vpp, bool *vp_heldp) } } +static __inline void +vm_pager_freespace(vm_object_t object, vm_pindex_t start, + vm_size_t size) +{ + pgo_freespace_t *method; + + method = pagertab[object->type]->pgo_freespace; + if (method != NULL) + method(object, start, size); +} + struct cdev_pager_ops { int (*cdev_pg_fault)(vm_object_t vm_obj, vm_ooffset_t offset, int prot, vm_page_t *mres);