summaryrefslogtreecommitdiffstats
path: root/sys/vm
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2010-08-06 09:42:15 +0000
committerkib <kib@FreeBSD.org>2010-08-06 09:42:15 +0000
commitba7ee96f4acc27c8c70a4af6c81be42c4856619f (patch)
tree7da521a717547b550e58c94609d3078b5dd9e826 /sys/vm
parentc3d4f0835cad384499298be886c0a8afc90d5822 (diff)
downloadFreeBSD-src-ba7ee96f4acc27c8c70a4af6c81be42c4856619f.zip
FreeBSD-src-ba7ee96f4acc27c8c70a4af6c81be42c4856619f.tar.gz
Add new make_dev_p(9) flag MAKEDEV_ETERNAL to inform devfs that created
cdev will never be destroyed. Propagate the flag to devfs vnodes as VV_ETERNVALDEV. Use the flags to avoid acquiring devmtx and taking a thread reference on such nodes. In collaboration with: pho MFC after: 1 month
Diffstat (limited to 'sys/vm')
-rw-r--r--sys/vm/device_pager.c13
-rw-r--r--sys/vm/vm_mmap.c14
2 files changed, 14 insertions, 13 deletions
diff --git a/sys/vm/device_pager.c b/sys/vm/device_pager.c
index 7d8d361..c7eab1d 100644
--- a/sys/vm/device_pager.c
+++ b/sys/vm/device_pager.c
@@ -108,6 +108,7 @@ dev_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot,
vm_ooffset_t off;
vm_memattr_t dummy;
struct cdevsw *csw;
+ int ref;
/*
* Offset should be page aligned.
@@ -122,7 +123,7 @@ dev_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot,
* Make sure this device can be mapped.
*/
dev = handle;
- csw = dev_refthread(dev);
+ csw = dev_refthread(dev, &ref);
if (csw == NULL)
return (NULL);
@@ -135,7 +136,7 @@ dev_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot,
npages = OFF_TO_IDX(size);
for (off = foff; npages--; off += PAGE_SIZE)
if (csw->d_mmap(dev, off, &paddr, (int)prot, &dummy) != 0) {
- dev_relthread(dev);
+ dev_relthread(dev, ref);
return (NULL);
}
@@ -177,7 +178,7 @@ dev_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot,
object->size = pindex;
}
mtx_unlock(&dev_pager_mtx);
- dev_relthread(dev);
+ dev_relthread(dev, ref);
vm_object_deallocate(object1);
return (object);
}
@@ -214,7 +215,7 @@ dev_pager_getpages(object, m, count, reqpage)
vm_page_t m_paddr, page;
vm_memattr_t memattr;
struct cdev *dev;
- int i, ret;
+ int i, ref, ret;
struct cdevsw *csw;
struct thread *td;
struct file *fpop;
@@ -225,7 +226,7 @@ dev_pager_getpages(object, m, count, reqpage)
offset = page->pindex;
memattr = object->memattr;
VM_OBJECT_UNLOCK(object);
- csw = dev_refthread(dev);
+ csw = dev_refthread(dev, &ref);
if (csw == NULL)
panic("dev_pager_getpage: no cdevsw");
td = curthread;
@@ -235,7 +236,7 @@ dev_pager_getpages(object, m, count, reqpage)
PROT_READ, &memattr);
KASSERT(ret == 0, ("dev_pager_getpage: map function returns error"));
td->td_fpop = fpop;
- dev_relthread(dev);
+ dev_relthread(dev, ref);
/* If "paddr" is a real page, perform a sanity check on "memattr". */
if ((m_paddr = vm_phys_paddr_to_vm_page(paddr)) != NULL &&
pmap_page_get_memattr(m_paddr) != memattr) {
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c
index 999a481..bd9f98f 100644
--- a/sys/vm/vm_mmap.c
+++ b/sys/vm/vm_mmap.c
@@ -1292,15 +1292,15 @@ vm_mmap_cdev(struct thread *td, vm_size_t objsize,
{
vm_object_t obj;
struct cdevsw *dsw;
- int error, flags;
+ int error, flags, ref;
flags = *flagsp;
- dsw = dev_refthread(cdev);
+ dsw = dev_refthread(cdev, &ref);
if (dsw == NULL)
return (ENXIO);
if (dsw->d_flags & D_MMAP_ANON) {
- dev_relthread(cdev);
+ dev_relthread(cdev, ref);
*maxprotp = VM_PROT_ALL;
*flagsp |= MAP_ANON;
return (0);
@@ -1310,11 +1310,11 @@ vm_mmap_cdev(struct thread *td, vm_size_t objsize,
*/
if ((*maxprotp & VM_PROT_WRITE) == 0 &&
(prot & PROT_WRITE) != 0) {
- dev_relthread(cdev);
+ dev_relthread(cdev, ref);
return (EACCES);
}
if (flags & (MAP_PRIVATE|MAP_COPY)) {
- dev_relthread(cdev);
+ dev_relthread(cdev, ref);
return (EINVAL);
}
/*
@@ -1324,7 +1324,7 @@ vm_mmap_cdev(struct thread *td, vm_size_t objsize,
#ifdef MAC_XXX
error = mac_cdev_check_mmap(td->td_ucred, cdev, prot);
if (error != 0) {
- dev_relthread(cdev);
+ dev_relthread(cdev, ref);
return (error);
}
#endif
@@ -1338,7 +1338,7 @@ vm_mmap_cdev(struct thread *td, vm_size_t objsize,
* XXX assumes VM_PROT_* == PROT_*
*/
error = dsw->d_mmap_single(cdev, foff, objsize, objp, (int)prot);
- dev_relthread(cdev);
+ dev_relthread(cdev, ref);
if (error != ENODEV)
return (error);
obj = vm_pager_allocate(OBJT_DEVICE, cdev, objsize, prot, *foff,
OpenPOWER on IntegriCloud