aboutsummaryrefslogtreecommitdiff
path: root/sys/geom/geom_dev.c
diff options
context:
space:
mode:
authorSteven Hartland <smh@FreeBSD.org>2013-04-26 15:43:24 +0000
committerSteven Hartland <smh@FreeBSD.org>2013-04-26 15:43:24 +0000
commit6f926c0b82d9341580aa6fe150f61352367985ec (patch)
tree1b4f63d9287ea91f7b3891c2aa1f82efdf51792a /sys/geom/geom_dev.c
parent6225bf48ae57eea78d9d1a491017c1a01760f5e5 (diff)
downloadsrc-6f926c0b82d9341580aa6fe150f61352367985ec.tar.gz
src-6f926c0b82d9341580aa6fe150f61352367985ec.zip
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
Notes
Notes: svn path=/head/; revision=249930
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 3185933dec9b..f8b26802f755 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;