summaryrefslogtreecommitdiffstats
path: root/sys/vm/phys_pager.c
diff options
context:
space:
mode:
authoralfred <alfred@FreeBSD.org>2000-12-06 21:52:23 +0000
committeralfred <alfred@FreeBSD.org>2000-12-06 21:52:23 +0000
commit012cf93dca4f03d0bb1879fb9308a0476262d6d9 (patch)
treed42ef46c3b3c582d88af688644462a86f72f9b5d /sys/vm/phys_pager.c
parent978bf0288dcc63cbf07834a158c164d4cee393ca (diff)
downloadFreeBSD-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.c67
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
OpenPOWER on IntegriCloud