Skip to content

Commit dbb3afb

Browse files
committed
Add L2ARC arcstats for MFU/MRU buffers and buffer content type
Currently the initial ARC state (MFU/MRU) of cached L2ARC buffers at the time of their caching is unknown. The same applies for the buffer content type. This commit adds L2ARC arcstats that display the aligned size (in bytes) of L2ARC buffers according to their content type (data/metadata) and according to their ARC state at the time of caching in L2ARC. This may prove beneficial in adjusting the L2ARC caching policy in the future. Signed-off-by: George Amanakis <[email protected]>
1 parent 772c69d commit dbb3afb

File tree

3 files changed

+100
-16
lines changed

3 files changed

+100
-16
lines changed

cmd/zdb/zdb.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4101,6 +4101,8 @@ dump_l2arc_log_entries(uint64_t log_entries,
41014101
(u_longlong_t)L2BLK_GET_PREFETCH((&le[j])->le_prop));
41024102
(void) printf("|\t\t\t\taddress: %llu\n",
41034103
(u_longlong_t)le[j].le_daddr);
4104+
(void) printf("|\t\t\t\tstate: %llu\n",
4105+
(u_longlong_t)L2BLK_GET_STATE((&le[j])->le_prop));
41044106
(void) printf("|\n");
41054107
}
41064108
(void) printf("\n");

