kernel - Fix shared/excl livelock with vm.shared_fault
authorMatthew Dillon <dillon@apollo.backplane.com>
Tue, 26 Feb 2013 03:27:05 +0000 (19:27 -0800)
committerMatthew Dillon <dillon@apollo.backplane.com>
Tue, 26 Feb 2013 03:27:05 +0000 (19:27 -0800)
* The vop_helper_read_shortcut() code was holding a shared token on
  a VM object through a uiomove().  If the uiomove() generated a VM
  fault requiring a shadow copy, the shadow copy would try to get
  an exclusive token on potentially the same object and livelock.

* Fix by unlocking/relocking across the uiomove().

sys/kern/vfs_helper.c

index bf62f9d..0d351eb 100644 (file)
@@ -371,7 +371,16 @@ vop_helper_read_shortcut(struct vop_read_args *ap)
                        break;
                }
                lwb = lwbuf_alloc(m, &lwb_cache);
+
+               /*
+                * Can't hold object across uiomove, a VM fault could
+                * wind up live locking on the same object (one shared,
+                * on exclusive).
+                */
+               vm_object_drop(obj);
                error = uiomove((char *)lwbuf_kva(lwb) + offset, n, uio);
+               vm_object_hold_shared(obj);
+
                vm_page_flag_set(m, PG_REFERENCED);
                lwbuf_free(lwb);
                vm_page_wakeup(m);