From b4460ab356b9d7f1bd11c8badbf2a6dc97a7776f Mon Sep 17 00:00:00 2001 From: Venkatesh Srinivas Date: Tue, 7 Jun 2011 13:13:34 -0700 Subject: [PATCH] kernel -- vm_object locking: Interlock vm_object work in vm_fault.c and vm_map.c with per-object token. Handle NULL objects for _hold and _drop. --- sys/vm/vm_fault.c | 16 ++++++++-------- sys/vm/vm_map.c | 3 +++ sys/vm/vm_object.c | 10 ++++++++++ sys/vm/vm_object.h | 4 ++++ sys/vm/vnode_pager.c | 2 +- 5 files changed, 26 insertions(+), 9 deletions(-) diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c index 5c621db4a2..b98dd113b8 100644 --- a/sys/vm/vm_fault.c +++ b/sys/vm/vm_fault.c @@ -355,13 +355,13 @@ RetryFault: * truncation operations) during I/O. This must be done after * obtaining the vnode lock in order to avoid possible deadlocks. * - * The vm_token is needed to manipulate the vm_object + * The vm_object must be held before manipulation. */ - lwkt_gettoken(&vm_token); + vm_object_hold(fs.first_object); vm_object_reference(fs.first_object); fs.vp = vnode_pager_lock(fs.first_object); vm_object_pip_add(fs.first_object, 1); - lwkt_reltoken(&vm_token); + vm_object_drop(fs.first_object); fs.lookup_still_valid = TRUE; fs.first_m = NULL; @@ -585,13 +585,13 @@ RetryFault: * truncation operations) during I/O. This must be done after * obtaining the vnode lock in order to avoid possible deadlocks. * - * The vm_token is needed to manipulate the vm_object + * The vm_object must be held before manipulation. */ - lwkt_gettoken(&vm_token); + vm_object_hold(fs.first_object); vm_object_reference(fs.first_object); fs.vp = vnode_pager_lock(fs.first_object); vm_object_pip_add(fs.first_object, 1); - lwkt_reltoken(&vm_token); + vm_object_drop(fs.first_object); fs.lookup_still_valid = TRUE; fs.first_m = NULL; @@ -746,11 +746,11 @@ RetryFault: * truncation operations) during I/O. This must be done after * obtaining the vnode lock in order to avoid possible deadlocks. */ - lwkt_gettoken(&vm_token); + vm_object_hold(fs.first_object); vm_object_reference(fs.first_object); fs.vp = vnode_pager_lock(fs.first_object); vm_object_pip_add(fs.first_object, 1); - lwkt_reltoken(&vm_token); + vm_object_drop(fs.first_object); fs.lookup_still_valid = TRUE; fs.first_m = NULL; diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c index 10224f6596..def68155ee 100644 --- a/sys/vm/vm_map.c +++ b/sys/vm/vm_map.c @@ -2711,6 +2711,7 @@ again: */ lwkt_gettoken(&vm_token); lwkt_gettoken(&vmobj_token); + vm_object_hold(object); if (object == &kernel_object) { vm_object_page_remove(object, offidxstart, @@ -2738,6 +2739,8 @@ again: } } } + + vm_object_drop(object); lwkt_reltoken(&vmobj_token); lwkt_reltoken(&vm_token); diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c index c35988a2c8..8f9bb362ef 100644 --- a/sys/vm/vm_object.c +++ b/sys/vm/vm_object.c @@ -243,7 +243,9 @@ void vm_object_reference(vm_object_t object) { lwkt_gettoken(&vmobj_token); + vm_object_hold(object); vm_object_reference_locked(object); + vm_object_drop(object); lwkt_reltoken(&vmobj_token); } @@ -252,6 +254,8 @@ vm_object_reference_locked(vm_object_t object) { if (object) { ASSERT_LWKT_TOKEN_HELD(&vmobj_token); + /*NOTYET*/ + /*ASSERT_LWKT_TOKEN_HELD(vm_object_token(object));*/ object->ref_count++; if (object->type == OBJT_VNODE) { vref(object->handle); @@ -1866,6 +1870,9 @@ vm_object_unlock(vm_object_t obj) void vm_object_hold(vm_object_t obj) { + if (obj == NULL) + return; + vm_object_lock(obj); refcount_acquire(&obj->hold_count); @@ -1889,6 +1896,9 @@ vm_object_drop(vm_object_t obj) { int rc; + if (obj == NULL) + return; + #if defined(DEBUG_LOCKS) int found = 0; int i; diff --git a/sys/vm/vm_object.h b/sys/vm/vm_object.h index a0c1650f92..c94748800c 100644 --- a/sys/vm/vm_object.h +++ b/sys/vm/vm_object.h @@ -274,6 +274,10 @@ vm_object_pip_wait(vm_object_t object, char *waitid) vm_object_pip_sleep(object, waitid); } +static inline lwkt_token_t vm_object_token(vm_object_t obj) { + return (lwkt_token_pool_lookup(obj)); +} + vm_object_t vm_object_allocate (objtype_t, vm_pindex_t); void _vm_object_allocate (objtype_t, vm_pindex_t, vm_object_t); boolean_t vm_object_coalesce (vm_object_t, vm_pindex_t, vm_size_t, vm_size_t); diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c index 6be7dd63a5..d5bb3df17f 100644 --- a/sys/vm/vnode_pager.c +++ b/sys/vm/vnode_pager.c @@ -835,7 +835,7 @@ vnode_pager_lock(vm_object_t object) struct thread *td = curthread; /* XXX */ int error; - ASSERT_LWKT_TOKEN_HELD(&vm_token); + ASSERT_LWKT_TOKEN_HELD(vm_object_token(object)); for (; object != NULL; object = object->backing_object) { if (object->type != OBJT_VNODE) -- 2.41.0