diff options
author | alfred <alfred@FreeBSD.org> | 2000-12-06 21:52:23 +0000 |
---|---|---|
committer | alfred <alfred@FreeBSD.org> | 2000-12-06 21:52:23 +0000 |
commit | 012cf93dca4f03d0bb1879fb9308a0476262d6d9 (patch) | |
tree | d42ef46c3b3c582d88af688644462a86f72f9b5d /sys/vm/phys_pager.c | |
parent | 978bf0288dcc63cbf07834a158c164d4cee393ca (diff) | |
download | FreeBSD-src-012cf93dca4f03d0bb1879fb9308a0476262d6d9.zip FreeBSD-src-012cf93dca4f03d0bb1879fb9308a0476262d6d9.tar.gz |
Really fix phys_pager:
Backout the previous delta (rev 1.4), it didn't make any difference.
If the requested handle is NULL then don't add it to the list of
objects, to be found by handle.
The problem is that when asking for a NULL handle you are implying
you want a new object. Because objects with NULL handles were
being added to the list, any further requests for phys backed
objects with NULL handles would return a reference to the initial
NULL handle object after finding it on the list.
Basically one couldn't have more than one phys backed object without
a handle in the entire system without this fix. If you did more
than one shared memory allocation using the phys pager it would
give you your initial allocation again.
Diffstat (limited to 'sys/vm/phys_pager.c')
-rw-r--r-- | sys/vm/phys_pager.c | 67 |
1 files changed, 36 insertions, 31 deletions
diff --git a/sys/vm/phys_pager.c b/sys/vm/phys_pager.c index 153dd2f..6e710b2 100644 --- a/sys/vm/phys_pager.c +++ b/sys/vm/phys_pager.c @@ -64,42 +64,46 @@ phys_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot, size = round_page(size); - /* - * Lock to prevent object creation race condition. - */ - while (phys_pager_alloc_lock) { - phys_pager_alloc_lock_want++; - tsleep(&phys_pager_alloc_lock, PVM, "ppall", 0); - phys_pager_alloc_lock_want--; - } - phys_pager_alloc_lock = 1; - - /* - * Look up pager, creating as necessary. - */ - object = vm_pager_object_lookup(&phys_pager_object_list, handle); - if (object == NULL) { + if (handle != NULL) { /* - * Allocate object and associate it with the pager. + * Lock to prevent object creation race condition. */ - object = vm_object_allocate(OBJT_PHYS, - OFF_TO_IDX(foff + PAGE_MASK + size)); - object->handle = handle; - TAILQ_INSERT_TAIL(&phys_pager_object_list, object, - pager_object_list); - } else { + while (phys_pager_alloc_lock) { + phys_pager_alloc_lock_want++; + tsleep(&phys_pager_alloc_lock, PVM, "ppall", 0); + phys_pager_alloc_lock_want--; + } + phys_pager_alloc_lock = 1; + /* - * Gain a reference to the object. + * Look up pager, creating as necessary. */ - vm_object_reference(object); - if (OFF_TO_IDX(foff + size) > object->size) - object->size = OFF_TO_IDX(foff + size); + 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, + OFF_TO_IDX(foff + size)); + object->handle = handle; + TAILQ_INSERT_TAIL(&phys_pager_object_list, object, + pager_object_list); + } else { + /* + * Gain a reference to the object. + */ + vm_object_reference(object); + if (OFF_TO_IDX(foff + size) > object->size) + object->size = OFF_TO_IDX(foff + size); + } + phys_pager_alloc_lock = 0; + if (phys_pager_alloc_lock_want) + wakeup(&phys_pager_alloc_lock); + } else { + object = vm_object_allocate(OBJT_PHYS, + OFF_TO_IDX(foff + size)); } - phys_pager_alloc_lock = 0; - if (phys_pager_alloc_lock_want) - wakeup(&phys_pager_alloc_lock); - return (object); } @@ -107,7 +111,8 @@ static void phys_pager_dealloc(vm_object_t object) { - TAILQ_REMOVE(&phys_pager_object_list, object, pager_object_list); + if (object->handle != NULL) + TAILQ_REMOVE(&phys_pager_object_list, object, pager_object_list); } static int |