summaryrefslogtreecommitdiffstats
path: root/sys/vm
diff options
context:
space:
mode:
authordillon <dillon@FreeBSD.org>2001-12-20 22:42:27 +0000
committerdillon <dillon@FreeBSD.org>2001-12-20 22:42:27 +0000
commitac9876d609290ddd585a1e5a67550061f01c20dd (patch)
tree74464ed2703c6925992ebe509294859864e96118 /sys/vm
parent53b1a7ecefc98fa3a2e71925a3be359d4873214b (diff)
downloadFreeBSD-src-ac9876d609290ddd585a1e5a67550061f01c20dd.zip
FreeBSD-src-ac9876d609290ddd585a1e5a67550061f01c20dd.tar.gz
Fix a BUF_TIMELOCK race against BUF_LOCK and fix a deadlock in vget()
against VM_WAIT in the pageout code. Both fixes involve adjusting the lockmgr's timeout capability so locks obtained with timeouts do not interfere with locks obtained without a timeout. Hopefully MFC: before the 4.5 release
Diffstat (limited to 'sys/vm')
-rw-r--r--sys/vm/vm_pageout.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c
index 73ef06d..47ce9e8 100644
--- a/sys/vm/vm_pageout.c
+++ b/sys/vm/vm_pageout.c
@@ -193,6 +193,10 @@ SYSCTL_INT(_vm, OID_AUTO, defer_swapspace_pageouts,
SYSCTL_INT(_vm, OID_AUTO, disable_swapspace_pageouts,
CTLFLAG_RW, &disable_swap_pageouts, 0, "Disallow swapout of dirty pages");
+static int pageout_lock_miss;
+SYSCTL_INT(_vm, OID_AUTO, pageout_lock_miss,
+ CTLFLAG_RD, &pageout_lock_miss, 0, "vget() lock misses during pageout");
+
#define VM_PAGEOUT_PAGE_COUNT 16
int vm_pageout_page_count = VM_PAGEOUT_PAGE_COUNT;
@@ -860,17 +864,20 @@ rescan0:
* way too large a weighting to defering the freeing
* of dirty pages.
*
- * XXX we need to be able to apply a timeout to the
- * vget() lock attempt.
+ * We can't wait forever for the vnode lock, we might
+ * deadlock due to a vn_read() getting stuck in
+ * vm_wait while holding this vnode. We skip the
+ * vnode if we can't get it in a reasonable amount
+ * of time.
*/
-
if (object->type == OBJT_VNODE) {
vp = object->handle;
mp = NULL;
if (vp->v_type == VREG)
vn_start_write(vp, &mp, V_NOWAIT);
- if (vget(vp, LK_EXCLUSIVE|LK_NOOBJ, curthread)) {
+ if (vget(vp, LK_EXCLUSIVE|LK_NOOBJ|LK_TIMELOCK, curthread)) {
+ ++pageout_lock_miss;
vn_finished_write(mp);
if (object->flags & OBJ_MIGHTBEDIRTY)
vnodes_skipped++;
OpenPOWER on IntegriCloud