Date: Fri, 28 Aug 2009 14:06:56 +0000 (UTC) From: John Baldwin <jhb@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r196615 - in head/sys: kern sys vm Message-ID: <200908281406.n7SE6uK6026804@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jhb Date: Fri Aug 28 14:06:55 2009 New Revision: 196615 URL: http://svn.freebsd.org/changeset/base/196615 Log: 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 Modified: head/sys/kern/kern_conf.c head/sys/sys/conf.h head/sys/sys/types.h head/sys/vm/device_pager.c head/sys/vm/vm.h Modified: head/sys/kern/kern_conf.c ============================================================================== --- head/sys/kern/kern_conf.c Fri Aug 28 10:25:26 2009 (r196614) +++ head/sys/kern/kern_conf.c Fri Aug 28 14:06:55 2009 (r196615) @@ -302,7 +302,7 @@ static struct cdevsw dead_cdevsw = { #define no_read (d_read_t *)enodev #define no_write (d_write_t *)enodev #define no_ioctl (d_ioctl_t *)enodev -#define no_mmap (d_mmap_t *)enodev +#define no_mmap (d_mmap2_t *)enodev #define no_kqfilter (d_kqfilter_t *)enodev #define no_mmap_single (d_mmap_single_t *)enodev @@ -469,7 +469,8 @@ giant_kqfilter(struct cdev *dev, struct } static int -giant_mmap(struct cdev *dev, vm_offset_t offset, vm_paddr_t *paddr, int nprot) +giant_mmap(struct cdev *dev, vm_offset_t offset, vm_paddr_t *paddr, int nprot, + vm_memattr_t *memattr) { struct cdevsw *dsw; int retval; @@ -478,7 +479,11 @@ giant_mmap(struct cdev *dev, vm_offset_t if (dsw == NULL) return (ENXIO); mtx_lock(&Giant); - retval = dsw->d_gianttrick->d_mmap(dev, offset, paddr, nprot); + if (dsw->d_gianttrick->d_flags & D_MMAP2) + retval = dsw->d_gianttrick->d_mmap2(dev, offset, paddr, nprot, + memattr); + else + retval = dsw->d_gianttrick->d_mmap(dev, offset, paddr, nprot); mtx_unlock(&Giant); dev_relthread(dev); return (retval); @@ -614,6 +619,7 @@ prep_cdevsw(struct cdevsw *devsw) if (devsw->d_gianttrick == NULL) { memcpy(dsw2, devsw, sizeof *dsw2); devsw->d_gianttrick = dsw2; + devsw->d_flags |= D_MMAP2; dsw2 = NULL; } } @@ -634,7 +640,7 @@ prep_cdevsw(struct cdevsw *devsw) FIXUP(d_write, no_write, giant_write); FIXUP(d_ioctl, no_ioctl, giant_ioctl); FIXUP(d_poll, no_poll, giant_poll); - FIXUP(d_mmap, no_mmap, giant_mmap); + FIXUP(d_mmap2, no_mmap, giant_mmap); FIXUP(d_strategy, no_strategy, giant_strategy); FIXUP(d_kqfilter, no_kqfilter, giant_kqfilter); FIXUP(d_mmap_single, no_mmap_single, giant_mmap_single); Modified: head/sys/sys/conf.h ============================================================================== --- head/sys/sys/conf.h Fri Aug 28 10:25:26 2009 (r196614) +++ head/sys/sys/conf.h Fri Aug 28 14:06:55 2009 (r196615) @@ -137,6 +137,8 @@ typedef int d_poll_t(struct cdev *dev, i typedef int d_kqfilter_t(struct cdev *dev, struct knote *kn); typedef int d_mmap_t(struct cdev *dev, vm_offset_t offset, vm_paddr_t *paddr, int nprot); +typedef int d_mmap2_t(struct cdev *dev, vm_offset_t offset, vm_paddr_t *paddr, + int nprot, vm_memattr_t *memattr); typedef int d_mmap_single_t(struct cdev *cdev, vm_ooffset_t *offset, vm_size_t size, struct vm_object **object, int nprot); typedef void d_purge_t(struct cdev *dev); @@ -170,6 +172,7 @@ typedef int dumper_t( #define D_PSEUDO 0x00200000 /* make_dev() can return NULL */ #define D_NEEDGIANT 0x00400000 /* driver want Giant */ #define D_NEEDMINOR 0x00800000 /* driver uses clone_create() */ +#define D_MMAP2 0x01000000 /* driver uses d_mmap2() */ /* * Version numbers. @@ -198,7 +201,10 @@ struct cdevsw { d_write_t *d_write; d_ioctl_t *d_ioctl; d_poll_t *d_poll; - d_mmap_t *d_mmap; + union { + d_mmap_t *old; + d_mmap2_t *new; + } __d_mmap; d_strategy_t *d_strategy; dumper_t *d_dump; d_kqfilter_t *d_kqfilter; @@ -218,6 +224,8 @@ struct cdevsw { SLIST_ENTRY(cdevsw) postfree_list; } __d_giant; }; +#define d_mmap __d_mmap.old +#define d_mmap2 __d_mmap.new #define d_gianttrick __d_giant.gianttrick #define d_postfree_list __d_giant.postfree_list Modified: head/sys/sys/types.h ============================================================================== --- head/sys/sys/types.h Fri Aug 28 10:25:26 2009 (r196614) +++ head/sys/sys/types.h Fri Aug 28 14:06:55 2009 (r196615) @@ -299,6 +299,7 @@ typedef __uint32_t intrmask_t; /* Interr typedef __uintfptr_t uintfptr_t; typedef __uint64_t uoff_t; +typedef char vm_memattr_t; /* memory attribute codes */ typedef struct vm_page *vm_page_t; #define offsetof(type, field) __offsetof(type, field) Modified: head/sys/vm/device_pager.c ============================================================================== --- head/sys/vm/device_pager.c Fri Aug 28 10:25:26 2009 (r196614) +++ head/sys/vm/device_pager.c Fri Aug 28 14:06:55 2009 (r196615) @@ -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 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 */ 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, req 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, req 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); Modified: head/sys/vm/vm.h ============================================================================== --- head/sys/vm/vm.h Fri Aug 28 10:25:26 2009 (r196614) +++ head/sys/vm/vm.h Fri Aug 28 14:06:55 2009 (r196615) @@ -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>. */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200908281406.n7SE6uK6026804>