diff options
author | Konstantin Belousov <kib@FreeBSD.org> | 2007-08-18 16:40:33 +0000 |
---|---|---|
committer | Konstantin Belousov <kib@FreeBSD.org> | 2007-08-18 16:40:33 +0000 |
commit | efe7553ed7aa65e6b241d4159ec560c22ac94ff1 (patch) | |
tree | 8d3069975564b76f59783f6cab8fa5fed278be76 | |
parent | 11eeea5e850bceab1705a242dd9f37182190ab2b (diff) |
Notes
-rw-r--r-- | sys/vm/phys_pager.c | 47 |
1 files changed, 25 insertions, 22 deletions
diff --git a/sys/vm/phys_pager.c b/sys/vm/phys_pager.c index 626e888f42c9..c699b8f4189e 100644 --- a/sys/vm/phys_pager.c +++ b/sys/vm/phys_pager.c @@ -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); } } |