diff options
| author | Konstantin Belousov <kib@FreeBSD.org> | 2007-08-07 15:36:25 +0000 |
|---|---|---|
| committer | Konstantin Belousov <kib@FreeBSD.org> | 2007-08-07 15:36:25 +0000 |
| commit | deea654ebfd5fdbb803ccda0077aeb64d9cf3f54 (patch) | |
| tree | bd215a18467b2f34de98aec0553cf0ac7408ddbc /sys/vm | |
| parent | 5a5ee8cb1efe5341b26175e670e37f4fa83c1881 (diff) | |
Notes
Diffstat (limited to 'sys/vm')
| -rw-r--r-- | sys/vm/device_pager.c | 36 |
1 files changed, 24 insertions, 12 deletions
diff --git a/sys/vm/device_pager.c b/sys/vm/device_pager.c index bbca5cc9ee08..e557082d3763 100644 --- a/sys/vm/device_pager.c +++ b/sys/vm/device_pager.c @@ -64,8 +64,6 @@ static boolean_t dev_pager_haspage(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; @@ -89,7 +87,6 @@ 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", NULL, MTX_DEF); fakepg_zone = uma_zcreate("DP fakepg", sizeof(struct vm_page), NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, @@ -103,7 +100,7 @@ static vm_object_t dev_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot, vm_ooffset_t foff) { struct cdev *dev; - vm_object_t object; + vm_object_t object, object1; vm_pindex_t pindex; unsigned int npages; vm_paddr_t paddr; @@ -143,29 +140,42 @@ dev_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot, vm_ooffset_t fo /* * Lock to prevent object creation race condition. */ - sx_xlock(&dev_pager_sx); + mtx_lock(&dev_pager_mtx); /* * Look up pager, creating as necessary. */ + object1 = NULL; object = vm_pager_object_lookup(&dev_pager_object_list, handle); if (object == NULL) { /* * Allocate object and associate it with the pager. */ - object = vm_object_allocate(OBJT_DEVICE, pindex); - 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); + object1 = vm_object_allocate(OBJT_DEVICE, pindex); + mtx_lock(&dev_pager_mtx); + object = vm_pager_object_lookup(&dev_pager_object_list, handle); + if (object != NULL) { + /* + * We raced with other thread while allocating object. + */ + if (pindex > object->size) + object->size = pindex; + } else { + object = object1; + object1 = NULL; + object->handle = handle; + TAILQ_INIT(&object->un_pager.devp.devp_pglist); + TAILQ_INSERT_TAIL(&dev_pager_object_list, object, + pager_object_list); + } } else { if (pindex > object->size) object->size = pindex; } - - sx_xunlock(&dev_pager_sx); + mtx_unlock(&dev_pager_mtx); dev_relthread(dev); + vm_object_deallocate(object1); return (object); } @@ -175,9 +185,11 @@ dev_pager_dealloc(object) { vm_page_t m; + VM_OBJECT_UNLOCK(object); mtx_lock(&dev_pager_mtx); TAILQ_REMOVE(&dev_pager_object_list, object, pager_object_list); mtx_unlock(&dev_pager_mtx); + VM_OBJECT_LOCK(object); /* * Free up our fake pages. */ |
