@@ -527,6 +527,12 @@ arc_stats_t arc_stats = {
527
527
{ "mfu_ghost_evictable_metadata" , KSTAT_DATA_UINT64 },
528
528
{ "l2_hits" , KSTAT_DATA_UINT64 },
529
529
{ "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 },
530
536
{ "l2_feeds" , KSTAT_DATA_UINT64 },
531
537
{ "l2_rw_clash" , KSTAT_DATA_UINT64 },
532
538
{ "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);
887
893
static boolean_t l2arc_write_eligible (uint64_t , arc_buf_hdr_t * );
888
894
static void l2arc_read_done (zio_t * );
889
895
static void l2arc_do_free_on_write (void );
896
+ static void l2arc_hdr_arcstats_update (arc_buf_hdr_t * hdr , boolean_t incr );
890
897
891
898
/*
892
899
* L2ARC TRIM
@@ -1707,7 +1714,8 @@ arc_buf_try_copy_decompressed_data(arc_buf_t *buf)
1707
1714
static arc_buf_hdr_t *
1708
1715
arc_buf_alloc_l2only (size_t size , arc_buf_contents_t type , l2arc_dev_t * dev ,
1709
1716
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 )
1711
1719
{
1712
1720
arc_buf_hdr_t * hdr ;
1713
1721
@@ -1730,6 +1738,7 @@ arc_buf_alloc_l2only(size_t size, arc_buf_contents_t type, l2arc_dev_t *dev,
1730
1738
1731
1739
hdr -> b_l2hdr .b_dev = dev ;
1732
1740
hdr -> b_l2hdr .b_daddr = daddr ;
1741
+ hdr -> b_l2hdr .b_arcs_state = arcs_state ;
1733
1742
1734
1743
return (hdr );
1735
1744
}
@@ -3661,6 +3670,68 @@ arc_alloc_raw_buf(spa_t *spa, void *tag, uint64_t dsobj, boolean_t byteorder,
3661
3670
return (buf );
3662
3671
}
3663
3672
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
+ /*
3700
+ * We use the value stored in the L2 header upon initial caching in
3701
+ * L2ARC. This is because we are interested in the state of the buffer
3702
+ * in ARC when it was cached in L2ARC for the first time. This also
3703
+ * solves the problem of a possibly absent L1 header.
3704
+ */
3705
+ switch (hdr -> b_l2hdr .b_arcs_state ) {
3706
+ case ARC_STATE_MRU :
3707
+ ARCSTAT_INCR (arcstat_l2_mru_asize , asize_s );
3708
+ break ;
3709
+ case ARC_STATE_MRU_GHOST :
3710
+ ARCSTAT_INCR (arcstat_l2_mru_ghost_asize , asize_s );
3711
+ break ;
3712
+ case ARC_STATE_MFU :
3713
+ ARCSTAT_INCR (arcstat_l2_mfu_asize , asize_s );
3714
+ break ;
3715
+ case ARC_STATE_MFU_GHOST :
3716
+ ARCSTAT_INCR (arcstat_l2_mfu_ghost_asize , asize_s );
3717
+ break ;
3718
+ default :
3719
+ break ;
3720
+ }
3721
+
3722
+ switch (type ) {
3723
+ case ARC_BUFC_DATA :
3724
+ ARCSTAT_INCR (arcstat_l2_bufc_data_asize , asize_s );
3725
+ break ;
3726
+ case ARC_BUFC_METADATA :
3727
+ ARCSTAT_INCR (arcstat_l2_bufc_metadata_asize , asize_s );
3728
+ break ;
3729
+ default :
3730
+ break ;
3731
+ }
3732
+ }
3733
+
3734
+
3664
3735
static void
3665
3736
arc_hdr_l2hdr_destroy (arc_buf_hdr_t * hdr )
3666
3737
{
@@ -3674,9 +3745,7 @@ arc_hdr_l2hdr_destroy(arc_buf_hdr_t *hdr)
3674
3745
3675
3746
list_remove (& dev -> l2ad_buflist , hdr );
3676
3747
3677
- ARCSTAT_INCR (arcstat_l2_psize , - psize );
3678
- ARCSTAT_INCR (arcstat_l2_lsize , - HDR_GET_LSIZE (hdr ));
3679
-
3748
+ l2arc_hdr_arcstats_update (hdr , B_FALSE );
3680
3749
vdev_space_update (dev -> l2ad_vdev , - asize , 0 , 0 );
3681
3750
3682
3751
(void ) zfs_refcount_remove_many (& dev -> l2ad_alloc , arc_hdr_size (hdr ),
@@ -8025,9 +8094,6 @@ l2arc_write_done(zio_t *zio)
8025
8094
DTRACE_PROBE2 (l2arc__iodone , zio_t * , zio ,
8026
8095
l2arc_write_callback_t * , cb );
8027
8096
8028
- if (zio -> io_error != 0 )
8029
- ARCSTAT_BUMP (arcstat_l2_writes_error );
8030
-
8031
8097
/*
8032
8098
* All writes completed, or an error was hit.
8033
8099
*/
@@ -8091,8 +8157,7 @@ l2arc_write_done(zio_t *zio)
8091
8157
arc_hdr_clear_flags (hdr , ARC_FLAG_HAS_L2HDR );
8092
8158
8093
8159
uint64_t psize = HDR_GET_PSIZE (hdr );
8094
- ARCSTAT_INCR (arcstat_l2_psize , - psize );
8095
- ARCSTAT_INCR (arcstat_l2_lsize , - HDR_GET_LSIZE (hdr ));
8160
+ l2arc_hdr_arcstats_update (hdr , B_FALSE );
8096
8161
8097
8162
bytes_dropped +=
8098
8163
vdev_psize_to_asize (dev -> l2ad_vdev , psize );
@@ -8140,6 +8205,8 @@ l2arc_write_done(zio_t *zio)
8140
8205
list_destroy (& cb -> l2wcb_abd_list );
8141
8206
8142
8207
if (zio -> io_error != 0 ) {
8208
+ ARCSTAT_BUMP (arcstat_l2_writes_error );
8209
+
8143
8210
/*
8144
8211
* Restore the lbps array in the header to its previous state.
8145
8212
* If the list of log block pointers is empty, zero out the
@@ -9024,6 +9091,8 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz)
9024
9091
hdr -> b_l2hdr .b_hits = 0 ;
9025
9092
9026
9093
hdr -> b_l2hdr .b_daddr = dev -> l2ad_hand ;
9094
+ hdr -> b_l2hdr .b_arcs_state =
9095
+ hdr -> b_l1hdr .b_state -> arcs_state ;
9027
9096
arc_hdr_set_flags (hdr , ARC_FLAG_HAS_L2HDR );
9028
9097
9029
9098
mutex_enter (& dev -> l2ad_mtx );
@@ -9046,6 +9115,7 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz)
9046
9115
write_psize += psize ;
9047
9116
write_asize += asize ;
9048
9117
dev -> l2ad_hand += asize ;
9118
+ l2arc_hdr_arcstats_update (hdr , B_TRUE );
9049
9119
vdev_space_update (dev -> l2ad_vdev , asize , 0 , 0 );
9050
9120
9051
9121
mutex_exit (hash_lock );
@@ -10023,19 +10093,18 @@ l2arc_hdr_restore(const l2arc_log_ent_phys_t *le, l2arc_dev_t *dev)
10023
10093
L2BLK_GET_PSIZE ((le )-> le_prop ), le -> le_birth ,
10024
10094
L2BLK_GET_COMPRESS ((le )-> le_prop ),
10025
10095
L2BLK_GET_PROTECTED ((le )-> le_prop ),
10026
- L2BLK_GET_PREFETCH ((le )-> le_prop ));
10096
+ L2BLK_GET_PREFETCH ((le )-> le_prop ),
10097
+ L2BLK_GET_STATE ((le )-> le_prop ));
10027
10098
asize = vdev_psize_to_asize (dev -> l2ad_vdev ,
10028
10099
L2BLK_GET_PSIZE ((le )-> le_prop ));
10029
10100
10030
10101
/*
10031
10102
* vdev_space_update() has to be called before arc_hdr_destroy() to
10032
- * avoid underflow since the latter also calls the former .
10103
+ * avoid underflow since the latter also calls vdev_space_update() .
10033
10104
*/
10105
+ l2arc_hdr_arcstats_update (hdr , B_TRUE );
10034
10106
vdev_space_update (dev -> l2ad_vdev , asize , 0 , 0 );
10035
10107
10036
- ARCSTAT_INCR (arcstat_l2_lsize , HDR_GET_LSIZE (hdr ));
10037
- ARCSTAT_INCR (arcstat_l2_psize , HDR_GET_PSIZE (hdr ));
10038
-
10039
10108
mutex_enter (& dev -> l2ad_mtx );
10040
10109
list_insert_tail (& dev -> l2ad_buflist , hdr );
10041
10110
(void ) zfs_refcount_add_many (& dev -> l2ad_alloc , arc_hdr_size (hdr ), hdr );
@@ -10055,14 +10124,15 @@ l2arc_hdr_restore(const l2arc_log_ent_phys_t *le, l2arc_dev_t *dev)
10055
10124
arc_hdr_set_flags (exists , ARC_FLAG_HAS_L2HDR );
10056
10125
exists -> b_l2hdr .b_dev = dev ;
10057
10126
exists -> b_l2hdr .b_daddr = le -> le_daddr ;
10127
+ exists -> b_l2hdr .b_arcs_state =
10128
+ L2BLK_GET_STATE ((le )-> le_prop );
10058
10129
mutex_enter (& dev -> l2ad_mtx );
10059
10130
list_insert_tail (& dev -> l2ad_buflist , exists );
10060
10131
(void ) zfs_refcount_add_many (& dev -> l2ad_alloc ,
10061
10132
arc_hdr_size (exists ), exists );
10062
10133
mutex_exit (& dev -> l2ad_mtx );
10134
+ l2arc_hdr_arcstats_update (exists , B_TRUE );
10063
10135
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 ));
10066
10136
}
10067
10137
ARCSTAT_BUMP (arcstat_l2_rebuild_bufs_precached );
10068
10138
}
@@ -10357,6 +10427,7 @@ l2arc_log_blk_insert(l2arc_dev_t *dev, const arc_buf_hdr_t *hdr)
10357
10427
L2BLK_SET_TYPE ((le )-> le_prop , hdr -> b_type );
10358
10428
L2BLK_SET_PROTECTED ((le )-> le_prop , !!(HDR_PROTECTED (hdr )));
10359
10429
L2BLK_SET_PREFETCH ((le )-> le_prop , !!(HDR_PREFETCH (hdr )));
10430
+ L2BLK_SET_STATE ((le )-> le_prop , hdr -> b_l1hdr .b_state -> arcs_state );
10360
10431
10361
10432
dev -> l2ad_log_blk_payload_asize += vdev_psize_to_asize (dev -> l2ad_vdev ,
10362
10433
HDR_GET_PSIZE (hdr ));
0 commit comments