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
This commit is contained in:
Konstantin Belousov 2021-05-01 20:12:32 +03:00
parent 192112b74f
commit 1390a5cbeb
4 changed files with 26 additions and 20 deletions

View File

@ -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)
{

View File

@ -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);

View File

@ -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);
}
/*

View File

@ -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);