kernel -- vm_object locking: Interlock vm_object work in vm_fault.c
authorVenkatesh Srinivas <me@endeavour.zapto.org>
Tue, 7 Jun 2011 20:13:34 +0000 (13:13 -0700)
committerVenkatesh Srinivas <me@endeavour.zapto.org>
Tue, 7 Jun 2011 20:13:34 +0000 (13:13 -0700)
and vm_map.c with per-object token. Handle NULL objects for _hold and _drop.

sys/vm/vm_fault.c
sys/vm/vm_map.c
sys/vm/vm_object.c
sys/vm/vm_object.h
sys/vm/vnode_pager.c

index 5c621db..b98dd11 100644 (file)
@@ -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;
index 10224f6..def6815 100644 (file)
@@ -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);
 
index c35988a..8f9bb36 100644 (file)
@@ -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;
index a0c1650..c947488 100644 (file)
@@ -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);
index 6be7dd6..d5bb3df 100644 (file)
@@ -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)