diff options
author | jhb <jhb@FreeBSD.org> | 2009-08-28 14:06:55 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2009-08-28 14:06:55 +0000 |
commit | 7b069e86c6dbd397d4d622acf8c924f2ade8127d (patch) | |
tree | 90a42d70408be865b0d3f244445d7106ff89a054 /sys/vm | |
parent | b546d1fee4837a126b1e940e542b8d9ff2132bc6 (diff) | |
download | FreeBSD-src-7b069e86c6dbd397d4d622acf8c924f2ade8127d.zip FreeBSD-src-7b069e86c6dbd397d4d622acf8c924f2ade8127d.tar.gz |
Extend the device pager to support different memory attributes on different
pages in an object.
- Add a new variant of d_mmap() currently called d_mmap2() which accepts
an additional in/out parameter that is the memory attribute to use for
the requested page.
- A driver either uses d_mmap() or d_mmap2() for all requests but not both.
The current implementation uses a flag in the cdevsw (D_MMAP2) to indicate
that the driver provides a d_mmap2() handler instead of d_mmap(). This
is done to make the change ABI compatible with existing drivers and
MFC'able to 7 and 8.
Submitted by: alc
MFC after: 1 month
Diffstat (limited to 'sys/vm')
-rw-r--r-- | sys/vm/device_pager.c | 20 | ||||
-rw-r--r-- | sys/vm/vm.h | 12 |
2 files changed, 21 insertions, 11 deletions
diff --git a/sys/vm/device_pager.c b/sys/vm/device_pager.c index 0d762de..c7f5593 100644 --- a/sys/vm/device_pager.c +++ b/sys/vm/device_pager.c @@ -93,6 +93,17 @@ dev_pager_init() UMA_ZONE_NOFREE|UMA_ZONE_VM); } +static __inline int +dev_mmap(struct cdevsw *csw, struct cdev *dev, vm_offset_t offset, + vm_paddr_t *paddr, int nprot, vm_memattr_t *memattr) +{ + + if (csw->d_flags & D_MMAP2) + return (csw->d_mmap2(dev, offset, paddr, nprot, memattr)); + else + return (csw->d_mmap(dev, offset, paddr, nprot)); +} + /* * MPSAFE */ @@ -106,6 +117,7 @@ dev_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot, unsigned int npages; vm_paddr_t paddr; vm_offset_t off; + vm_memattr_t dummy; struct cdevsw *csw; /* @@ -133,7 +145,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) != 0) { + if (dev_mmap(csw, dev, off, &paddr, (int)prot, &dummy) != 0) { dev_relthread(dev); return (NULL); } @@ -214,7 +226,6 @@ dev_pager_getpages(object, m, count, reqpage) vm_memattr_t memattr; struct cdev *dev; int i, ret; - int prot; struct cdevsw *csw; struct thread *td; struct file *fpop; @@ -228,12 +239,11 @@ dev_pager_getpages(object, m, count, reqpage) csw = dev_refthread(dev); if (csw == NULL) panic("dev_pager_getpage: no cdevsw"); - prot = PROT_READ; /* XXX should pass in? */ - td = curthread; fpop = td->td_fpop; td->td_fpop = NULL; - ret = (*csw->d_mmap)(dev, (vm_offset_t)offset << PAGE_SHIFT, &paddr, prot); + ret = dev_mmap(csw, dev, (vm_offset_t)offset << PAGE_SHIFT, &paddr, + PROT_READ, &memattr); KASSERT(ret == 0, ("dev_pager_getpage: map function returns error")); td->td_fpop = fpop; dev_relthread(dev); diff --git a/sys/vm/vm.h b/sys/vm/vm.h index b547514..941300a 100644 --- a/sys/vm/vm.h +++ b/sys/vm/vm.h @@ -63,12 +63,6 @@ #include <machine/vm.h> -/* - * The exact set of memory attributes is machine dependent. However, every - * machine is required to define VM_MEMATTR_DEFAULT. - */ -typedef char vm_memattr_t; /* memory attribute codes */ - typedef char vm_inherit_t; /* inheritance codes */ #define VM_INHERIT_SHARE ((vm_inherit_t) 0) @@ -115,6 +109,12 @@ typedef struct vm_object *vm_object_t; typedef int boolean_t; /* + * The exact set of memory attributes is machine dependent. However, every + * machine is required to define VM_MEMATTR_DEFAULT. + */ +typedef char vm_memattr_t; /* memory attribute codes */ + +/* * This is defined in <sys/types.h> for the kernel so that vnode_if.h * doesn't have to include <vm/vm.h>. */ |