3 #define ZFS_PROC_ARCSTATS "/proc/spl/kstat/zfs/arcstats"
4 #define ZFS_FAMILY_SIZE "size"
5 #define ZFS_FAMILY_EFFICIENCY "efficiency"
6 #define ZFS_FAMILY_ACCESSES "accesses"
7 #define ZFS_FAMILY_OPERATIONS "operations"
8 #define ZFS_FAMILY_HASH "hashes"
10 static struct arcstats {
11 unsigned long long hits;
12 unsigned long long misses;
13 unsigned long long demand_data_hits;
14 unsigned long long demand_data_misses;
15 unsigned long long demand_metadata_hits;
16 unsigned long long demand_metadata_misses;
17 unsigned long long prefetch_data_hits;
18 unsigned long long prefetch_data_misses;
19 unsigned long long prefetch_metadata_hits;
20 unsigned long long prefetch_metadata_misses;
21 unsigned long long mru_hits;
22 unsigned long long mru_ghost_hits;
23 unsigned long long mfu_hits;
24 unsigned long long mfu_ghost_hits;
25 unsigned long long deleted;
26 unsigned long long mutex_miss;
27 unsigned long long evict_skip;
28 unsigned long long evict_not_enough;
29 unsigned long long evict_l2_cached;
30 unsigned long long evict_l2_eligible;
31 unsigned long long evict_l2_ineligible;
32 unsigned long long evict_l2_skip;
33 unsigned long long hash_elements;
34 unsigned long long hash_elements_max;
35 unsigned long long hash_collisions;
36 unsigned long long hash_chains;
37 unsigned long long hash_chain_max;
40 unsigned long long c_min;
41 unsigned long long c_max;
42 unsigned long long size;
43 unsigned long long hdr_size;
44 unsigned long long data_size;
45 unsigned long long metadata_size;
46 unsigned long long other_size;
47 unsigned long long anon_size;
48 unsigned long long anon_evictable_data;
49 unsigned long long anon_evictable_metadata;
50 unsigned long long mru_size;
51 unsigned long long mru_evictable_data;
52 unsigned long long mru_evictable_metadata;
53 unsigned long long mru_ghost_size;
54 unsigned long long mru_ghost_evictable_data;
55 unsigned long long mru_ghost_evictable_metadata;
56 unsigned long long mfu_size;
57 unsigned long long mfu_evictable_data;
58 unsigned long long mfu_evictable_metadata;
59 unsigned long long mfu_ghost_size;
60 unsigned long long mfu_ghost_evictable_data;
61 unsigned long long mfu_ghost_evictable_metadata;
62 unsigned long long l2_hits;
63 unsigned long long l2_misses;
64 unsigned long long l2_feeds;
65 unsigned long long l2_rw_clash;
66 unsigned long long l2_read_bytes;
67 unsigned long long l2_write_bytes;
68 unsigned long long l2_writes_sent;
69 unsigned long long l2_writes_done;
70 unsigned long long l2_writes_error;
71 unsigned long long l2_writes_lock_retry;
72 unsigned long long l2_evict_lock_retry;
73 unsigned long long l2_evict_reading;
74 unsigned long long l2_evict_l1cached;
75 unsigned long long l2_free_on_write;
76 unsigned long long l2_cdata_free_on_write;
77 unsigned long long l2_abort_lowmem;
78 unsigned long long l2_cksum_bad;
79 unsigned long long l2_io_error;
80 unsigned long long l2_size;
81 unsigned long long l2_asize;
82 unsigned long long l2_hdr_size;
83 unsigned long long l2_compress_successes;
84 unsigned long long l2_compress_zeros;
85 unsigned long long l2_compress_failures;
86 unsigned long long memory_throttle_count;
87 unsigned long long duplicate_buffers;
88 unsigned long long duplicate_buffers_size;
89 unsigned long long duplicate_reads;
90 unsigned long long memory_direct_count;
91 unsigned long long memory_indirect_count;
92 unsigned long long arc_no_grow;
93 unsigned long long arc_tempreserve;
94 unsigned long long arc_loaned_bytes;
95 unsigned long long arc_prune;
96 unsigned long long arc_meta_used;
97 unsigned long long arc_meta_limit;
98 unsigned long long arc_meta_max;
99 unsigned long long arc_meta_min;
100 unsigned long long arc_need_free;
101 unsigned long long arc_sys_free;
106 static void generate_charts_arcstats(int update_every) {
109 unsigned long long aread = arcstats.hits + arcstats.misses;
112 unsigned long long dhit = arcstats.demand_data_hits + arcstats.demand_metadata_hits;
113 unsigned long long dmiss = arcstats.demand_data_misses + arcstats.demand_metadata_misses;
114 unsigned long long dread = dhit + dmiss;
117 unsigned long long phit = arcstats.prefetch_data_hits + arcstats.prefetch_metadata_hits;
118 unsigned long long pmiss = arcstats.prefetch_data_misses + arcstats.prefetch_metadata_misses;
119 unsigned long long pread = phit + pmiss;
122 unsigned long long mhit = arcstats.prefetch_metadata_hits + arcstats.demand_metadata_hits;
123 unsigned long long mmiss = arcstats.prefetch_metadata_misses + arcstats.demand_metadata_misses;
124 unsigned long long mread = mhit + mmiss;
127 unsigned long long l2hit = arcstats.l2_hits + arcstats.l2_misses;
128 unsigned long long l2miss = arcstats.prefetch_metadata_misses + arcstats.demand_metadata_misses;
129 unsigned long long l2read = l2hit + l2miss;
131 // --------------------------------------------------------------------
134 static RRDSET *st_arc_size = NULL;
135 static RRDDIM *rd_arc_size = NULL;
136 static RRDDIM *rd_arc_target_size = NULL;
137 static RRDDIM *rd_arc_target_min_size = NULL;
138 static RRDDIM *rd_arc_target_max_size = NULL;
140 if (unlikely(!st_arc_size)) {
141 st_arc_size = rrdset_create_localhost(
154 rd_arc_size = rrddim_add(st_arc_size, "size", "arcsz", 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
155 rd_arc_target_size = rrddim_add(st_arc_size, "target", NULL, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
156 rd_arc_target_min_size = rrddim_add(st_arc_size, "min", "min (hard limit)", 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
157 rd_arc_target_max_size = rrddim_add(st_arc_size, "max", "max (high water)", 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
160 rrdset_next(st_arc_size);
162 rrddim_set_by_pointer(st_arc_size, rd_arc_size, arcstats.size);
163 rrddim_set_by_pointer(st_arc_size, rd_arc_target_size, arcstats.c);
164 rrddim_set_by_pointer(st_arc_size, rd_arc_target_min_size, arcstats.c_min);
165 rrddim_set_by_pointer(st_arc_size, rd_arc_target_max_size, arcstats.c_max);
166 rrdset_done(st_arc_size);
169 // --------------------------------------------------------------------
171 if(likely(l2exist)) {
172 static RRDSET *st_l2_size = NULL;
173 static RRDDIM *rd_l2_size = NULL;
174 static RRDDIM *rd_l2_asize = NULL;
176 if (unlikely(!st_l2_size)) {
177 st_l2_size = rrdset_create_localhost(
190 rd_l2_asize = rrddim_add(st_l2_size, "actual", NULL, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
191 rd_l2_size = rrddim_add(st_l2_size, "size", NULL, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
194 rrdset_next(st_l2_size);
196 rrddim_set_by_pointer(st_l2_size, rd_l2_size, arcstats.l2_size);
197 rrddim_set_by_pointer(st_l2_size, rd_l2_asize, arcstats.l2_asize);
198 rrdset_done(st_l2_size);
201 // --------------------------------------------------------------------
204 static RRDSET *st_reads = NULL;
205 static RRDDIM *rd_aread = NULL;
206 static RRDDIM *rd_dread = NULL;
207 static RRDDIM *rd_pread = NULL;
208 static RRDDIM *rd_mread = NULL;
209 static RRDDIM *rd_l2read = NULL;
211 if (unlikely(!st_reads)) {
212 st_reads = rrdset_create_localhost(
216 , ZFS_FAMILY_ACCESSES
225 rd_aread = rrddim_add(st_reads, "areads", "arc", 1, 1, RRD_ALGORITHM_INCREMENTAL);
226 rd_dread = rrddim_add(st_reads, "dreads", "demand", 1, 1, RRD_ALGORITHM_INCREMENTAL);
227 rd_pread = rrddim_add(st_reads, "preads", "prefetch", 1, 1, RRD_ALGORITHM_INCREMENTAL);
228 rd_mread = rrddim_add(st_reads, "mreads", "metadata", 1, 1, RRD_ALGORITHM_INCREMENTAL);
231 rd_l2read = rrddim_add(st_reads, "l2reads", "l2", 1, 1, RRD_ALGORITHM_INCREMENTAL);
234 rrdset_next(st_reads);
236 rrddim_set_by_pointer(st_reads, rd_aread, aread);
237 rrddim_set_by_pointer(st_reads, rd_dread, dread);
238 rrddim_set_by_pointer(st_reads, rd_pread, pread);
239 rrddim_set_by_pointer(st_reads, rd_mread, mread);
242 rrddim_set_by_pointer(st_reads, rd_l2read, l2read);
244 rrdset_done(st_reads);
247 // --------------------------------------------------------------------
249 if(likely(l2exist)) {
250 static RRDSET *st_l2bytes = NULL;
251 static RRDDIM *rd_l2_read_bytes = NULL;
252 static RRDDIM *rd_l2_write_bytes = NULL;
254 if (unlikely(!st_l2bytes)) {
255 st_l2bytes = rrdset_create_localhost(
259 , ZFS_FAMILY_ACCESSES
261 , "ZFS ARC L2 Read/Write Rate"
268 rd_l2_read_bytes = rrddim_add(st_l2bytes, "read", NULL, 1, 1024, RRD_ALGORITHM_INCREMENTAL);
269 rd_l2_write_bytes = rrddim_add(st_l2bytes, "write", NULL, -1, 1024, RRD_ALGORITHM_INCREMENTAL);
272 rrdset_next(st_l2bytes);
274 rrddim_set_by_pointer(st_l2bytes, rd_l2_read_bytes, arcstats.l2_read_bytes);
275 rrddim_set_by_pointer(st_l2bytes, rd_l2_write_bytes, arcstats.l2_write_bytes);
276 rrdset_done(st_l2bytes);
279 // --------------------------------------------------------------------
282 static RRDSET *st_ahits = NULL;
283 static RRDDIM *rd_ahits = NULL;
284 static RRDDIM *rd_amisses = NULL;
286 if (unlikely(!st_ahits)) {
287 st_ahits = rrdset_create_localhost(
291 , ZFS_FAMILY_EFFICIENCY
297 , RRDSET_TYPE_STACKED
300 rd_ahits = rrddim_add(st_ahits, "hits", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
301 rd_amisses = rrddim_add(st_ahits, "misses", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
304 rrdset_next(st_ahits);
306 rrddim_set_by_pointer(st_ahits, rd_ahits, arcstats.hits);
307 rrddim_set_by_pointer(st_ahits, rd_amisses, arcstats.misses);
308 rrdset_done(st_ahits);
311 // --------------------------------------------------------------------
314 static RRDSET *st_dhits = NULL;
315 static RRDDIM *rd_dhits = NULL;
316 static RRDDIM *rd_dmisses = NULL;
318 if (unlikely(!st_dhits)) {
319 st_dhits = rrdset_create_localhost(
323 , ZFS_FAMILY_EFFICIENCY
329 , RRDSET_TYPE_STACKED
332 rd_dhits = rrddim_add(st_dhits, "hits", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
333 rd_dmisses = rrddim_add(st_dhits, "misses", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
336 rrdset_next(st_dhits);
338 rrddim_set_by_pointer(st_dhits, rd_dhits, dhit);
339 rrddim_set_by_pointer(st_dhits, rd_dmisses, dmiss);
340 rrdset_done(st_dhits);
343 // --------------------------------------------------------------------
346 static RRDSET *st_phits = NULL;
347 static RRDDIM *rd_phits = NULL;
348 static RRDDIM *rd_pmisses = NULL;
350 if (unlikely(!st_phits)) {
351 st_phits = rrdset_create_localhost(
355 , ZFS_FAMILY_EFFICIENCY
357 , "ZFS Prefetch Hits"
361 , RRDSET_TYPE_STACKED
364 rd_phits = rrddim_add(st_phits, "hits", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
365 rd_pmisses = rrddim_add(st_phits, "misses", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
368 rrdset_next(st_phits);
370 rrddim_set_by_pointer(st_phits, rd_phits, phit);
371 rrddim_set_by_pointer(st_phits, rd_pmisses, pmiss);
372 rrdset_done(st_phits);
375 // --------------------------------------------------------------------
378 static RRDSET *st_mhits = NULL;
379 static RRDDIM *rd_mhits = NULL;
380 static RRDDIM *rd_mmisses = NULL;
382 if (unlikely(!st_mhits)) {
383 st_mhits = rrdset_create_localhost(
387 , ZFS_FAMILY_EFFICIENCY
389 , "ZFS Metadata Hits"
393 , RRDSET_TYPE_STACKED
396 rd_mhits = rrddim_add(st_mhits, "hits", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
397 rd_mmisses = rrddim_add(st_mhits, "misses", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
400 rrdset_next(st_mhits);
402 rrddim_set_by_pointer(st_mhits, rd_mhits, mhit);
403 rrddim_set_by_pointer(st_mhits, rd_mmisses, mmiss);
404 rrdset_done(st_mhits);
407 // --------------------------------------------------------------------
409 if(likely(l2exist)) {
410 static RRDSET *st_l2hits = NULL;
411 static RRDDIM *rd_l2hits = NULL;
412 static RRDDIM *rd_l2misses = NULL;
414 if (unlikely(!st_l2hits)) {
415 st_l2hits = rrdset_create_localhost(
419 , ZFS_FAMILY_EFFICIENCY
425 , RRDSET_TYPE_STACKED
428 rd_l2hits = rrddim_add(st_l2hits, "hits", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
429 rd_l2misses = rrddim_add(st_l2hits, "misses", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
432 rrdset_next(st_l2hits);
434 rrddim_set_by_pointer(st_l2hits, rd_l2hits, l2hit);
435 rrddim_set_by_pointer(st_l2hits, rd_l2misses, l2miss);
436 rrdset_done(st_l2hits);
439 // --------------------------------------------------------------------
442 static RRDSET *st_list_hits = NULL;
443 static RRDDIM *rd_mfu = NULL;
444 static RRDDIM *rd_mru = NULL;
445 static RRDDIM *rd_mfug = NULL;
446 static RRDDIM *rd_mrug = NULL;
448 if (unlikely(!st_list_hits)) {
449 st_list_hits = rrdset_create_localhost(
453 , ZFS_FAMILY_EFFICIENCY
462 rd_mfu = rrddim_add(st_list_hits, "mfu", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
463 rd_mfug = rrddim_add(st_list_hits, "mfug", "mfu ghost", 1, 1, RRD_ALGORITHM_INCREMENTAL);
464 rd_mru = rrddim_add(st_list_hits, "mru", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
465 rd_mrug = rrddim_add(st_list_hits, "mrug", "mru ghost", 1, 1, RRD_ALGORITHM_INCREMENTAL);
468 rrdset_next(st_list_hits);
470 rrddim_set_by_pointer(st_list_hits, rd_mfu, arcstats.mfu_hits);
471 rrddim_set_by_pointer(st_list_hits, rd_mru, arcstats.mru_hits);
472 rrddim_set_by_pointer(st_list_hits, rd_mfug, arcstats.mfu_ghost_hits);
473 rrddim_set_by_pointer(st_list_hits, rd_mrug, arcstats.mru_ghost_hits);
474 rrdset_done(st_list_hits);
478 static void generate_charts_arc_summary(int update_every) {
479 unsigned long long arc_accesses_total = arcstats.hits + arcstats.misses;
480 unsigned long long real_hits = arcstats.mfu_hits + arcstats.mru_hits;
481 unsigned long long real_misses = arc_accesses_total - real_hits;
483 //unsigned long long anon_hits = arcstats.hits - (arcstats.mfu_hits + arcstats.mru_hits + arcstats.mfu_ghost_hits + arcstats.mru_ghost_hits);
485 unsigned long long arc_size = arcstats.size;
486 unsigned long long mru_size = arcstats.p;
487 //unsigned long long target_min_size = arcstats.c_min;
488 //unsigned long long target_max_size = arcstats.c_max;
489 unsigned long long target_size = arcstats.c;
490 //unsigned long long target_size_ratio = (target_max_size / target_min_size);
492 unsigned long long mfu_size;
493 if(arc_size > target_size)
494 mfu_size = arc_size - mru_size;
496 mfu_size = target_size - mru_size;
498 // --------------------------------------------------------------------
501 static RRDSET *st_arc_size_breakdown = NULL;
502 static RRDDIM *rd_most_recent = NULL;
503 static RRDDIM *rd_most_frequent = NULL;
505 if (unlikely(!st_arc_size_breakdown)) {
506 st_arc_size_breakdown = rrdset_create_localhost(
508 , "arc_size_breakdown"
510 , ZFS_FAMILY_EFFICIENCY
512 , "ZFS ARC Size Breakdown"
516 , RRDSET_TYPE_STACKED
519 rd_most_recent = rrddim_add(st_arc_size_breakdown, "recent", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_ROW_TOTAL);
520 rd_most_frequent = rrddim_add(st_arc_size_breakdown, "frequent", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_ROW_TOTAL);
523 rrdset_next(st_arc_size_breakdown);
525 rrddim_set_by_pointer(st_arc_size_breakdown, rd_most_recent, mru_size);
526 rrddim_set_by_pointer(st_arc_size_breakdown, rd_most_frequent, mfu_size);
527 rrdset_done(st_arc_size_breakdown);
530 // --------------------------------------------------------------------
533 static RRDSET *st_memory = NULL;
534 static RRDDIM *rd_direct = NULL;
535 static RRDDIM *rd_throttled = NULL;
536 static RRDDIM *rd_indirect = NULL;
538 if (unlikely(!st_memory)) {
539 st_memory = rrdset_create_localhost(
543 , ZFS_FAMILY_OPERATIONS
545 , "ZFS Memory Operations"
552 rd_direct = rrddim_add(st_memory, "direct", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
553 rd_throttled = rrddim_add(st_memory, "throttled", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
554 rd_indirect = rrddim_add(st_memory, "indirect", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
557 rrdset_next(st_memory);
559 rrddim_set_by_pointer(st_memory, rd_direct, arcstats.memory_direct_count);
560 rrddim_set_by_pointer(st_memory, rd_throttled, arcstats.memory_throttle_count);
561 rrddim_set_by_pointer(st_memory, rd_indirect, arcstats.memory_indirect_count);
562 rrdset_done(st_memory);
565 // --------------------------------------------------------------------
568 static RRDSET *st_important_ops = NULL;
569 static RRDDIM *rd_deleted = NULL;
570 static RRDDIM *rd_mutex_misses = NULL;
571 static RRDDIM *rd_evict_skips = NULL;
572 static RRDDIM *rd_hash_collisions = NULL;
574 if (unlikely(!st_important_ops)) {
575 st_important_ops = rrdset_create_localhost(
579 , ZFS_FAMILY_OPERATIONS
581 , "ZFS Important Operations"
588 rd_evict_skips = rrddim_add(st_important_ops, "eskip", "evict skip", 1, 1, RRD_ALGORITHM_INCREMENTAL);
589 rd_deleted = rrddim_add(st_important_ops, "deleted", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
590 rd_mutex_misses = rrddim_add(st_important_ops, "mtxmis", "mutex miss", 1, 1, RRD_ALGORITHM_INCREMENTAL);
591 rd_hash_collisions = rrddim_add(st_important_ops, "hash_collisions", "hash collisions", 1, 1, RRD_ALGORITHM_INCREMENTAL);
594 rrdset_next(st_important_ops);
596 rrddim_set_by_pointer(st_important_ops, rd_deleted, arcstats.deleted);
597 rrddim_set_by_pointer(st_important_ops, rd_evict_skips, arcstats.evict_skip);
598 rrddim_set_by_pointer(st_important_ops, rd_mutex_misses, arcstats.mutex_miss);
599 rrddim_set_by_pointer(st_important_ops, rd_hash_collisions, arcstats.hash_collisions);
600 rrdset_done(st_important_ops);
603 // --------------------------------------------------------------------
606 static RRDSET *st_actual_hits = NULL;
607 static RRDDIM *rd_actual_hits = NULL;
608 static RRDDIM *rd_actual_misses = NULL;
610 if (unlikely(!st_actual_hits)) {
611 st_actual_hits = rrdset_create_localhost(
615 , ZFS_FAMILY_EFFICIENCY
617 , "ZFS Actual Cache Hits"
621 , RRDSET_TYPE_STACKED
624 rd_actual_hits = rrddim_add(st_actual_hits, "hits", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
625 rd_actual_misses = rrddim_add(st_actual_hits, "misses", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
628 rrdset_next(st_actual_hits);
630 rrddim_set_by_pointer(st_actual_hits, rd_actual_hits, real_hits);
631 rrddim_set_by_pointer(st_actual_hits, rd_actual_misses, real_misses);
632 rrdset_done(st_actual_hits);
635 // --------------------------------------------------------------------
638 static RRDSET *st_demand_data_hits = NULL;
639 static RRDDIM *rd_demand_data_hits = NULL;
640 static RRDDIM *rd_demand_data_misses = NULL;
642 if (unlikely(!st_demand_data_hits)) {
643 st_demand_data_hits = rrdset_create_localhost(
647 , ZFS_FAMILY_EFFICIENCY
649 , "ZFS Data Demand Efficiency"
653 , RRDSET_TYPE_STACKED
656 rd_demand_data_hits = rrddim_add(st_demand_data_hits, "hits", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
657 rd_demand_data_misses = rrddim_add(st_demand_data_hits, "misses", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
660 rrdset_next(st_demand_data_hits);
662 rrddim_set_by_pointer(st_demand_data_hits, rd_demand_data_hits, arcstats.demand_data_hits);
663 rrddim_set_by_pointer(st_demand_data_hits, rd_demand_data_misses, arcstats.demand_data_misses);
664 rrdset_done(st_demand_data_hits);
667 // --------------------------------------------------------------------
670 static RRDSET *st_prefetch_data_hits = NULL;
671 static RRDDIM *rd_prefetch_data_hits = NULL;
672 static RRDDIM *rd_prefetch_data_misses = NULL;
674 if (unlikely(!st_prefetch_data_hits)) {
675 st_prefetch_data_hits = rrdset_create_localhost(
677 , "prefetch_data_hits"
679 , ZFS_FAMILY_EFFICIENCY
681 , "ZFS Data Prefetch Efficiency"
685 , RRDSET_TYPE_STACKED
688 rd_prefetch_data_hits = rrddim_add(st_prefetch_data_hits, "hits", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
689 rd_prefetch_data_misses = rrddim_add(st_prefetch_data_hits, "misses", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
692 rrdset_next(st_prefetch_data_hits);
694 rrddim_set_by_pointer(st_prefetch_data_hits, rd_prefetch_data_hits, arcstats.prefetch_data_hits);
695 rrddim_set_by_pointer(st_prefetch_data_hits, rd_prefetch_data_misses, arcstats.prefetch_data_misses);
696 rrdset_done(st_prefetch_data_hits);
699 // --------------------------------------------------------------------
702 static RRDSET *st_hash_elements = NULL;
703 static RRDDIM *rd_hash_elements_current = NULL;
704 static RRDDIM *rd_hash_elements_max = NULL;
706 if (unlikely(!st_hash_elements)) {
707 st_hash_elements = rrdset_create_localhost(
713 , "ZFS ARC Hash Elements"
720 rd_hash_elements_current = rrddim_add(st_hash_elements, "current", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
721 rd_hash_elements_max = rrddim_add(st_hash_elements, "max", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
724 rrdset_next(st_hash_elements);
726 rrddim_set_by_pointer(st_hash_elements, rd_hash_elements_current, arcstats.hash_elements);
727 rrddim_set_by_pointer(st_hash_elements, rd_hash_elements_max, arcstats.hash_elements_max);
728 rrdset_done(st_hash_elements);
731 // --------------------------------------------------------------------
734 static RRDSET *st_hash_chains = NULL;
735 static RRDDIM *rd_hash_chains_current = NULL;
736 static RRDDIM *rd_hash_chains_max = NULL;
738 if (unlikely(!st_hash_chains)) {
739 st_hash_chains = rrdset_create_localhost(
745 , "ZFS ARC Hash Chains"
752 rd_hash_chains_current = rrddim_add(st_hash_chains, "current", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
753 rd_hash_chains_max = rrddim_add(st_hash_chains, "max", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
756 rrdset_next(st_hash_chains);
758 rrddim_set_by_pointer(st_hash_chains, rd_hash_chains_current, arcstats.hash_chains);
759 rrddim_set_by_pointer(st_hash_chains, rd_hash_chains_max, arcstats.hash_chain_max);
760 rrdset_done(st_hash_chains);
763 // --------------------------------------------------------------------
767 int do_proc_spl_kstat_zfs_arcstats(int update_every, usec_t dt) {
770 static procfile *ff = NULL;
771 static ARL_BASE *arl_base = NULL;
773 if(unlikely(!arl_base)) {
774 arl_base = arl_create("arcstats", NULL, 60);
776 arl_expect(arl_base, "hits", &arcstats.hits);
777 arl_expect(arl_base, "misses", &arcstats.misses);
778 arl_expect(arl_base, "demand_data_hits", &arcstats.demand_data_hits);
779 arl_expect(arl_base, "demand_data_misses", &arcstats.demand_data_misses);
780 arl_expect(arl_base, "demand_metadata_hits", &arcstats.demand_metadata_hits);
781 arl_expect(arl_base, "demand_metadata_misses", &arcstats.demand_metadata_misses);
782 arl_expect(arl_base, "prefetch_data_hits", &arcstats.prefetch_data_hits);
783 arl_expect(arl_base, "prefetch_data_misses", &arcstats.prefetch_data_misses);
784 arl_expect(arl_base, "prefetch_metadata_hits", &arcstats.prefetch_metadata_hits);
785 arl_expect(arl_base, "prefetch_metadata_misses", &arcstats.prefetch_metadata_misses);
786 arl_expect(arl_base, "mru_hits", &arcstats.mru_hits);
787 arl_expect(arl_base, "mru_ghost_hits", &arcstats.mru_ghost_hits);
788 arl_expect(arl_base, "mfu_hits", &arcstats.mfu_hits);
789 arl_expect(arl_base, "mfu_ghost_hits", &arcstats.mfu_ghost_hits);
790 arl_expect(arl_base, "deleted", &arcstats.deleted);
791 arl_expect(arl_base, "mutex_miss", &arcstats.mutex_miss);
792 arl_expect(arl_base, "evict_skip", &arcstats.evict_skip);
793 arl_expect(arl_base, "evict_not_enough", &arcstats.evict_not_enough);
794 arl_expect(arl_base, "evict_l2_cached", &arcstats.evict_l2_cached);
795 arl_expect(arl_base, "evict_l2_eligible", &arcstats.evict_l2_eligible);
796 arl_expect(arl_base, "evict_l2_ineligible", &arcstats.evict_l2_ineligible);
797 arl_expect(arl_base, "evict_l2_skip", &arcstats.evict_l2_skip);
798 arl_expect(arl_base, "hash_elements", &arcstats.hash_elements);
799 arl_expect(arl_base, "hash_elements_max", &arcstats.hash_elements_max);
800 arl_expect(arl_base, "hash_collisions", &arcstats.hash_collisions);
801 arl_expect(arl_base, "hash_chains", &arcstats.hash_chains);
802 arl_expect(arl_base, "hash_chain_max", &arcstats.hash_chain_max);
803 arl_expect(arl_base, "p", &arcstats.p);
804 arl_expect(arl_base, "c", &arcstats.c);
805 arl_expect(arl_base, "c_min", &arcstats.c_min);
806 arl_expect(arl_base, "c_max", &arcstats.c_max);
807 arl_expect(arl_base, "size", &arcstats.size);
808 arl_expect(arl_base, "hdr_size", &arcstats.hdr_size);
809 arl_expect(arl_base, "data_size", &arcstats.data_size);
810 arl_expect(arl_base, "metadata_size", &arcstats.metadata_size);
811 arl_expect(arl_base, "other_size", &arcstats.other_size);
812 arl_expect(arl_base, "anon_size", &arcstats.anon_size);
813 arl_expect(arl_base, "anon_evictable_data", &arcstats.anon_evictable_data);
814 arl_expect(arl_base, "anon_evictable_metadata", &arcstats.anon_evictable_metadata);
815 arl_expect(arl_base, "mru_size", &arcstats.mru_size);
816 arl_expect(arl_base, "mru_evictable_data", &arcstats.mru_evictable_data);
817 arl_expect(arl_base, "mru_evictable_metadata", &arcstats.mru_evictable_metadata);
818 arl_expect(arl_base, "mru_ghost_size", &arcstats.mru_ghost_size);
819 arl_expect(arl_base, "mru_ghost_evictable_data", &arcstats.mru_ghost_evictable_data);
820 arl_expect(arl_base, "mru_ghost_evictable_metadata", &arcstats.mru_ghost_evictable_metadata);
821 arl_expect(arl_base, "mfu_size", &arcstats.mfu_size);
822 arl_expect(arl_base, "mfu_evictable_data", &arcstats.mfu_evictable_data);
823 arl_expect(arl_base, "mfu_evictable_metadata", &arcstats.mfu_evictable_metadata);
824 arl_expect(arl_base, "mfu_ghost_size", &arcstats.mfu_ghost_size);
825 arl_expect(arl_base, "mfu_ghost_evictable_data", &arcstats.mfu_ghost_evictable_data);
826 arl_expect(arl_base, "mfu_ghost_evictable_metadata", &arcstats.mfu_ghost_evictable_metadata);
827 arl_expect(arl_base, "l2_hits", &arcstats.l2_hits);
828 arl_expect(arl_base, "l2_misses", &arcstats.l2_misses);
829 arl_expect(arl_base, "l2_feeds", &arcstats.l2_feeds);
830 arl_expect(arl_base, "l2_rw_clash", &arcstats.l2_rw_clash);
831 arl_expect(arl_base, "l2_read_bytes", &arcstats.l2_read_bytes);
832 arl_expect(arl_base, "l2_write_bytes", &arcstats.l2_write_bytes);
833 arl_expect(arl_base, "l2_writes_sent", &arcstats.l2_writes_sent);
834 arl_expect(arl_base, "l2_writes_done", &arcstats.l2_writes_done);
835 arl_expect(arl_base, "l2_writes_error", &arcstats.l2_writes_error);
836 arl_expect(arl_base, "l2_writes_lock_retry", &arcstats.l2_writes_lock_retry);
837 arl_expect(arl_base, "l2_evict_lock_retry", &arcstats.l2_evict_lock_retry);
838 arl_expect(arl_base, "l2_evict_reading", &arcstats.l2_evict_reading);
839 arl_expect(arl_base, "l2_evict_l1cached", &arcstats.l2_evict_l1cached);
840 arl_expect(arl_base, "l2_free_on_write", &arcstats.l2_free_on_write);
841 arl_expect(arl_base, "l2_cdata_free_on_write", &arcstats.l2_cdata_free_on_write);
842 arl_expect(arl_base, "l2_abort_lowmem", &arcstats.l2_abort_lowmem);
843 arl_expect(arl_base, "l2_cksum_bad", &arcstats.l2_cksum_bad);
844 arl_expect(arl_base, "l2_io_error", &arcstats.l2_io_error);
845 arl_expect(arl_base, "l2_size", &arcstats.l2_size);
846 arl_expect(arl_base, "l2_asize", &arcstats.l2_asize);
847 arl_expect(arl_base, "l2_hdr_size", &arcstats.l2_hdr_size);
848 arl_expect(arl_base, "l2_compress_successes", &arcstats.l2_compress_successes);
849 arl_expect(arl_base, "l2_compress_zeros", &arcstats.l2_compress_zeros);
850 arl_expect(arl_base, "l2_compress_failures", &arcstats.l2_compress_failures);
851 arl_expect(arl_base, "memory_throttle_count", &arcstats.memory_throttle_count);
852 arl_expect(arl_base, "duplicate_buffers", &arcstats.duplicate_buffers);
853 arl_expect(arl_base, "duplicate_buffers_size", &arcstats.duplicate_buffers_size);
854 arl_expect(arl_base, "duplicate_reads", &arcstats.duplicate_reads);
855 arl_expect(arl_base, "memory_direct_count", &arcstats.memory_direct_count);
856 arl_expect(arl_base, "memory_indirect_count", &arcstats.memory_indirect_count);
857 arl_expect(arl_base, "arc_no_grow", &arcstats.arc_no_grow);
858 arl_expect(arl_base, "arc_tempreserve", &arcstats.arc_tempreserve);
859 arl_expect(arl_base, "arc_loaned_bytes", &arcstats.arc_loaned_bytes);
860 arl_expect(arl_base, "arc_prune", &arcstats.arc_prune);
861 arl_expect(arl_base, "arc_meta_used", &arcstats.arc_meta_used);
862 arl_expect(arl_base, "arc_meta_limit", &arcstats.arc_meta_limit);
863 arl_expect(arl_base, "arc_meta_max", &arcstats.arc_meta_max);
864 arl_expect(arl_base, "arc_meta_min", &arcstats.arc_meta_min);
865 arl_expect(arl_base, "arc_need_free", &arcstats.arc_need_free);
866 arl_expect(arl_base, "arc_sys_free", &arcstats.arc_sys_free);
870 char filename[FILENAME_MAX + 1];
871 snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, ZFS_PROC_ARCSTATS);
872 ff = procfile_open(config_get("plugin:proc:" ZFS_PROC_ARCSTATS, "filename to monitor", filename), " \t:", PROCFILE_FLAG_DEFAULT);
877 ff = procfile_readall(ff);
879 return 0; // we return 0, so that we will retry to open it next time
881 size_t lines = procfile_lines(ff), l;
885 for(l = 0; l < lines ;l++) {
886 size_t words = procfile_linewords(ff, l);
887 if(unlikely(words < 3)) {
888 if(unlikely(words)) error("Cannot read " ZFS_PROC_ARCSTATS " line %zu. Expected 3 params, read %zu.", l, words);
892 const char *key = procfile_lineword(ff, l, 0);
893 const char *value = procfile_lineword(ff, l, 2);
895 if(unlikely(l2exist == -1)) {
896 if(key[0] == 'l' && key[1] == '2' && key[2] == '_')
900 if(unlikely(arl_check(arl_base, key, value))) break;
903 if(unlikely(l2exist == -1))
906 generate_charts_arcstats(update_every);
907 generate_charts_arc_summary(update_every);