Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More adaptive ARC eviction. #14359

Merged
merged 1 commit into from
Mar 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 71 additions & 30 deletions cmd/arc_summary
Original file line number Diff line number Diff line change
Expand Up @@ -270,16 +270,14 @@ def draw_graph(kstats_dict):
arc_perc = f_perc(arc_stats['size'], arc_stats['c_max'])
mfu_size = f_bytes(arc_stats['mfu_size'])
mru_size = f_bytes(arc_stats['mru_size'])
meta_limit = f_bytes(arc_stats['arc_meta_limit'])
meta_size = f_bytes(arc_stats['arc_meta_used'])
dnode_limit = f_bytes(arc_stats['arc_dnode_limit'])
dnode_size = f_bytes(arc_stats['dnode_size'])

info_form = ('ARC: {0} ({1}) MFU: {2} MRU: {3} META: {4} ({5}) '
'DNODE {6} ({7})')
info_form = ('ARC: {0} ({1}) MFU: {2} MRU: {3} META: {4} '
'DNODE {5} ({6})')
info_line = info_form.format(arc_size, arc_perc, mfu_size, mru_size,
meta_size, meta_limit, dnode_size,
dnode_limit)
meta_size, dnode_size, dnode_limit)
info_spc = ' '*int((GRAPH_WIDTH-len(info_line))/2)
info_line = GRAPH_INDENT+info_spc+info_line

