summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorken <ken@FreeBSD.org>2013-08-15 22:52:39 +0000
committerken <ken@FreeBSD.org>2013-08-15 22:52:39 +0000
commit5591de079d3f2d8a4854b384d52322fc01bf57ea (patch)
tree3aad15663c99de3361bd1808e8449ee767a03647
parentbdb743702fb53c60e30455a13dfd78783868ac2c (diff)
downloadFreeBSD-src-5591de079d3f2d8a4854b384d52322fc01bf57ea.zip
FreeBSD-src-5591de079d3f2d8a4854b384d52322fc01bf57ea.tar.gz
Change the way that unmapped I/O capability is advertised.
The previous method was to set the D_UNMAPPED_IO flag in the cdevsw for the driver. The problem with this is that in many cases (e.g. sa(4)) there may be some instances of the driver that can handle unmapped I/O and some that can't. The isp(4) driver can handle unmapped I/O, but the esp(4) driver currently cannot. The cdevsw is shared among all driver instances. So instead of setting a flag on the cdevsw, set a flag on the cdev. This allows drivers to indicate support for unmapped I/O on a per-instance basis. sys/conf.h: Remove the D_UNMAPPED_IO cdevsw flag and replace it with an SI_UNMAPPED cdev flag. kern_physio.c: Look at the cdev SI_UNMAPPED flag to determine whether or not a particular driver can handle unmapped I/O. geom_dev.c: Set the SI_UNMAPPED flag for all GEOM cdevs. Since GEOM will create a temporary mapping when needed, setting SI_UNMAPPED unconditionally will work. Remove the D_UNMAPPED_IO flag. nvme_ns.c: Set the SI_UNMAPPED flag on cdevs created here if NVME_UNMAPPED_BIO_SUPPORT is enabled. vfs_aio.c: In aio_qphysio(), check the SI_UNMAPPED flag on a cdev instead of the D_UNMAPPED_IO flag on the cdevsw. sys/param.h: Bump __FreeBSD_version to 1000045 for the switch from setting the D_UNMAPPED_IO flag in the cdevsw to setting SI_UNMAPPED in the cdev. Reviewed by: kib, jimharris MFC after: 1 week Sponsored by: Spectra Logic
-rw-r--r--sys/dev/nvme/nvme_ns.c7
-rw-r--r--sys/geom/geom_dev.c4
-rw-r--r--sys/kern/kern_physio.c3
-rw-r--r--sys/kern/vfs_aio.c2
-rw-r--r--sys/sys/conf.h2
-rw-r--r--sys/sys/param.h2
6 files changed, 10 insertions, 10 deletions
diff --git a/sys/dev/nvme/nvme_ns.c b/sys/dev/nvme/nvme_ns.c
index fb31852..5fa3ba0 100644
--- a/sys/dev/nvme/nvme_ns.c
+++ b/sys/dev/nvme/nvme_ns.c
@@ -133,11 +133,7 @@ nvme_ns_strategy(struct bio *bp)
static struct cdevsw nvme_ns_cdevsw = {
.d_version = D_VERSION,
-#ifdef NVME_UNMAPPED_BIO_SUPPORT
- .d_flags = D_DISK | D_UNMAPPED_IO,
-#else
.d_flags = D_DISK,
-#endif
.d_read = physread,
.d_write = physwrite,
.d_open = nvme_ns_open,
@@ -348,6 +344,9 @@ nvme_ns_construct(struct nvme_namespace *ns, uint16_t id,
NULL, UID_ROOT, GID_WHEEL, 0600, "nvme%dns%d",
device_get_unit(ctrlr->dev), ns->id);
#endif
+#ifdef NVME_UNMAPPED_BIO_SUPPORT
+ ns->cdev->si_flags |= SI_UNMAPPED;
+#endif
if (ns->cdev != NULL)
ns->cdev->si_drv1 = ns;
diff --git a/sys/geom/geom_dev.c b/sys/geom/geom_dev.c
index f8b2680..17f24f8 100644
--- a/sys/geom/geom_dev.c
+++ b/sys/geom/geom_dev.c
@@ -79,7 +79,7 @@ static struct cdevsw g_dev_cdevsw = {
.d_ioctl = g_dev_ioctl,
.d_strategy = g_dev_strategy,
.d_name = "g_dev",
- .d_flags = D_DISK | D_TRACKCLOSE | D_UNMAPPED_IO,
+ .d_flags = D_DISK | D_TRACKCLOSE,
};
static g_taste_t g_dev_taste;
@@ -237,6 +237,7 @@ g_dev_taste(struct g_class *mp, struct g_provider *pp, int insist __unused)
g_free(sc);
return (NULL);
}
+ dev->si_flags |= SI_UNMAPPED;
sc->sc_dev = dev;
/* Search for device alias name and create it if found. */
@@ -251,6 +252,7 @@ g_dev_taste(struct g_class *mp, struct g_provider *pp, int insist __unused)
freeenv(val);
make_dev_alias_p(MAKEDEV_CHECKNAME | MAKEDEV_WAITOK,
&adev, dev, "%s", buf);
+ adev->si_flags |= SI_UNMAPPED;
break;
}
}
diff --git a/sys/kern/kern_physio.c b/sys/kern/kern_physio.c
index 1387c8e..ab9c344 100644
--- a/sys/kern/kern_physio.c
+++ b/sys/kern/kern_physio.c
@@ -93,8 +93,7 @@ physio(struct cdev *dev, struct uio *uio, int ioflag)
csw = dev->si_devsw;
if (uio->uio_segflg == UIO_USERSPACE) {
- if (csw != NULL &&
- (csw->d_flags & D_UNMAPPED_IO) != 0)
+ if (dev->si_flags & SI_UNMAPPED)
mapped = 0;
else
mapped = 1;
diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c
index f732d31..a66f7c2 100644
--- a/sys/kern/vfs_aio.c
+++ b/sys/kern/vfs_aio.c
@@ -1375,7 +1375,7 @@ aio_qphysio(struct proc *p, struct aiocblist *aiocbe)
/*
* Bring buffer into kernel space.
*/
- if (vmapbuf(bp, (csw->d_flags & D_UNMAPPED_IO) == 0) < 0) {
+ if (vmapbuf(bp, (dev->si_flags & SI_UNMAPPED) == 0) < 0) {
error = EFAULT;
goto doerror;
}
diff --git a/sys/sys/conf.h b/sys/sys/conf.h
index 5a579b4..fcce859 100644
--- a/sys/sys/conf.h
+++ b/sys/sys/conf.h
@@ -61,6 +61,7 @@ struct cdev {
#define SI_CHILD 0x0010 /* child of another struct cdev **/
#define SI_DUMPDEV 0x0080 /* is kernel dumpdev */
#define SI_CLONELIST 0x0200 /* on a clone list */
+#define SI_UNMAPPED 0x0400 /* can handle unmapped I/O */
struct timespec si_atime;
struct timespec si_ctime;
struct timespec si_mtime;
@@ -167,7 +168,6 @@ typedef int dumper_t(
#define D_MMAP_ANON 0x00100000 /* special treatment in vm_mmap.c */
#define D_NEEDGIANT 0x00400000 /* driver want Giant */
#define D_NEEDMINOR 0x00800000 /* driver uses clone_create() */
-#define D_UNMAPPED_IO 0x01000000 /* d_strategy can accept unmapped IO */
/*
* Version numbers.
diff --git a/sys/sys/param.h b/sys/sys/param.h
index 8698d7e..347765c 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -58,7 +58,7 @@
* in the range 5 to 9.
*/
#undef __FreeBSD_version
-#define __FreeBSD_version 1000044 /* Master, propagated to newvers */
+#define __FreeBSD_version 1000045 /* Master, propagated to newvers */
/*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
OpenPOWER on IntegriCloud