PERFORCE change 91261 for review
John Baldwin
jhb at FreeBSD.org
Mon Feb 6 13:41:35 PST 2006
http://perforce.freebsd.org/chv.cgi?CH=91261
Change 91261 by jhb at jhb_slimer on 2006/02/06 21:40:31
Save this fix for a race condition here until Kris can test it to
verify that it works.
Reviewed by: alc
Affected files ...
.. //depot/projects/smpng/sys/vm/vm_object.c#77 edit
Differences ...
==== //depot/projects/smpng/sys/vm/vm_object.c#77 (text+ko) ====
@@ -438,23 +438,37 @@
while (object != NULL) {
int vfslocked;
- /*
- * In general, the object should be locked when working with
- * its type. In this case, in order to maintain proper lock
- * ordering, an exception is possible because a vnode-backed
- * object never changes its type.
- */
+
vfslocked = 0;
+ restart:
+ VM_OBJECT_LOCK(object);
if (object->type == OBJT_VNODE) {
struct vnode *vp = (struct vnode *) object->handle;
- vfslocked = VFS_LOCK_GIANT(vp->v_mount);
- }
- VM_OBJECT_LOCK(object);
- if (object->type == OBJT_VNODE) {
+
+ /*
+ * Conditionally acquire Giant for a vnode-backed
+ * object. We have to be careful since the type of
+ * a vnode object can change while the object is
+ * unlocked.
+ */
+ if (VFS_NEEDSGIANT(vp->v_mount) && !vfslocked) {
+ vfslocked = 1;
+ if (!mtx_trylock(&Giant)) {
+ VM_OBJECT_UNLOCK(object);
+ mtx_lock(&Giant);
+ goto restart;
+ }
+ }
vm_object_vndeallocate(object);
VFS_UNLOCK_GIANT(vfslocked);
return;
- }
+ } else
+ /*
+ * This is to handle the case that the object
+ * changed type while we dropped its lock to
+ * obtain Giant.
+ */
+ VFS_UNLOCK_GIANT(vfslocked);
KASSERT(object->ref_count != 0,
("vm_object_deallocate: object deallocated too many times: %d", object->type));
More information about the p4-projects
mailing list