kern/54690: [PATCH] wrap swap_pager's swhash with a mutex

Bruce M Simpson bms at spc.org
Mon Jul 21 01:40:23 PDT 2003


>Number:         54690
>Category:       kern
>Synopsis:       [PATCH] wrap swap_pager's swhash with a mutex
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Mon Jul 21 01:40:18 PDT 2003
>Closed-Date:
>Last-Modified:
>Originator:     Bruce M Simpson
>Release:        FreeBSD 5.1-RELEASE i386
>Organization:
>Environment:
System: FreeBSD saboteur.dek.spc.org 5.1-RELEASE FreeBSD 5.1-RELEASE #3: Mon Jun 23 06:55:01 BST 2003 root at saboteur.dek.spc.org:/usr/src/sys/i386/compile/SABOTEUR i386


	
>Description:
	Requested and reviewed by alc at freebsd.org -- wrap the swap block
	hash table in the swap pager with a fine grained lock.
>How-To-Repeat:
	
>Fix:

	

--- swhash.col.patch begins here ---
Generated by diffcoll on Sat 19 Jul 2003 20:35:54 BST

diff -uN src/sys/vm/swap_pager.c.orig src/sys/vm/swap_pager.c
--- /usr/src/sys/vm/swap_pager.c.orig	Sat Jul 19 00:56:10 2003
+++ /usr/src/sys/vm/swap_pager.c	Sat Jul 19 20:35:47 2003
@@ -113,8 +113,11 @@
 static int nsw_cluster_max;	/* maximum VOP I/O allowed		*/
 
 struct blist *swapblist;
+
+static struct mtx swhash_mtx;	/* protect hash table */
 static struct swblock **swhash;
 static int swhash_mask;
+
 static int swap_async_max = 4;	/* maximum in-progress async I/O's	*/
 static struct sx sw_alloc_sx;
 
@@ -256,6 +259,8 @@
 	 */
 	dmmax = SWB_NPAGES * 2;
 	dmmax_mask = ~(dmmax - 1);
+
+	mtx_init(&swhash_mtx, "swap_pager swhash mutex", NULL, MTX_DEF);
 }
 
 /*
@@ -1752,6 +1757,7 @@
 
 full_rescan:
 	waitobj = NULL;
+	mtx_lock(&swhash_mtx);
 	for (i = 0; i <= swhash_mask; i++) { /* '<=' is correct here */
 restart:
 		pswap = &swhash[i];
@@ -1763,7 +1769,9 @@
                                         break;
                         }
 			if (j < SWAP_META_PAGES) {
+				mtx_unlock(&swhash_mtx);
 				swp_pager_force_pagein(swap, j);
+				mtx_lock(&swhash_mtx);
 				goto restart;
 			} else if (swap->swb_object->paging_in_progress) {
 				if (!waitobj)
@@ -1772,6 +1780,8 @@
 			pswap = &swap->swb_hnext;
 		}
 	}
+	mtx_unlock(&swhash_mtx);
+
 	if (waitobj && *sw_used) {
 	    /*
 	     * We wait on an arbitrary object to clock our rescans
@@ -1782,6 +1792,7 @@
 	    VM_OBJECT_UNLOCK(waitobj);
 	    goto full_rescan;
 	}
+
 	if (*sw_used)
 	    panic("swapoff: failed to locate %d swap blocks", *sw_used);
 }
@@ -1817,6 +1828,8 @@
 	struct swblock *swap;
 
 	index &= ~(vm_pindex_t)SWAP_META_MASK;
+
+	mtx_lock(&swhash_mtx);
 	pswap = &swhash[(index ^ (int)(intptr_t)object) & swhash_mask];
 	while ((swap = *pswap) != NULL) {
 		if (swap->swb_object == object &&
@@ -1826,6 +1839,8 @@
 		}
 		pswap = &swap->swb_hnext;
 	}
+	mtx_unlock(&swhash_mtx);
+
 	return (pswap);
 }
 
--- swhash.col.patch ends here ---


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list