Fix the phys_pager in the way similar to the rev. 1.83 of the
sys/vm/device_pager.c: Protect the creation of the phys pager with non-NULL handle with the phys_pager_mtx. Lookup of phys pager in the pagers list by handle is now synchronized with its removal from the list, and phys_pager_mtx is put before vm object lock in lock order. Dispose the phys_pager_alloc_lock and tsleep calls, together with acquiring Giant, since phys_pager_mtx now covers the same block. Reviewed by: alc Approved by: re (kensmith)
This commit is contained in:
parent
c58bdad9f2
commit
ba6ef6ecca
@ -42,8 +42,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <vm/vm_page.h>
|
||||
#include <vm/vm_pager.h>
|
||||
|
||||
/* prevent concurrent creation races */
|
||||
static int phys_pager_alloc_lock;
|
||||
/* list of device pager objects */
|
||||
static struct pagerlst phys_pager_object_list;
|
||||
/* protect access to phys_pager_object_list */
|
||||
@ -64,7 +62,7 @@ static vm_object_t
|
||||
phys_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot,
|
||||
vm_ooffset_t foff)
|
||||
{
|
||||
vm_object_t object;
|
||||
vm_object_t object, object1;
|
||||
vm_pindex_t pindex;
|
||||
|
||||
/*
|
||||
@ -76,38 +74,41 @@ phys_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot,
|
||||
pindex = OFF_TO_IDX(foff + PAGE_MASK + size);
|
||||
|
||||
if (handle != NULL) {
|
||||
mtx_lock(&Giant);
|
||||
/*
|
||||
* Lock to prevent object creation race condition.
|
||||
*/
|
||||
while (phys_pager_alloc_lock) {
|
||||
phys_pager_alloc_lock = -1;
|
||||
tsleep(&phys_pager_alloc_lock, PVM, "swpalc", 0);
|
||||
}
|
||||
phys_pager_alloc_lock = 1;
|
||||
|
||||
mtx_lock(&phys_pager_mtx);
|
||||
/*
|
||||
* Look up pager, creating as necessary.
|
||||
*/
|
||||
object1 = NULL;
|
||||
object = vm_pager_object_lookup(&phys_pager_object_list, handle);
|
||||
if (object == NULL) {
|
||||
/*
|
||||
* Allocate object and associate it with the pager.
|
||||
*/
|
||||
object = vm_object_allocate(OBJT_PHYS, pindex);
|
||||
object->handle = handle;
|
||||
mtx_lock(&phys_pager_mtx);
|
||||
TAILQ_INSERT_TAIL(&phys_pager_object_list, object,
|
||||
pager_object_list);
|
||||
mtx_unlock(&phys_pager_mtx);
|
||||
object1 = vm_object_allocate(OBJT_PHYS, pindex);
|
||||
mtx_lock(&phys_pager_mtx);
|
||||
object = vm_pager_object_lookup(&phys_pager_object_list,
|
||||
handle);
|
||||
if (object != NULL) {
|
||||
/*
|
||||
* We raced with other thread while
|
||||
* allocating object.
|
||||
*/
|
||||
if (pindex > object->size)
|
||||
object->size = pindex;
|
||||
} else {
|
||||
object = object1;
|
||||
object1 = NULL;
|
||||
object->handle = handle;
|
||||
TAILQ_INSERT_TAIL(&phys_pager_object_list, object,
|
||||
pager_object_list);
|
||||
}
|
||||
} else {
|
||||
if (pindex > object->size)
|
||||
object->size = pindex;
|
||||
}
|
||||
if (phys_pager_alloc_lock == -1)
|
||||
wakeup(&phys_pager_alloc_lock);
|
||||
phys_pager_alloc_lock = 0;
|
||||
mtx_unlock(&Giant);
|
||||
mtx_unlock(&phys_pager_mtx);
|
||||
vm_object_deallocate(object1);
|
||||
} else {
|
||||
object = vm_object_allocate(OBJT_PHYS, pindex);
|
||||
}
|
||||
@ -123,9 +124,11 @@ phys_pager_dealloc(vm_object_t object)
|
||||
{
|
||||
|
||||
if (object->handle != NULL) {
|
||||
VM_OBJECT_UNLOCK(object);
|
||||
mtx_lock(&phys_pager_mtx);
|
||||
TAILQ_REMOVE(&phys_pager_object_list, object, pager_object_list);
|
||||
mtx_unlock(&phys_pager_mtx);
|
||||
VM_OBJECT_LOCK(object);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user