Author: kib
Date: Sat Jul 30 14:13:57 2011
New Revision: 224522
URL: http://svn.freebsd.org/changeset/base/224522

Log:
  Fix a race in the device pager allocation. If another thread won and
  allocated the device pager for the given handle, then the object
  fictitious pages list and the object membership in the global object
  list still need to be initialized. Otherwise, dev_pager_dealloc() will
  traverse uninitialized pointers.
  
  Reported and tested by: pho
  Reviewed by:    jhb
  Approved by:  re (kensmith)
  MFC after:      1 week

Modified:
  head/sys/vm/device_pager.c

Modified: head/sys/vm/device_pager.c
==============================================================================
--- head/sys/vm/device_pager.c  Sat Jul 30 14:12:37 2011        (r224521)
+++ head/sys/vm/device_pager.c  Sat Jul 30 14:13:57 2011        (r224522)
@@ -147,6 +147,7 @@ dev_pager_alloc(void *handle, vm_ooffset
                object1 = vm_object_allocate(OBJT_DEVICE, pindex);
                object1->flags |= OBJ_COLORED;
                object1->pg_color = atop(paddr) - OFF_TO_IDX(off - PAGE_SIZE);
+               TAILQ_INIT(&object1->un_pager.devp.devp_pglist);
                mtx_lock(&dev_pager_mtx);
                object = vm_pager_object_lookup(&dev_pager_object_list, handle);
                if (object != NULL) {
@@ -159,7 +160,6 @@ dev_pager_alloc(void *handle, vm_ooffset
                        object = object1;
                        object1 = NULL;
                        object->handle = handle;
-                       TAILQ_INIT(&object->un_pager.devp.devp_pglist);
                        TAILQ_INSERT_TAIL(&dev_pager_object_list, object,
                            pager_object_list);
                }
@@ -169,7 +169,14 @@ dev_pager_alloc(void *handle, vm_ooffset
        }
        mtx_unlock(&dev_pager_mtx);
        dev_relthread(dev, ref);
-       vm_object_deallocate(object1);
+       if (object1 != NULL) {
+               object1->handle = object1;
+               mtx_lock(&dev_pager_mtx);
+               TAILQ_INSERT_TAIL(&dev_pager_object_list, object1,
+                   pager_object_list);
+               mtx_unlock(&dev_pager_mtx);
+               vm_object_deallocate(object1);
+       }
        return (object);
 }
 
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to