Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 24 Dec 2016 09:57:32 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r310496 - head/sys/vm
Message-ID:  <201612240957.uBO9vWTZ049843@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Sat Dec 24 09:57:31 2016
New Revision: 310496
URL: https://svnweb.freebsd.org/changeset/base/310496

Log:
  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

Modified:
  head/sys/vm/swap_pager.c

Modified: head/sys/vm/swap_pager.c
==============================================================================
--- head/sys/vm/swap_pager.c	Sat Dec 24 08:59:30 2016	(r310495)
+++ head/sys/vm/swap_pager.c	Sat Dec 24 09:57:31 2016	(r310496)
@@ -410,7 +410,7 @@ static daddr_t	swp_pager_getswapspace(in
  */
 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 @@ done:
  *	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;
-				}
+		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;
 			}
-			--count;
-			++index;
-		} else {
-			int n = SWAP_META_PAGES - (index & SWAP_META_MASK);
-			count -= n;
-			index += n;
 		}
-		mtx_unlock(&swhash_mtx);
 	}
+	mtx_unlock(&swhash_mtx);
 }
 
 /*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201612240957.uBO9vWTZ049843>