Skip to content

Commit

Permalink
Add TRIM support for L2ARC.
Browse files Browse the repository at this point in the history
This adds TRIM support to cache vdevs. When ARC buffers are removed
from the L2ARC in arc_hdr_destroy(), arc_release() or l2arc_evict(),
the size previously occupied by the buffer gets scheduled for TRIMming.
As always, actual TRIMs are only issued to the L2ARC after
txg_trim_limit.
  • Loading branch information
dechamps committed Oct 5, 2012
1 parent 082e2b0 commit 31aae37
Show file tree
Hide file tree
Showing 4 changed files with 12 additions and 6 deletions.
2 changes: 1 addition & 1 deletion include/sys/trim_map.h
Expand Up @@ -36,7 +36,7 @@ extern "C" {

extern void trim_map_create(vdev_t *vd);
extern void trim_map_destroy(vdev_t *vd);
extern void trim_map_free(zio_t *zio);
extern void trim_map_free(vdev_t *vd, uint64_t offset, uint64_t size);
extern boolean_t trim_map_write_start(zio_t *zio);
extern void trim_map_write_done(zio_t *zio);

Expand Down
7 changes: 7 additions & 0 deletions module/zfs/arc.c
Expand Up @@ -141,6 +141,7 @@
#include <sys/callb.h>
#include <sys/kstat.h>
#include <sys/dmu_tx.h>
#include <sys/trim_map.h>
#include <zfs_fletcher.h>

static kmutex_t arc_reclaim_thr_lock;
Expand Down Expand Up @@ -1519,6 +1520,8 @@ arc_hdr_destroy(arc_buf_hdr_t *hdr)
}

if (l2hdr != NULL) {
trim_map_free(l2hdr->b_dev->l2ad_vdev, l2hdr->b_daddr,
hdr->b_size);
list_remove(l2hdr->b_dev->l2ad_buflist, hdr);
ARCSTAT_INCR(arcstat_l2_size, -hdr->b_size);
kmem_free(l2hdr, sizeof (l2arc_buf_hdr_t));
Expand Down Expand Up @@ -3376,6 +3379,8 @@ arc_release(arc_buf_t *buf, void *tag)
buf->b_private = NULL;

if (l2hdr) {
trim_map_free(l2hdr->b_dev->l2ad_vdev, l2hdr->b_daddr,
hdr->b_size);
list_remove(l2hdr->b_dev->l2ad_buflist, hdr);
kmem_free(l2hdr, sizeof (l2arc_buf_hdr_t));
ARCSTAT_INCR(arcstat_l2_size, -buf_size);
Expand Down Expand Up @@ -4487,6 +4492,8 @@ l2arc_evict(l2arc_dev_t *dev, uint64_t distance, boolean_t all)
if (ab->b_l2hdr != NULL) {
abl2 = ab->b_l2hdr;
ab->b_l2hdr = NULL;
trim_map_free(abl2->b_dev->l2ad_vdev, abl2->b_daddr,
ab->b_size);
kmem_free(abl2, sizeof (l2arc_buf_hdr_t));
ARCSTAT_INCR(arcstat_l2_size, -ab->b_size);
}
Expand Down
7 changes: 3 additions & 4 deletions module/zfs/trim_map.c
Expand Up @@ -192,7 +192,7 @@ trim_map_segment_add(trim_map_t *tm, uint64_t start, uint64_t end, uint64_t txg)
} else if (merge_after) {
ts_after->ts_start = start;
} else {
ts = kmem_alloc(sizeof (*ts), KM_SLEEP);
ts = kmem_alloc(sizeof (*ts), KM_PUSHPAGE);
ts->ts_start = start;
ts->ts_end = end;
ts->ts_txg = txg;
Expand Down Expand Up @@ -261,16 +261,15 @@ trim_map_free_locked(trim_map_t *tm, uint64_t start, uint64_t end, uint64_t txg)
}

void
trim_map_free(zio_t *zio)
trim_map_free(vdev_t *vd, uint64_t offset, uint64_t size)
{
vdev_t *vd = zio->io_vd;
trim_map_t *tm = vd->vdev_trimmap;

if (zfs_notrim || vd->vdev_notrim || tm == NULL)
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, offset, offset + size,
vd->vdev_spa->spa_syncing_txg);
mutex_exit(&tm->tm_lock);
}
Expand Down
2 changes: 1 addition & 1 deletion module/zfs/zio.c
Expand Up @@ -2454,7 +2454,7 @@ zio_vdev_io_start(zio_t *zio)
}

if (vd->vdev_ops->vdev_op_leaf && zio->io_type == ZIO_TYPE_FREE) {
trim_map_free(zio);
trim_map_free(vd, zio->io_offset, zio->io_size);
return (ZIO_PIPELINE_CONTINUE);
}

Expand Down

0 comments on commit 31aae37

Please sign in to comment.