Fix argument type and microoptimize swp_pager_meta_free().
The count argument natural type if vm_pindex_t, but due to the loop organization, it has to be signed type to detect the termination condition. Replace this logic by using distinguished counter for the processed pages, and terminate loop when the counter exceeds the argument. Completely process one swblock for all relevant indexes instead of doing relookup in hash when incrementing page index on the loop step. Do not drop hash mutex around iterations. Noted and reviewed by: alc Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 2 weeks
This commit is contained in:
parent
733e7b5b6c
commit
da005e5578
@ -410,7 +410,7 @@ static daddr_t swp_pager_getswapspace(int npages);
|
||||
*/
|
||||
static struct swblock **swp_pager_hash(vm_object_t object, vm_pindex_t index);
|
||||
static void swp_pager_meta_build(vm_object_t, vm_pindex_t, daddr_t);
|
||||
static void swp_pager_meta_free(vm_object_t, vm_pindex_t, daddr_t);
|
||||
static void swp_pager_meta_free(vm_object_t, vm_pindex_t, vm_pindex_t);
|
||||
static void swp_pager_meta_free_all(vm_object_t);
|
||||
static daddr_t swp_pager_meta_ctl(vm_object_t, vm_pindex_t, int);
|
||||
|
||||
@ -1869,42 +1869,42 @@ swp_pager_meta_build(vm_object_t object, vm_pindex_t pindex, daddr_t swapblk)
|
||||
* with resident pages.
|
||||
*/
|
||||
static void
|
||||
swp_pager_meta_free(vm_object_t object, vm_pindex_t index, daddr_t count)
|
||||
swp_pager_meta_free(vm_object_t object, vm_pindex_t index, vm_pindex_t count)
|
||||
{
|
||||
struct swblock **pswap, *swap;
|
||||
vm_pindex_t c;
|
||||
daddr_t v;
|
||||
int n, sidx;
|
||||
|
||||
VM_OBJECT_ASSERT_LOCKED(object);
|
||||
if (object->type != OBJT_SWAP)
|
||||
if (object->type != OBJT_SWAP || count == 0)
|
||||
return;
|
||||
|
||||
while (count > 0) {
|
||||
struct swblock **pswap;
|
||||
struct swblock *swap;
|
||||
|
||||
mtx_lock(&swhash_mtx);
|
||||
mtx_lock(&swhash_mtx);
|
||||
for (c = 0; c < count;) {
|
||||
pswap = swp_pager_hash(object, index);
|
||||
|
||||
if ((swap = *pswap) != NULL) {
|
||||
daddr_t v = swap->swb_pages[index & SWAP_META_MASK];
|
||||
|
||||
if (v != SWAPBLK_NONE) {
|
||||
swp_pager_freeswapspace(v, 1);
|
||||
swap->swb_pages[index & SWAP_META_MASK] =
|
||||
SWAPBLK_NONE;
|
||||
if (--swap->swb_count == 0) {
|
||||
*pswap = swap->swb_hnext;
|
||||
uma_zfree(swap_zone, swap);
|
||||
--object->un_pager.swp.swp_bcount;
|
||||
}
|
||||
}
|
||||
--count;
|
||||
++index;
|
||||
} else {
|
||||
int n = SWAP_META_PAGES - (index & SWAP_META_MASK);
|
||||
count -= n;
|
||||
index += n;
|
||||
sidx = index & SWAP_META_MASK;
|
||||
n = SWAP_META_PAGES - sidx;
|
||||
index += n;
|
||||
if ((swap = *pswap) == NULL) {
|
||||
c += n;
|
||||
continue;
|
||||
}
|
||||
for (; c < count && sidx < SWAP_META_PAGES; ++c, ++sidx) {
|
||||
if ((v = swap->swb_pages[sidx]) == SWAPBLK_NONE)
|
||||
continue;
|
||||
swp_pager_freeswapspace(v, 1);
|
||||
swap->swb_pages[sidx] = SWAPBLK_NONE;
|
||||
if (--swap->swb_count == 0) {
|
||||
*pswap = swap->swb_hnext;
|
||||
uma_zfree(swap_zone, swap);
|
||||
--object->un_pager.swp.swp_bcount;
|
||||
c += SWAP_META_PAGES - sidx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
mtx_unlock(&swhash_mtx);
|
||||
}
|
||||
mtx_unlock(&swhash_mtx);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user