]> git.proxmox.com Git - mirror_zfs.git/blame - module/zfs/dbuf_stats.c
linux spl: fix typo in top comment of spl-condvar.c
[mirror_zfs.git] / module / zfs / dbuf_stats.c
CommitLineData
e0b0ca98
BB
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
1d3ba0bf 9 * or https://opensource.org/licenses/CDDL-1.0.
e0b0ca98
BB
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22#include <sys/zfs_context.h>
23#include <sys/dbuf.h>
24#include <sys/dmu_objset.h>
25
26/*
27 * Calculate the index of the arc header for the state, disabled by default.
28 */
29int zfs_dbuf_state_index = 0;
30
31/*
32 * ==========================================================================
33 * Dbuf Hash Read Routines
34 * ==========================================================================
35 */
36typedef struct dbuf_stats_t {
37 kmutex_t lock;
38 kstat_t *kstat;
39 dbuf_hash_table_t *hash;
40 int idx;
41} dbuf_stats_t;
42
43static dbuf_stats_t dbuf_stats_hash_table;
44
45static int
46dbuf_stats_hash_table_headers(char *buf, size_t size)
47{
7b2d78a0 48 (void) snprintf(buf, size,
92dc4ad8
RN
49 "%-105s | %-119s | %s\n"
50 "%-16s %-8s %-8s %-8s %-8s %-10s %-8s %-8s %-5s %-5s %-7s %3s | "
5e021f56
GDN
51 "%-5s %-5s %-9s %-6s %-8s %-12s "
52 "%-6s %-6s %-6s %-6s %-6s %-8s %-8s %-8s %-6s | "
53 "%-6s %-6s %-8s %-8s %-6s %-6s %-6s %-8s %-8s\n",
e0b0ca98 54 "dbuf", "arcbuf", "dnode", "pool", "objset", "object", "level",
92dc4ad8
RN
55 "blkid", "offset", "dbsize", "usize", "meta", "state", "dbholds",
56 "dbc", "list", "atype", "flags", "count", "asize", "access",
d1d7e268
MK
57 "mru", "gmru", "mfu", "gmfu", "l2", "l2_dattr", "l2_asize",
58 "l2_comp", "aholds", "dtype", "btype", "data_bs", "meta_bs",
59 "bsize", "lvls", "dholds", "blocks", "dsize");
e0b0ca98
BB
60
61 return (0);
62}
63
65c7cc49 64static int
e0b0ca98
BB
65__dbuf_stats_hash_table_data(char *buf, size_t size, dmu_buf_impl_t *db)
66{
67 arc_buf_info_t abi = { 0 };
68 dmu_object_info_t doi = { 0 };
69 dnode_t *dn = DB_DNODE(db);
aa2ef419 70 size_t nwritten;
e0b0ca98
BB
71
72 if (db->db_buf)
73 arc_buf_info(db->db_buf, &abi, zfs_dbuf_state_index);
74
4c5b89f5 75 __dmu_object_info_from_dnode(dn, &doi);
e0b0ca98 76
aa2ef419 77 nwritten = snprintf(buf, size,
92dc4ad8
RN
78 "%-16s %-8llu %-8lld %-8lld %-8lld %-10llu %-8llu %-8llu "
79 "%-5d %-5d %-7lu %-3d | %-5d %-5d 0x%-7x %-6lu %-8llu %-12llu "
5e021f56
GDN
80 "%-6lu %-6lu %-6lu %-6lu %-6lu %-8llu %-8llu %-8d %-6lu | "
81 "%-6d %-6d %-8lu %-8lu %-6llu %-6lu %-6lu %-8llu %-8llu\n",
e0b0ca98
BB
82 /* dmu_buf_impl_t */
83 spa_name(dn->dn_objset->os_spa),
84 (u_longlong_t)dmu_objset_id(db->db_objset),
85 (longlong_t)db->db.db_object,
86 (longlong_t)db->db_level,
87 (longlong_t)db->db_blkid,
88 (u_longlong_t)db->db.db_offset,
89 (u_longlong_t)db->db.db_size,
92dc4ad8 90 (u_longlong_t)dmu_buf_user_size(&db->db),
e0b0ca98
BB
91 !!dbuf_is_metadata(db),
92 db->db_state,
424fd7c3 93 (ulong_t)zfs_refcount_count(&db->db_holds),
5e021f56 94 multilist_link_active(&db->db_cache_link),
e0b0ca98
BB
95 /* arc_buf_info_t */
96 abi.abi_state_type,
97 abi.abi_state_contents,
e0b0ca98 98 abi.abi_flags,
d3c2ae1c 99 (ulong_t)abi.abi_bufcnt,
e0b0ca98
BB
100 (u_longlong_t)abi.abi_size,
101 (u_longlong_t)abi.abi_access,
102 (ulong_t)abi.abi_mru_hits,
103 (ulong_t)abi.abi_mru_ghost_hits,
104 (ulong_t)abi.abi_mfu_hits,
105 (ulong_t)abi.abi_mfu_ghost_hits,
106 (ulong_t)abi.abi_l2arc_hits,
107 (u_longlong_t)abi.abi_l2arc_dattr,
108 (u_longlong_t)abi.abi_l2arc_asize,
109 abi.abi_l2arc_compress,
110 (ulong_t)abi.abi_holds,
111 /* dmu_object_info_t */
112 doi.doi_type,
113 doi.doi_bonus_type,
114 (ulong_t)doi.doi_data_block_size,
115 (ulong_t)doi.doi_metadata_block_size,
116 (u_longlong_t)doi.doi_bonus_size,
117 (ulong_t)doi.doi_indirection,
424fd7c3 118 (ulong_t)zfs_refcount_count(&dn->dn_holds),
e0b0ca98
BB
119 (u_longlong_t)doi.doi_fill_count,
120 (u_longlong_t)doi.doi_max_offset);
e0b0ca98 121
aa2ef419
TC
122 if (nwritten >= size)
123 return (size);
124
125 return (nwritten + 1);
e0b0ca98
BB
126}
127
128static int
129dbuf_stats_hash_table_data(char *buf, size_t size, void *data)
130{
131 dbuf_stats_t *dsh = (dbuf_stats_t *)data;
132 dbuf_hash_table_t *h = dsh->hash;
133 dmu_buf_impl_t *db;
134 int length, error = 0;
135
136 ASSERT3S(dsh->idx, >=, 0);
137 ASSERT3S(dsh->idx, <=, h->hash_table_mask);
1cb8202b
MM
138 if (size)
139 buf[0] = 0;
e0b0ca98 140
223b04d2 141 mutex_enter(DBUF_HASH_MUTEX(h, dsh->idx));
e0b0ca98
BB
142 for (db = h->hash_table[dsh->idx]; db != NULL; db = db->db_hash_next) {
143 /*
144 * Returning ENOMEM will cause the data and header functions
145 * to be called with a larger scratch buffers.
146 */
147 if (size < 512) {
ecb2b7dc 148 error = SET_ERROR(ENOMEM);
e0b0ca98
BB
149 break;
150 }
151
152 mutex_enter(&db->db_mtx);
e0b0ca98 153
e2c4acde
BB
154 if (db->db_state != DB_EVICTING) {
155 length = __dbuf_stats_hash_table_data(buf, size, db);
156 buf += length;
157 size -= length;
158 }
e0b0ca98
BB
159
160 mutex_exit(&db->db_mtx);
e0b0ca98 161 }
223b04d2 162 mutex_exit(DBUF_HASH_MUTEX(h, dsh->idx));
e0b0ca98
BB
163
164 return (error);
165}
166
167static void *
168dbuf_stats_hash_table_addr(kstat_t *ksp, loff_t n)
169{
170 dbuf_stats_t *dsh = ksp->ks_private;
171
d1d7e268 172 ASSERT(MUTEX_HELD(&dsh->lock));
e0b0ca98
BB
173
174 if (n <= dsh->hash->hash_table_mask) {
175 dsh->idx = n;
176 return (dsh);
177 }
178
179 return (NULL);
180}
181
182static void
183dbuf_stats_hash_table_init(dbuf_hash_table_t *hash)
184{
185 dbuf_stats_t *dsh = &dbuf_stats_hash_table;
186 kstat_t *ksp;
187
188 mutex_init(&dsh->lock, NULL, MUTEX_DEFAULT, NULL);
189 dsh->hash = hash;
190
191 ksp = kstat_create("zfs", 0, "dbufs", "misc",
192 KSTAT_TYPE_RAW, 0, KSTAT_FLAG_VIRTUAL);
193 dsh->kstat = ksp;
194
195 if (ksp) {
196 ksp->ks_lock = &dsh->lock;
197 ksp->ks_ndata = UINT32_MAX;
198 ksp->ks_private = dsh;
199 kstat_set_raw_ops(ksp, dbuf_stats_hash_table_headers,
200 dbuf_stats_hash_table_data, dbuf_stats_hash_table_addr);
201 kstat_install(ksp);
202 }
203}
204
205static void
206dbuf_stats_hash_table_destroy(void)
207{
208 dbuf_stats_t *dsh = &dbuf_stats_hash_table;
209 kstat_t *ksp;
210
211 ksp = dsh->kstat;
212 if (ksp)
213 kstat_delete(ksp);
214
215 mutex_destroy(&dsh->lock);
216}
217
218void
219dbuf_stats_init(dbuf_hash_table_t *hash)
220{
221 dbuf_stats_hash_table_init(hash);
222}
223
224void
225dbuf_stats_destroy(void)
226{
227 dbuf_stats_hash_table_destroy();
228}
229
03fdcb9a
MM
230ZFS_MODULE_PARAM(zfs, zfs_, dbuf_state_index, INT, ZMOD_RW,
231 "Calculate arc header index");