summaryrefslogtreecommitdiffstats
path: root/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/trim_map.c
diff options
context:
space:
mode:
authorsmh <smh@FreeBSD.org>2012-12-13 17:06:38 +0000
committersmh <smh@FreeBSD.org>2012-12-13 17:06:38 +0000
commit88b6a40b33f7635a0478e35c2cbcf1ffe60820e9 (patch)
tree7d5848e7ee4a31c472d71d4f0b58fca332260cf8 /sys/cddl/contrib/opensolaris/uts/common/fs/zfs/trim_map.c
parent9ffc5fc1ccef66b1ce687f4fe78278f23479a400 (diff)
downloadFreeBSD-src-88b6a40b33f7635a0478e35c2cbcf1ffe60820e9.zip
FreeBSD-src-88b6a40b33f7635a0478e35c2cbcf1ffe60820e9.tar.gz
Upgrades trim free request sizes before inserting them into to free map,
making range consolidation much more effective particularly for small deletes. This reduces memory used by the free map as well as reducing the number of bio requests down to geom required to process all deletes. In tests this achieved a factor of 10 reduction of trim ranges / geom call downs. While I'm here correct the description of zio_vdev_io_start. PR: kern/173254 Submitted by: Steven Hartland Approved by: pjd (mentor)
Diffstat (limited to 'sys/cddl/contrib/opensolaris/uts/common/fs/zfs/trim_map.c')
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/trim_map.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/trim_map.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/trim_map.c
index 5de5f2a..4bf0734 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/trim_map.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/trim_map.c
@@ -28,6 +28,17 @@
#include <sys/vdev_impl.h>
#include <sys/trim_map.h>
+/*
+ * Calculate the zio end, upgrading based on ashift which would be
+ * done by zio_vdev_io_start.
+ *
+ * This makes free range consolidation much more effective
+ * than it would otherwise be as well as ensuring that entire
+ * blocks are invalidated by writes.
+ */
+#define TRIM_ZIO_END(zio) ((zio)->io_offset + \
+ P2ROUNDUP((zio)->io_size, 1ULL << (zio)->io_vd->vdev_top->vdev_ashift))
+
typedef struct trim_map {
list_t tm_head; /* List of segments sorted by txg. */
avl_tree_t tm_queued_frees; /* AVL tree of segments waiting for TRIM. */
@@ -270,7 +281,7 @@ trim_map_free(zio_t *zio)
return;
mutex_enter(&tm->tm_lock);
- trim_map_free_locked(tm, zio->io_offset, zio->io_offset + zio->io_size,
+ trim_map_free_locked(tm, zio->io_offset, TRIM_ZIO_END(zio),
vd->vdev_spa->spa_syncing_txg);
mutex_exit(&tm->tm_lock);
}
@@ -288,7 +299,7 @@ trim_map_write_start(zio_t *zio)
return (B_TRUE);
start = zio->io_offset;
- end = start + zio->io_size;
+ end = TRIM_ZIO_END(zio);
tsearch.ts_start = start;
tsearch.ts_end = end;
OpenPOWER on IntegriCloud