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