summaryrefslogtreecommitdiffstats
path: root/sys/geom/geom_dev.c
diff options
context:
space:
mode:
authorsmh <smh@FreeBSD.org>2013-04-26 15:43:24 +0000
committersmh <smh@FreeBSD.org>2013-04-26 15:43:24 +0000
commit5e3cfe527c9f5a7d6255ead694356de608509bf7 (patch)
tree1b4f63d9287ea91f7b3891c2aa1f82efdf51792a /sys/geom/geom_dev.c
parentbb465a0ea2adda799d70e444a0c74c76d2aa2aa7 (diff)
downloadFreeBSD-src-5e3cfe527c9f5a7d6255ead694356de608509bf7.zip
FreeBSD-src-5e3cfe527c9f5a7d6255ead694356de608509bf7.tar.gz
Added a sysctl (kern.geom.dev.delete_max_sectors) to control the maximum
size of a delete request sent to the providing device performed by g_dev_ioctl. This allows the kernel and apps via ioctl e.g. newfs -E to request large LBA deletes which siginificantly improves performance. Previously this was hard coded to 65536 sectors, the new default is 262144 which doubles the throughput of deletes on commonly available SSD's. In tests on a Intel 520 120GB FW: 400i disk it improved the delete throughput from 1.6GB/s to over 2.6GB/s on a full disk delete such as that done via newfs -E For some SSD's where delete time is pretty much constant, no matter what the request, setting this to 0 will provide significantly better throughput e.g. Samsung 840 240GB FW DXT07B0Q @ 262144 = 79G/s, @ 0 = 2259G/s Reviewed by: mav Approved by: pjd (mentor) MFC after: 2 weeks
Diffstat (limited to 'sys/geom/geom_dev.c')
-rw-r--r--sys/geom/geom_dev.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/sys/geom/geom_dev.c b/sys/geom/geom_dev.c
index 3185933..f8b2680 100644
--- a/sys/geom/geom_dev.c
+++ b/sys/geom/geom_dev.c
@@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
#include <sys/disk.h>
#include <sys/fcntl.h>
#include <sys/limits.h>
+#include <sys/sysctl.h>
#include <geom/geom.h>
#include <geom/geom_int.h>
#include <machine/stdarg.h>
@@ -93,6 +94,19 @@ static struct g_class g_dev_class = {
.attrchanged = g_dev_attrchanged
};
+/*
+ * We target 262144 (8 x 32768) sectors by default as this significantly
+ * increases the throughput on commonly used SSD's with a marginal
+ * increase in non-interruptible request latency.
+ */
+static uint64_t g_dev_del_max_sectors = 262144;
+SYSCTL_DECL(_kern_geom);
+SYSCTL_NODE(_kern_geom, OID_AUTO, dev, CTLFLAG_RW, 0, "GEOM_DEV stuff");
+SYSCTL_QUAD(_kern_geom_dev, OID_AUTO, delete_max_sectors, CTLFLAG_RW,
+ &g_dev_del_max_sectors, 0, "Maximum number of sectors in a single "
+ "delete request sent to the provider. Larger requests are chunked "
+ "so they can be interrupted. (0 = disable chunking)");
+
static void
g_dev_destroy(void *arg, int flags __unused)
{
@@ -408,17 +422,20 @@ g_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread
}
while (length > 0) {
chunk = length;
- if (chunk > 65536 * cp->provider->sectorsize)
- chunk = 65536 * cp->provider->sectorsize;
+ if (g_dev_del_max_sectors != 0 && chunk >
+ g_dev_del_max_sectors * cp->provider->sectorsize) {
+ chunk = g_dev_del_max_sectors *
+ cp->provider->sectorsize;
+ }
error = g_delete_data(cp, offset, chunk);
length -= chunk;
offset += chunk;
if (error)
break;
/*
- * Since the request size is unbounded, the service
- * time is likewise. We make this ioctl interruptible
- * by checking for signals for each bio.
+ * Since the request size can be large, the service
+ * time can be is likewise. We make this ioctl
+ * interruptible by checking for signals for each bio.
*/
if (SIGPENDING(td))
break;
OpenPOWER on IntegriCloud