summaryrefslogtreecommitdiffstats
path: root/sys/vm/phys_pager.c
diff options
context:
space:
mode:
authoralfred <alfred@FreeBSD.org>2001-04-18 20:24:16 +0000
committeralfred <alfred@FreeBSD.org>2001-04-18 20:24:16 +0000
commite6ee97803e2e4bc2318d05d375cfafd22d4bc79c (patch)
tree7072bae86e21b8fd82f2551d60eae00feb42d142 /sys/vm/phys_pager.c
parent82131f7a660dcea81c8a5ab014109eabe6919132 (diff)
downloadFreeBSD-src-e6ee97803e2e4bc2318d05d375cfafd22d4bc79c.zip
FreeBSD-src-e6ee97803e2e4bc2318d05d375cfafd22d4bc79c.tar.gz
Protect pager object creation with sx locks.
Protect pager object list manipulation with a mutex. It doesn't look possible to combine them under a single sx lock because creation may block and we can't have the object list manipulation block on anything other than a mutex because of interrupt requests.
Diffstat (limited to 'sys/vm/phys_pager.c')
-rw-r--r--sys/vm/phys_pager.c28
1 files changed, 16 insertions, 12 deletions
diff --git a/sys/vm/phys_pager.c b/sys/vm/phys_pager.c
index 6e710b2..5a6aca5 100644
--- a/sys/vm/phys_pager.c
+++ b/sys/vm/phys_pager.c
@@ -29,8 +29,10 @@
#include <sys/systm.h>
#include <sys/linker_set.h>
#include <sys/conf.h>
+#include <sys/kernel.h>
#include <sys/mman.h>
#include <sys/sysctl.h>
+#include <sys/sx.h>
#include <vm/vm.h>
#include <vm/vm_object.h>
@@ -38,16 +40,20 @@
#include <vm/vm_pager.h>
#include <vm/vm_zone.h>
+/* prevent concurrant creation races */
+static struct sx phys_pager_sx;
/* list of device pager objects */
static struct pagerlst phys_pager_object_list;
-
-static int phys_pager_alloc_lock, phys_pager_alloc_lock_want;
+/* protect access to phys_pager_object_list */
+static struct mtx phys_pager_mtx;
static void
phys_pager_init(void)
{
TAILQ_INIT(&phys_pager_object_list);
+ sx_init(&phys_pager_sx, "phys_pager create");
+ mtx_init(&phys_pager_mtx, "phys_pager list", MTX_DEF);
}
static vm_object_t
@@ -68,12 +74,7 @@ phys_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot,
/*
* 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;
+ sx_xlock(&phys_pager_sx);
/*
* Look up pager, creating as necessary.
@@ -86,8 +87,10 @@ phys_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot,
object = vm_object_allocate(OBJT_PHYS,
OFF_TO_IDX(foff + size));
object->handle = handle;
+ mtx_lock(&phys_pager_mtx);
TAILQ_INSERT_TAIL(&phys_pager_object_list, object,
pager_object_list);
+ mtx_unlock(&phys_pager_mtx);
} else {
/*
* Gain a reference to the object.
@@ -96,9 +99,7 @@ phys_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot,
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);
+ sx_xunlock(&phys_pager_sx);
} else {
object = vm_object_allocate(OBJT_PHYS,
OFF_TO_IDX(foff + size));
@@ -111,8 +112,11 @@ static void
phys_pager_dealloc(vm_object_t object)
{
- if (object->handle != NULL)
+ if (object->handle != NULL) {
+ mtx_lock(&phys_pager_mtx);
TAILQ_REMOVE(&phys_pager_object_list, object, pager_object_list);
+ mtx_unlock(&phys_pager_mtx);
+ }
}
static int
OpenPOWER on IntegriCloud