include/sys/arc_impl.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,8 @@ typedef struct l2arc_lb_ptr_buf {
349349
#define L2BLK_SET_TYPE(field, x) BF64_SET((field), 48, 8, x)
350350
#define L2BLK_GET_PROTECTED(field) BF64_GET((field), 56, 1)
351351
#define L2BLK_SET_PROTECTED(field, x) BF64_SET((field), 56, 1, x)
352+
#define L2BLK_GET_STATE(field) BF64_GET((field), 57, 4)
353+
#define L2BLK_SET_STATE(field, x) BF64_SET((field), 57, 4, x)
352354

353355
#define PTR_SWAP(x, y) \
354356
do { \
@@ -445,6 +447,7 @@ typedef struct l2arc_buf_hdr {
445447
uint64_t b_daddr; /* disk address, offset byte */
446448
uint32_t b_hits;
447449
list_node_t b_l2node;
450+
arc_state_type_t b_arcs_state;
448451
} l2arc_buf_hdr_t;
449452

450453
typedef struct l2arc_write_callback {
@@ -733,6 +736,20 @@ typedef struct arc_stats {
733736
kstat_named_t arcstat_mfu_ghost_evictable_metadata;
734737
kstat_named_t arcstat_l2_hits;
735738
kstat_named_t arcstat_l2_misses;
739+
/*
740+
* Aligned size (in bytes) of L2ARC cached buffers according to their
741+
* ARC state at the time of caching in L2ARC.
742+
*/
743+
kstat_named_t arcstat_l2_mru_asize;
744+
kstat_named_t arcstat_l2_mru_ghost_asize;
745+
kstat_named_t arcstat_l2_mfu_asize;
746+
kstat_named_t arcstat_l2_mfu_ghost_asize;
747+
/*
748+
* Aligned size (in bytes) of L2ARC cached buffers by buffer content
749+
* type.
750+
*/
751+
kstat_named_t arcstat_l2_bufc_data_asize;
752+
kstat_named_t arcstat_l2_bufc_metadata_asize;
736753
kstat_named_t arcstat_l2_feeds;
737754
kstat_named_t arcstat_l2_rw_clash;
738755
kstat_named_t arcstat_l2_read_bytes;

module/zfs/arc.c

Lines changed: 81 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,12 @@ arc_stats_t arc_stats = {
527527
{ "mfu_ghost_evictable_metadata", KSTAT_DATA_UINT64 },
528528
{ "l2_hits", KSTAT_DATA_UINT64 },
529529
{ "l2_misses", KSTAT_DATA_UINT64 },
530+
{ "l2_mru_asize", KSTAT_DATA_UINT64 },
531+
{ "l2_mru_ghost_asize", KSTAT_DATA_UINT64 },
532+
{ "l2_mfu_asize", KSTAT_DATA_UINT64 },
533+
{ "l2_mfu_ghost_asize", KSTAT_DATA_UINT64 },
534+
{ "l2_bufc_data_asize", KSTAT_DATA_UINT64 },
535+
{ "l2_bufc_metadata_asize", KSTAT_DATA_UINT64 },
530536
{ "l2_feeds", KSTAT_DATA_UINT64 },
531537
{ "l2_rw_clash", KSTAT_DATA_UINT64 },
532538
{ "l2_read_bytes", KSTAT_DATA_UINT64 },
@@ -887,6 +893,7 @@ static inline void arc_hdr_clear_flags(arc_buf_hdr_t *hdr, arc_flags_t flags);
887893
static boolean_t l2arc_write_eligible(uint64_t, arc_buf_hdr_t *);
888894
static void l2arc_read_done(zio_t *);
889895
static void l2arc_do_free_on_write(void);
896+
static void l2arc_hdr_arcstats_update(arc_buf_hdr_t *hdr, boolean_t incr);
890897

891898
/*
892899
* L2ARC TRIM
@@ -1707,7 +1714,8 @@ arc_buf_try_copy_decompressed_data(arc_buf_t *buf)
17071714
static arc_buf_hdr_t *
17081715
arc_buf_alloc_l2only(size_t size, arc_buf_contents_t type, l2arc_dev_t *dev,
17091716
dva_t dva, uint64_t daddr, int32_t psize, uint64_t birth,
1710-
enum zio_compress compress, boolean_t protected, boolean_t prefetch)
1717+
enum zio_compress compress, boolean_t protected, boolean_t prefetch,
1718+
arc_state_type_t arcs_state)
17111719
{
17121720
arc_buf_hdr_t *hdr;
17131721

@@ -1730,6 +1738,7 @@ arc_buf_alloc_l2only(size_t size, arc_buf_contents_t type, l2arc_dev_t *dev,
17301738

17311739
hdr->b_l2hdr.b_dev = dev;
17321740
hdr->b_l2hdr.b_daddr = daddr;
1741+
hdr->b_l2hdr.b_arcs_state = arcs_state;
17331742

17341743
return (hdr);
17351744
}
@@ -3661,6 +3670,62 @@ arc_alloc_raw_buf(spa_t *spa, void *tag, uint64_t dsobj, boolean_t byteorder,
36613670
return (buf);
36623671
}
36633672

3673+
static void
3674+
l2arc_hdr_arcstats_update(arc_buf_hdr_t *hdr, boolean_t incr)
3675+
{
3676+
l2arc_buf_hdr_t *l2hdr = &hdr->b_l2hdr;
3677+
l2arc_dev_t *dev = l2hdr->b_dev;
3678+
uint64_t lsize = HDR_GET_LSIZE(hdr);
3679+
uint64_t psize = HDR_GET_PSIZE(hdr);
3680+
uint64_t asize = vdev_psize_to_asize(dev->l2ad_vdev, psize);
3681+
arc_buf_contents_t type = hdr->b_type;
3682+
int64_t lsize_s;
3683+
int64_t psize_s;
3684+
int64_t asize_s;
3685+
3686+
if (!incr) {
3687+
lsize_s = -lsize;
3688+
psize_s = -psize;
3689+
asize_s = -asize;
3690+
} else {
3691+
lsize_s = lsize;
3692+
psize_s = psize;
3693+
asize_s = asize;
3694+
}
3695+
3696+
ARCSTAT_INCR(arcstat_l2_psize, psize_s);
3697+
ARCSTAT_INCR(arcstat_l2_lsize, lsize_s);
3698+
3699+
switch (hdr->b_l2hdr.b_arcs_state) {
3700+
case ARC_STATE_MRU:
3701+
ARCSTAT_INCR(arcstat_l2_mru_asize, asize_s);
3702+
break;
3703+
case ARC_STATE_MRU_GHOST:
3704+
ARCSTAT_INCR(arcstat_l2_mru_ghost_asize, asize_s);
3705+
break;
3706+
case ARC_STATE_MFU:
3707+
ARCSTAT_INCR(arcstat_l2_mfu_asize, asize_s);
3708+
break;
3709+
case ARC_STATE_MFU_GHOST:
3710+
ARCSTAT_INCR(arcstat_l2_mfu_ghost_asize, asize_s);
3711+
break;
3712+
default:
3713+
break;
3714+
}
3715+
3716+
switch (type) {
3717+
case ARC_BUFC_DATA:
3718+
ARCSTAT_INCR(arcstat_l2_bufc_data_asize, asize_s);
3719+
break;
3720+
case ARC_BUFC_METADATA:
3721+
ARCSTAT_INCR(arcstat_l2_bufc_metadata_asize, asize_s);
3722+
break;
3723+
default:
3724+
break;
3725+
}
3726+
}
3727+
3728+
36643729
static void
36653730
arc_hdr_l2hdr_destroy(arc_buf_hdr_t *hdr)
36663731
{
@@ -3674,9 +3739,7 @@ arc_hdr_l2hdr_destroy(arc_buf_hdr_t *hdr)
36743739

36753740
list_remove(&dev->l2ad_buflist, hdr);
36763741

3677-
ARCSTAT_INCR(arcstat_l2_psize, -psize);
3678-
ARCSTAT_INCR(arcstat_l2_lsize, -HDR_GET_LSIZE(hdr));
3679-
3742+
l2arc_hdr_arcstats_update(hdr, B_FALSE);
36803743
vdev_space_update(dev->l2ad_vdev, -asize, 0, 0);
36813744

36823745
(void) zfs_refcount_remove_many(&dev->l2ad_alloc, arc_hdr_size(hdr),
@@ -8025,9 +8088,6 @@ l2arc_write_done(zio_t *zio)
80258088
DTRACE_PROBE2(l2arc__iodone, zio_t *, zio,
80268089
l2arc_write_callback_t *, cb);
80278090

8028-
if (zio->io_error != 0)
8029-
ARCSTAT_BUMP(arcstat_l2_writes_error);
8030-
80318091
/*
80328092
* All writes completed, or an error was hit.
80338093
*/
@@ -8091,8 +8151,7 @@ l2arc_write_done(zio_t *zio)
80918151
arc_hdr_clear_flags(hdr, ARC_FLAG_HAS_L2HDR);
80928152

80938153
uint64_t psize = HDR_GET_PSIZE(hdr);
8094-
ARCSTAT_INCR(arcstat_l2_psize, -psize);
8095-
ARCSTAT_INCR(arcstat_l2_lsize, -HDR_GET_LSIZE(hdr));
8154+
l2arc_hdr_arcstats_update(hdr, B_FALSE);
80968155

80978156
bytes_dropped +=
80988157
vdev_psize_to_asize(dev->l2ad_vdev, psize);
@@ -8140,6 +8199,8 @@ l2arc_write_done(zio_t *zio)
81408199
list_destroy(&cb->l2wcb_abd_list);
81418200

81428201
if (zio->io_error != 0) {
8202+
ARCSTAT_BUMP(arcstat_l2_writes_error);
8203+
81438204
/*
81448205
* Restore the lbps array in the header to its previous state.
81458206
* If the list of log block pointers is empty, zero out the
@@ -9024,6 +9085,8 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz)
90249085
hdr->b_l2hdr.b_hits = 0;
90259086

90269087
hdr->b_l2hdr.b_daddr = dev->l2ad_hand;
9088+
hdr->b_l2hdr.b_arcs_state =
9089+
hdr->b_l1hdr.b_state->arcs_state;
90279090
arc_hdr_set_flags(hdr, ARC_FLAG_HAS_L2HDR);
90289091

90299092
mutex_enter(&dev->l2ad_mtx);
@@ -9046,6 +9109,7 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz)
90469109
write_psize += psize;
90479110
write_asize += asize;
90489111
dev->l2ad_hand += asize;
9112+
l2arc_hdr_arcstats_update(hdr, B_TRUE);
90499113
vdev_space_update(dev->l2ad_vdev, asize, 0, 0);
90509114

90519115
mutex_exit(hash_lock);
@@ -10023,19 +10087,18 @@ l2arc_hdr_restore(const l2arc_log_ent_phys_t *le, l2arc_dev_t *dev)
1002310087
L2BLK_GET_PSIZE((le)->le_prop), le->le_birth,
1002410088
L2BLK_GET_COMPRESS((le)->le_prop),
1002510089
L2BLK_GET_PROTECTED((le)->le_prop),
10026-
L2BLK_GET_PREFETCH((le)->le_prop));
10090+
L2BLK_GET_PREFETCH((le)->le_prop),
10091+
L2BLK_GET_STATE((le)->le_prop));
1002710092
asize = vdev_psize_to_asize(dev->l2ad_vdev,
1002810093
L2BLK_GET_PSIZE((le)->le_prop));
1002910094

1003010095
/*
1003110096
* vdev_space_update() has to be called before arc_hdr_destroy() to
10032-
* avoid underflow since the latter also calls the former.
10097+
* avoid underflow since the latter also calls vdev_space_update().
1003310098
*/
10099+
l2arc_hdr_arcstats_update(hdr, B_TRUE);
1003410100
vdev_space_update(dev->l2ad_vdev, asize, 0, 0);
1003510101

10036-
ARCSTAT_INCR(arcstat_l2_lsize, HDR_GET_LSIZE(hdr));
10037-
ARCSTAT_INCR(arcstat_l2_psize, HDR_GET_PSIZE(hdr));
10038-
1003910102
mutex_enter(&dev->l2ad_mtx);
1004010103
list_insert_tail(&dev->l2ad_buflist, hdr);
1004110104
(void) zfs_refcount_add_many(&dev->l2ad_alloc, arc_hdr_size(hdr), hdr);
@@ -10055,14 +10118,15 @@ l2arc_hdr_restore(const l2arc_log_ent_phys_t *le, l2arc_dev_t *dev)
1005510118
arc_hdr_set_flags(exists, ARC_FLAG_HAS_L2HDR);
1005610119
exists->b_l2hdr.b_dev = dev;
1005710120
exists->b_l2hdr.b_daddr = le->le_daddr;
10121+
exists->b_l2hdr.b_arcs_state =
10122+
L2BLK_GET_STATE((le)->le_prop);
1005810123
mutex_enter(&dev->l2ad_mtx);
1005910124
list_insert_tail(&dev->l2ad_buflist, exists);
1006010125
(void) zfs_refcount_add_many(&dev->l2ad_alloc,
1006110126
arc_hdr_size(exists), exists);
1006210127
mutex_exit(&dev->l2ad_mtx);
10128+
l2arc_hdr_arcstats_update(exists, B_TRUE);
1006310129
vdev_space_update(dev->l2ad_vdev, asize, 0, 0);
10064-
ARCSTAT_INCR(arcstat_l2_lsize, HDR_GET_LSIZE(exists));
10065-
ARCSTAT_INCR(arcstat_l2_psize, HDR_GET_PSIZE(exists));
1006610130
}
1006710131
ARCSTAT_BUMP(arcstat_l2_rebuild_bufs_precached);
1006810132
}
@@ -10357,6 +10421,7 @@ l2arc_log_blk_insert(l2arc_dev_t *dev, const arc_buf_hdr_t *hdr)
1035710421
L2BLK_SET_TYPE((le)->le_prop, hdr->b_type);
1035810422
L2BLK_SET_PROTECTED((le)->le_prop, !!(HDR_PROTECTED(hdr)));
1035910423
L2BLK_SET_PREFETCH((le)->le_prop, !!(HDR_PREFETCH(hdr)));
10424+
L2BLK_SET_STATE((le)->le_prop, hdr->b_l1hdr.b_state->arcs_state);
1036010425

1036110426
dev->l2ad_log_blk_payload_asize += vdev_psize_to_asize(dev->l2ad_vdev,
1036210427
HDR_GET_PSIZE(hdr));

0 commit comments

Comments
 (0)