Expand Down Expand Up @@ -558,16 +556,28 @@ def section_arc(kstats_dict):
arc_target_size = arc_stats['c']
arc_max = arc_stats['c_max']
arc_min = arc_stats['c_min']
anon_size = arc_stats['anon_size']
mfu_size = arc_stats['mfu_size']
mru_size = arc_stats['mru_size']
mfug_size = arc_stats['mfu_ghost_size']
mrug_size = arc_stats['mru_ghost_size']
unc_size = arc_stats['uncached_size']
meta_limit = arc_stats['arc_meta_limit']
meta_size = arc_stats['arc_meta_used']
meta = arc_stats['meta']
pd = arc_stats['pd']
pm = arc_stats['pm']
anon_data = arc_stats['anon_data']
anon_metadata = arc_stats['anon_metadata']
mfu_data = arc_stats['mfu_data']
mfu_metadata = arc_stats['mfu_metadata']
mru_data = arc_stats['mru_data']
mru_metadata = arc_stats['mru_metadata']
mfug_data = arc_stats['mfu_ghost_data']
mfug_metadata = arc_stats['mfu_ghost_metadata']
mrug_data = arc_stats['mru_ghost_data']
mrug_metadata = arc_stats['mru_ghost_metadata']
unc_data = arc_stats['uncached_data']
unc_metadata = arc_stats['uncached_metadata']
bonus_size = arc_stats['bonus_size']
dnode_limit = arc_stats['arc_dnode_limit']
dnode_size = arc_stats['dnode_size']
dbuf_size = arc_stats['dbuf_size']
hdr_size = arc_stats['hdr_size']
l2_hdr_size = arc_stats['l2_hdr_size']
abd_chunk_waste_size = arc_stats['abd_chunk_waste_size']
target_size_ratio = '{0}:1'.format(int(arc_max) // int(arc_min))

prt_2('ARC size (current):',
Expand All @@ -578,25 +588,56 @@ def section_arc(kstats_dict):
f_perc(arc_min, arc_max), f_bytes(arc_min))
prt_i2('Max size (high water):',
target_size_ratio, f_bytes(arc_max))
caches_size = int(anon_size)+int(mfu_size)+int(mru_size)+int(unc_size)
prt_i2('Anonymouns data size:',
f_perc(anon_size, caches_size), f_bytes(anon_size))
prt_i2('Most Frequently Used (MFU) cache size:',
f_perc(mfu_size, caches_size), f_bytes(mfu_size))
prt_i2('Most Recently Used (MRU) cache size:',
f_perc(mru_size, caches_size), f_bytes(mru_size))
prt_i1('Most Frequently Used (MFU) ghost size:', f_bytes(mfug_size))
prt_i1('Most Recently Used (MRU) ghost size:', f_bytes(mrug_size))
caches_size = int(anon_data)+int(anon_metadata)+\
int(mfu_data)+int(mfu_metadata)+int(mru_data)+int(mru_metadata)+\
int(unc_data)+int(unc_metadata)
prt_i2('Anonymous data size:',
f_perc(anon_data, caches_size), f_bytes(anon_data))
prt_i2('Anonymous metadata size:',
f_perc(anon_metadata, caches_size), f_bytes(anon_metadata))
s = 4294967296
v = (s-int(pd))*(s-int(meta))/s
prt_i2('MFU data target:', f_perc(v, s),
f_bytes(v / 65536 * caches_size / 65536))
prt_i2('MFU data size:',
f_perc(mfu_data, caches_size), f_bytes(mfu_data))
prt_i1('MFU ghost data size:', f_bytes(mfug_data))
v = (s-int(pm))*int(meta)/s
prt_i2('MFU metadata target:', f_perc(v, s),
f_bytes(v / 65536 * caches_size / 65536))
prt_i2('MFU metadata size:',
f_perc(mfu_metadata, caches_size), f_bytes(mfu_metadata))
prt_i1('MFU ghost metadata size:', f_bytes(mfug_metadata))
v = int(pd)*(s-int(meta))/s
prt_i2('MRU data target:', f_perc(v, s),
f_bytes(v / 65536 * caches_size / 65536))
prt_i2('MRU data size:',
f_perc(mru_data, caches_size), f_bytes(mru_data))
prt_i1('MRU ghost data size:', f_bytes(mrug_data))
v = int(pm)*int(meta)/s
prt_i2('MRU metadata target:', f_perc(v, s),
f_bytes(v / 65536 * caches_size / 65536))
prt_i2('MRU metadata size:',
f_perc(mru_metadata, caches_size), f_bytes(mru_metadata))
prt_i1('MRU ghost metadata size:', f_bytes(mrug_metadata))
prt_i2('Uncached data size:',
f_perc(unc_size, caches_size), f_bytes(unc_size))
prt_i2('Metadata cache size (hard limit):',
f_perc(meta_limit, arc_max), f_bytes(meta_limit))
prt_i2('Metadata cache size (current):',
f_perc(meta_size, meta_limit), f_bytes(meta_size))
prt_i2('Dnode cache size (hard limit):',
f_perc(dnode_limit, meta_limit), f_bytes(dnode_limit))
prt_i2('Dnode cache size (current):',
f_perc(unc_data, caches_size), f_bytes(unc_data))
prt_i2('Uncached metadata size:',
f_perc(unc_metadata, caches_size), f_bytes(unc_metadata))
prt_i2('Bonus size:',
f_perc(bonus_size, arc_size), f_bytes(bonus_size))
prt_i2('Dnode cache target:',
f_perc(dnode_limit, arc_max), f_bytes(dnode_limit))
prt_i2('Dnode cache size:',
f_perc(dnode_size, dnode_limit), f_bytes(dnode_size))
prt_i2('Dbuf size:',
f_perc(dbuf_size, arc_size), f_bytes(dbuf_size))
prt_i2('Header size:',
f_perc(hdr_size, arc_size), f_bytes(hdr_size))
prt_i2('L2 header size:',
f_perc(l2_hdr_size, arc_size), f_bytes(l2_hdr_size))
prt_i2('ABD chunk waste size:',
f_perc(abd_chunk_waste_size, arc_size), f_bytes(abd_chunk_waste_size))
print()

print('ARC hash breakdown:')
Expand Down
5 changes: 2 additions & 3 deletions cmd/zdb/zdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@ zdb_ot_name(dmu_object_type_t type)

extern int reference_tracking_enable;
extern int zfs_recover;
extern unsigned long zfs_arc_meta_min, zfs_arc_meta_limit;
extern uint_t zfs_vdev_async_read_max_active;
extern boolean_t spa_load_verify_dryrun;
extern boolean_t spa_mode_readable_spacemaps;
Expand Down Expand Up @@ -8808,8 +8807,8 @@ main(int argc, char **argv)
* ZDB does not typically re-read blocks; therefore limit the ARC
* to 256 MB, which can be used entirely for metadata.
*/
zfs_arc_min = zfs_arc_meta_min = 2ULL << SPA_MAXBLOCKSHIFT;
zfs_arc_max = zfs_arc_meta_limit = 256 * 1024 * 1024;
zfs_arc_min = 2ULL << SPA_MAXBLOCKSHIFT;
zfs_arc_max = 256 * 1024 * 1024;
#endif

/*
Expand Down
1 change: 0 additions & 1 deletion include/sys/arc.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,6 @@ struct arc_buf {
};

typedef enum arc_buf_contents {
ARC_BUFC_INVALID, /* invalid type */
ARC_BUFC_DATA, /* buffer contains data */
ARC_BUFC_METADATA, /* buffer contains metadata */
ARC_BUFC_NUMTYPES
Expand Down
43 changes: 30 additions & 13 deletions include/sys/arc_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,15 +82,18 @@ typedef struct arc_state {
* supports the "dbufs" kstat
*/
arc_state_type_t arcs_state;
/*
* total amount of data in this state.
*/
zfs_refcount_t arcs_size[ARC_BUFC_NUMTYPES] ____cacheline_aligned;
/*
* total amount of evictable data in this state
*/
zfs_refcount_t arcs_esize[ARC_BUFC_NUMTYPES] ____cacheline_aligned;
zfs_refcount_t arcs_esize[ARC_BUFC_NUMTYPES];
/*
* total amount of data in this state; this includes: evictable,
* non-evictable, ARC_BUFC_DATA, and ARC_BUFC_METADATA.
* amount of hit bytes for this state (counted only for ghost states)
*/
zfs_refcount_t arcs_size;
wmsum_t arcs_hits[ARC_BUFC_NUMTYPES];
amotin marked this conversation as resolved.
Show resolved Hide resolved
} arc_state_t;

typedef struct arc_callback arc_callback_t;
Expand Down Expand Up @@ -358,8 +361,9 @@ typedef struct l2arc_lb_ptr_buf {
#define L2BLK_SET_PREFETCH(field, x) BF64_SET((field), 39, 1, x)
#define L2BLK_GET_CHECKSUM(field) BF64_GET((field), 40, 8)
#define L2BLK_SET_CHECKSUM(field, x) BF64_SET((field), 40, 8, x)
#define L2BLK_GET_TYPE(field) BF64_GET((field), 48, 8)
#define L2BLK_SET_TYPE(field, x) BF64_SET((field), 48, 8, x)
/* +/- 1 here are to keep compatibility after ARC_BUFC_INVALID removal. */
#define L2BLK_GET_TYPE(field) (BF64_GET((field), 48, 8) - 1)
#define L2BLK_SET_TYPE(field, x) BF64_SET((field), 48, 8, (x) + 1)
amotin marked this conversation as resolved.
Show resolved Hide resolved
#define L2BLK_GET_PROTECTED(field) BF64_GET((field), 56, 1)
#define L2BLK_SET_PROTECTED(field, x) BF64_SET((field), 56, 1, x)
#define L2BLK_GET_STATE(field) BF64_GET((field), 57, 4)
Expand Down Expand Up @@ -582,7 +586,9 @@ typedef struct arc_stats {
kstat_named_t arcstat_hash_collisions;
kstat_named_t arcstat_hash_chains;
kstat_named_t arcstat_hash_chain_max;
kstat_named_t arcstat_p;
kstat_named_t arcstat_meta;
kstat_named_t arcstat_pd;
kstat_named_t arcstat_pm;
kstat_named_t arcstat_c;
kstat_named_t arcstat_c_min;
kstat_named_t arcstat_c_max;
Expand Down Expand Up @@ -655,6 +661,8 @@ typedef struct arc_stats {
* are all included in this value.
*/
kstat_named_t arcstat_anon_size;
kstat_named_t arcstat_anon_data;
kstat_named_t arcstat_anon_metadata;
/*
* Number of bytes consumed by ARC buffers that meet the
* following criteria: backing buffers of type ARC_BUFC_DATA,
Expand All @@ -676,6 +684,8 @@ typedef struct arc_stats {
* are all included in this value.
*/
kstat_named_t arcstat_mru_size;
kstat_named_t arcstat_mru_data;
kstat_named_t arcstat_mru_metadata;
/*
* Number of bytes consumed by ARC buffers that meet the
* following criteria: backing buffers of type ARC_BUFC_DATA,
Expand All @@ -700,6 +710,8 @@ typedef struct arc_stats {
* buffers *would have* consumed this number of bytes.
*/
kstat_named_t arcstat_mru_ghost_size;
kstat_named_t arcstat_mru_ghost_data;
kstat_named_t arcstat_mru_ghost_metadata;
/*
* Number of bytes that *would have been* consumed by ARC
* buffers that are eligible for eviction, of type
Expand All @@ -719,6 +731,8 @@ typedef struct arc_stats {
* are all included in this value.
*/
kstat_named_t arcstat_mfu_size;
kstat_named_t arcstat_mfu_data;
kstat_named_t arcstat_mfu_metadata;
/*
* Number of bytes consumed by ARC buffers that are eligible for
* eviction, of type ARC_BUFC_DATA, and reside in the arc_mfu
Expand All @@ -737,6 +751,8 @@ typedef struct arc_stats {
* arcstat_mru_ghost_size for more details.
*/
kstat_named_t arcstat_mfu_ghost_size;
kstat_named_t arcstat_mfu_ghost_data;
kstat_named_t arcstat_mfu_ghost_metadata;
/*
* Number of bytes that *would have been* consumed by ARC
* buffers that are eligible for eviction, of type
Expand All @@ -754,6 +770,8 @@ typedef struct arc_stats {
* ARC_FLAG_UNCACHED being set.
*/
kstat_named_t arcstat_uncached_size;
kstat_named_t arcstat_uncached_data;
kstat_named_t arcstat_uncached_metadata;
/*
* Number of data bytes that are going to be evicted from ARC due to
* ARC_FLAG_UNCACHED being set.
Expand Down Expand Up @@ -876,10 +894,7 @@ typedef struct arc_stats {
kstat_named_t arcstat_loaned_bytes;
kstat_named_t arcstat_prune;
kstat_named_t arcstat_meta_used;
kstat_named_t arcstat_meta_limit;
kstat_named_t arcstat_dnode_limit;
kstat_named_t arcstat_meta_max;
kstat_named_t arcstat_meta_min;
kstat_named_t arcstat_async_upgrade_sync;
/* Number of predictive prefetch requests. */
kstat_named_t arcstat_predictive_prefetch;
Expand Down Expand Up @@ -942,7 +957,7 @@ typedef struct arc_sums {
wmsum_t arcstat_data_size;
wmsum_t arcstat_metadata_size;
wmsum_t arcstat_dbuf_size;
aggsum_t arcstat_dnode_size;
wmsum_t arcstat_dnode_size;
wmsum_t arcstat_bonus_size;
wmsum_t arcstat_l2_hits;
wmsum_t arcstat_l2_misses;
Expand Down Expand Up @@ -987,7 +1002,7 @@ typedef struct arc_sums {
wmsum_t arcstat_memory_direct_count;
wmsum_t arcstat_memory_indirect_count;
wmsum_t arcstat_prune;
aggsum_t arcstat_meta_used;
wmsum_t arcstat_meta_used;
wmsum_t arcstat_async_upgrade_sync;
wmsum_t arcstat_predictive_prefetch;
wmsum_t arcstat_demand_hit_predictive_prefetch;
Expand Down Expand Up @@ -1015,7 +1030,9 @@ typedef struct arc_evict_waiter {
#define ARCSTAT_BUMPDOWN(stat) ARCSTAT_INCR(stat, -1)

#define arc_no_grow ARCSTAT(arcstat_no_grow) /* do not grow cache size */
#define arc_p ARCSTAT(arcstat_p) /* target size of MRU */
#define arc_meta ARCSTAT(arcstat_meta) /* target frac of metadata */
amotin marked this conversation as resolved.
Show resolved Hide resolved
#define arc_pd ARCSTAT(arcstat_pd) /* target frac of data MRU */
#define arc_pm ARCSTAT(arcstat_pm) /* target frac of meta MRU */
#define arc_c ARCSTAT(arcstat_c) /* target size of cache */
#define arc_c_min ARCSTAT(arcstat_c_min) /* min target cache size */
#define arc_c_max ARCSTAT(arcstat_c_max) /* max target cache size */
Expand Down
Loading