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/device_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/device_pager.c')
-rw-r--r-- | sys/vm/device_pager.c | 25 |
1 files changed, 14 insertions, 11 deletions
diff --git a/sys/vm/device_pager.c b/sys/vm/device_pager.c index 85cad81..7d7480c 100644 --- a/sys/vm/device_pager.c +++ b/sys/vm/device_pager.c @@ -43,6 +43,7 @@ #include <sys/systm.h> #include <sys/conf.h> #include <sys/mman.h> +#include <sys/sx.h> #include <vm/vm.h> #include <vm/vm_object.h> @@ -62,6 +63,11 @@ static boolean_t dev_pager_haspage __P((vm_object_t, vm_pindex_t, int *, /* list of device pager objects */ static struct pagerlst dev_pager_object_list; +/* protect against object creation */ +static struct sx dev_pager_sx; +/* protect list manipulation */ +static struct mtx dev_pager_mtx; + static vm_zone_t fakepg_zone; static struct vm_zone fakepg_zone_store; @@ -69,8 +75,6 @@ static struct vm_zone fakepg_zone_store; static vm_page_t dev_pager_getfake __P((vm_offset_t)); static void dev_pager_putfake __P((vm_page_t)); -static int dev_pager_alloc_lock, dev_pager_alloc_lock_want; - struct pagerops devicepagerops = { dev_pager_init, dev_pager_alloc, @@ -85,6 +89,8 @@ static void dev_pager_init() { TAILQ_INIT(&dev_pager_object_list); + sx_init(&dev_pager_sx, "dev_pager create"); + mtx_init(&dev_pager_mtx, "dev_pager list", MTX_DEF); fakepg_zone = &fakepg_zone_store; zinitna(fakepg_zone, NULL, "DP fakepg", sizeof(struct vm_page), 0, 0, 2); } @@ -130,12 +136,7 @@ dev_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot, vm_ooffset_t fo /* * Lock to prevent object creation race condition. */ - while (dev_pager_alloc_lock) { - dev_pager_alloc_lock_want++; - tsleep(&dev_pager_alloc_lock, PVM, "dvpall", 0); - dev_pager_alloc_lock_want--; - } - dev_pager_alloc_lock = 1; + sx_xlock(&dev_pager_sx); /* * Look up pager, creating as necessary. @@ -149,7 +150,9 @@ dev_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot, vm_ooffset_t fo OFF_TO_IDX(foff + size)); object->handle = handle; TAILQ_INIT(&object->un_pager.devp.devp_pglist); + mtx_lock(&dev_pager_mtx); TAILQ_INSERT_TAIL(&dev_pager_object_list, object, pager_object_list); + mtx_unlock(&dev_pager_mtx); } else { /* * Gain a reference to the object. @@ -159,9 +162,7 @@ dev_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot, vm_ooffset_t fo object->size = OFF_TO_IDX(foff + size); } - dev_pager_alloc_lock = 0; - if (dev_pager_alloc_lock_want) - wakeup(&dev_pager_alloc_lock); + sx_xunlock(&dev_pager_sx); return (object); } @@ -172,7 +173,9 @@ dev_pager_dealloc(object) { vm_page_t m; + mtx_lock(&dev_pager_mtx); TAILQ_REMOVE(&dev_pager_object_list, object, pager_object_list); + mtx_unlock(&dev_pager_mtx); /* * Free up our fake pages. */ |