diff options
author | alfred <alfred@FreeBSD.org> | 2001-04-18 20:24:16 +0000 |
---|---|---|
committer | alfred <alfred@FreeBSD.org> | 2001-04-18 20:24:16 +0000 |
commit | e6ee97803e2e4bc2318d05d375cfafd22d4bc79c (patch) | |
tree | 7072bae86e21b8fd82f2551d60eae00feb42d142 /sys/vm/phys_pager.c | |
parent | 82131f7a660dcea81c8a5ab014109eabe6919132 (diff) | |
download | FreeBSD-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.c | 28 |
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 |