diff options
author | dillon <dillon@FreeBSD.org> | 2001-12-20 22:42:27 +0000 |
---|---|---|
committer | dillon <dillon@FreeBSD.org> | 2001-12-20 22:42:27 +0000 |
commit | ac9876d609290ddd585a1e5a67550061f01c20dd (patch) | |
tree | 74464ed2703c6925992ebe509294859864e96118 /sys/vm | |
parent | 53b1a7ecefc98fa3a2e71925a3be359d4873214b (diff) | |
download | FreeBSD-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.c | 15 |
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++; |