Skip to content

Commit

Permalink
Turn off log block writing when L2ARC size < 1GB
Browse files Browse the repository at this point in the history
Signed-off-by: George Amanakis <gamanakis@gmail.com>
  • Loading branch information
gamanakis committed Jan 14, 2020
1 parent e1e917f commit c8850ce
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 11 deletions.
14 changes: 14 additions & 0 deletions man/man5/zfs-module-parameters.5
Expand Up @@ -256,6 +256,20 @@ fragmented/unusable).
Use \fB1\fR for yes (default) and \fB0\fR for no.
.RE

.sp
.ne 2
.na
\fBl2arc_rebuild_blocks_min_size\fR (int)
.ad
.RS 12n
Min size in bytes of an L2ARC device to write rebuild log blocks in it.
Rationale: for L2ARC devices less than 1GB, the amount of data l2arc_evict()
evicts is significant compared to the amount of restored L2ARC data. In this
case do not write or restore log blocks in L2ARC in order not to waste space.
.sp
Default value: \fB1,073,741,824\fR (1GB).
.RE

.sp
.ne 2
.na
Expand Down
35 changes: 26 additions & 9 deletions module/zfs/arc.c
Expand Up @@ -864,11 +864,18 @@ static void l2arc_read_done(zio_t *);
/*
* Performance tuning of L2ARC persistence:
*
* l2arc_rebuild_enabled : A ZFS module that controls whether adding an L2ARC
* device (either at pool import or when adding one manually later)
* will attempt to rebuild L2ARC buffer contents.
* l2arc_rebuild_enabled : A ZFS module parameter that controls whether adding
* an L2ARC device (either at pool import or later) will attempt
* to rebuild L2ARC buffer contents.
* l2arc_rebuild_blocks_min_size : A ZFS module parameter that controls whether
* log blocks are written to the L2ARC device. If the L2ARC device
* is less than 1GB, the amount of data l2arc_evict() evicts is
* significant compared to the amount of restored L2ARC data. In
* this case do not write or restore log blocks in L2ARC so as not
* to waste space.
*/
int l2arc_rebuild_enabled = B_TRUE;
int l2arc_rebuild_blocks_min_size = 1024 * 1024 * 1024;

/* L2ARC persistence rebuild control routines. */
static void l2arc_dev_rebuild_start(l2arc_dev_t *dev);
Expand Down Expand Up @@ -8690,9 +8697,10 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz)

/*
* If we wrote any logs as part of this write, update dev hdr
* to point to it.
* to point to it. If log_entries = 0 also update the header here,
* otherwise it will not be updated, leading to dh_errors.
*/
if (dev_hdr_update)
if (dev_hdr_update || dev->l2ad_dev_hdr->dh_log_blk_ent == 0)
l2arc_dev_hdr_update(dev, pio, cb);

/*
Expand Down Expand Up @@ -8850,8 +8858,9 @@ l2arc_vdev_get(vdev_t *vd)
void
l2arc_add_vdev(spa_t *spa, vdev_t *vd, boolean_t rebuild)
{
l2arc_dev_t *adddev;
l2arc_dev_hdr_phys_t *hdr;
l2arc_dev_t *adddev;
l2arc_dev_hdr_phys_t *hdr;
uint64_t log_entries;

ASSERT(!l2arc_vdev_present(vd));

Expand Down Expand Up @@ -8895,8 +8904,13 @@ l2arc_add_vdev(spa_t *spa, vdev_t *vd, boolean_t rebuild)
* is less than that, we reduce the amount of committed and restored
* log entries per block so as to enable persistence.
*/
uint64_t log_entries = MIN((adddev->l2ad_end - adddev->l2ad_start) >>
SPA_MAXBLOCKSHIFT, L2ARC_LOG_BLK_MAX_ENTRIES);
if (adddev->l2ad_end < l2arc_rebuild_blocks_min_size) {
log_entries = 0;
} else {
log_entries = MIN((adddev->l2ad_end -
adddev->l2ad_start) >> SPA_MAXBLOCKSHIFT,
L2ARC_LOG_BLK_MAX_ENTRIES);
}

/*
* Read the device header, and if hdr->dh_log_blk_ent is not equal to
Expand Down Expand Up @@ -9893,6 +9907,9 @@ ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, norw, INT, ZMOD_RW,
ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, rebuild_enabled, INT, ZMOD_RW,
"Rebuild the L2ARC when importing a pool");

ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, rebuild_blocks_min_size, INT, ZMOD_RW,
"Min size in bytes to write rebuild log blocks in L2ARC");

ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, lotsfree_percent, param_set_arc_int,
param_get_int, ZMOD_RW, "System free memory I/O throttle in bytes");

Expand Down
Expand Up @@ -59,12 +59,16 @@ function cleanup
fi

log_must set_tunable32 l2arc_noprefetch $noprefetch
log_must set_tunable32 l2arc_rebuild_blocks_min_size \
$rebuild_blocks_min_size
}
log_onexit cleanup

# l2arc_noprefetch is set to 0 to let L2ARC handle prefetches
typeset noprefetch=$(get_tunable l2arc_noprefetch)
typeset rebuild_blocks_min_size=$(get_tunable l2arc_rebuild_blocks_min_size)
log_must set_tunable32 l2arc_noprefetch 0
log_must set_tunable32 l2arc_rebuild_blocks_min_size 0

typeset fill_mb=800
typeset cache_sz=$(( floor($fill_mb / 2 ) ))
Expand All @@ -90,7 +94,8 @@ log_must fio $FIO_SCRIPTS/random_reads.fio
log_must zpool export $TESTPOOL
log_must zpool import -d $VDIR $TESTPOOL

log_must test "$(zpool iostat -Hpv $TESTPOOL $VDEV_CACHE | awk '{print $2}')" -gt 23702188
log_must test "$(zpool iostat -Hpv $TESTPOOL $VDEV_CACHE | awk '{print $2}')" \
-gt 23702188

typeset l2_hits_start=$(grep l2_hits /proc/spl/kstat/zfs/arcstats | \
awk '{print $3}')
Expand Down
Expand Up @@ -63,12 +63,16 @@ function cleanup
fi

log_must set_tunable32 l2arc_noprefetch $noprefetch
log_must set_tunable32 l2arc_rebuild_blocks_min_size \
$rebuild_blocks_min_size
}
log_onexit cleanup

# l2arc_noprefetch is set to 0 to let L2ARC handle prefetches
typeset noprefetch=$(get_tunable l2arc_noprefetch)
typeset rebuild_blocks_min_size=$(get_tunable l2arc_rebuild_blocks_min_size)
log_must set_tunable32 l2arc_noprefetch 0
log_must set_tunable32 l2arc_rebuild_blocks_min_size 0

typeset fill_mb=800
typeset cache_sz=$(( floor($fill_mb / 2) ))
Expand Down Expand Up @@ -97,7 +101,8 @@ log_must fio $FIO_SCRIPTS/random_reads.fio
log_must zpool export $TESTPOOL
log_must zpool import -d $VDIR $TESTPOOL
log_must eval "echo $PASSPHRASE | zfs mount -l $TESTPOOL/$TESTFS1"
log_must test "$(zpool iostat -Hpv $TESTPOOL $VDEV_CACHE | awk '{print $2}')" -gt 23702188
log_must test "$(zpool iostat -Hpv $TESTPOOL $VDEV_CACHE | awk '{print $2}')" \
-gt 23702188

typeset l2_hits_start=$(grep l2_hits /proc/spl/kstat/zfs/arcstats | \
awk '{print $3}')
Expand Down

0 comments on commit c8850ce

Please sign in to comment.