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:
Konstantin Belousov 2016-12-24 09:57:31 +00:00
parent 4c06e939f8
commit 2e56b64fa4

View File

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