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
This commit is contained in:
Konstantin Belousov 2011-07-30 14:13:57 +00:00
parent 889dffba25
commit 339772b003

View File

@ -147,6 +147,7 @@ dev_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot,
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_t size, vm_prot_t prot,
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_t size, vm_prot_t prot,
}
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);
}