@@ -145,10 +145,53 @@ static const int zio_buf_debug_limit = 16384;
145
145
static const int zio_buf_debug_limit = 0 ;
146
146
#endif
147
147
148
+ typedef struct zio_stats {
149
+ kstat_named_t ziostat_total_allocations ;
150
+ kstat_named_t ziostat_alloc_class_fallbacks ;
151
+ kstat_named_t ziostat_gang_writes ;
152
+ kstat_named_t ziostat_gang_multilevel ;
153
+ } zio_stats_t ;
154
+
155
+ static zio_stats_t zio_stats = {
156
+ { "total_allocations" , KSTAT_DATA_UINT64 },
157
+ { "alloc_class_fallbacks" , KSTAT_DATA_UINT64 },
158
+ { "gang_writes" , KSTAT_DATA_UINT64 },
159
+ { "gang_multilevel" , KSTAT_DATA_UINT64 },
160
+ };
161
+
162
+ struct {
163
+ wmsum_t ziostat_total_allocations ;
164
+ wmsum_t ziostat_alloc_class_fallbacks ;
165
+ wmsum_t ziostat_gang_writes ;
166
+ wmsum_t ziostat_gang_multilevel ;
167
+ } ziostat_sums ;
168
+
169
+ #define ZIOSTAT_BUMP (stat ) wmsum_add(&ziostat_sums.stat, 1);
170
+
171
+ static kstat_t * zio_ksp ;
172
+
148
173
static inline void __zio_execute (zio_t * zio );
149
174
150
175
static void zio_taskq_dispatch (zio_t * , zio_taskq_type_t , boolean_t );
151
176
177
+ static int
178
+ zio_kstats_update (kstat_t * ksp , int rw )
179
+ {
180
+ zio_stats_t * zs = ksp -> ks_data ;
181
+ if (rw == KSTAT_WRITE )
182
+ return (EACCES );
183
+
184
+ zs -> ziostat_total_allocations .value .ui64 =
185
+ wmsum_value (& ziostat_sums .ziostat_total_allocations );
186
+ zs -> ziostat_alloc_class_fallbacks .value .ui64 =
187
+ wmsum_value (& ziostat_sums .ziostat_alloc_class_fallbacks );
188
+ zs -> ziostat_gang_writes .value .ui64 =
189
+ wmsum_value (& ziostat_sums .ziostat_gang_writes );
190
+ zs -> ziostat_gang_multilevel .value .ui64 =
191
+ wmsum_value (& ziostat_sums .ziostat_gang_multilevel );
192
+ return (0 );
193
+ }
194
+
152
195
void
153
196
zio_init (void )
154
197
{
@@ -159,6 +202,19 @@ zio_init(void)
159
202
zio_link_cache = kmem_cache_create ("zio_link_cache" ,
160
203
sizeof (zio_link_t ), 0 , NULL , NULL , NULL , NULL , NULL , 0 );
161
204
205
+ wmsum_init (& ziostat_sums .ziostat_total_allocations , 0 );
206
+ wmsum_init (& ziostat_sums .ziostat_alloc_class_fallbacks , 0 );
207
+ wmsum_init (& ziostat_sums .ziostat_gang_writes , 0 );
208
+ wmsum_init (& ziostat_sums .ziostat_gang_multilevel , 0 );
209
+ zio_ksp = kstat_create ("zfs" , 0 , "zio_stats" ,
210
+ "misc" , KSTAT_TYPE_NAMED , sizeof (zio_stats ) /
211
+ sizeof (kstat_named_t ), KSTAT_FLAG_VIRTUAL );
212
+ if (zio_ksp != NULL ) {
213
+ zio_ksp -> ks_data = & zio_stats ;
214
+ zio_ksp -> ks_update = zio_kstats_update ;
215
+ kstat_install (zio_ksp );
216
+ }
217
+
162
218
for (c = 0 ; c < SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT ; c ++ ) {
163
219
size_t size = (c + 1 ) << SPA_MINBLOCKSHIFT ;
164
220
size_t align , cflags , data_cflags ;
@@ -286,6 +342,16 @@ zio_fini(void)
286
342
VERIFY3P (zio_data_buf_cache [i ], = = , NULL );
287
343
}
288
344
345
+ if (zio_ksp != NULL ) {
346
+ kstat_delete (zio_ksp );
347
+ zio_ksp = NULL ;
348
+ }
349
+
350
+ wmsum_fini (& ziostat_sums .ziostat_total_allocations );
351
+ wmsum_fini (& ziostat_sums .ziostat_alloc_class_fallbacks );
352
+ wmsum_fini (& ziostat_sums .ziostat_gang_writes );
353
+ wmsum_fini (& ziostat_sums .ziostat_gang_multilevel );
354
+
289
355
kmem_cache_destroy (zio_link_cache );
290
356
kmem_cache_destroy (zio_cache );
291
357
@@ -4053,6 +4119,7 @@ zio_dva_allocate(zio_t *zio)
4053
4119
mc = spa_preferred_class (spa , zio );
4054
4120
zio -> io_metaslab_class = mc ;
4055
4121
}
4122
+ ZIOSTAT_BUMP (ziostat_total_allocations );
4056
4123
4057
4124
/*
4058
4125
* Try allocating the block in the usual metaslab class.
@@ -4118,6 +4185,7 @@ zio_dva_allocate(zio_t *zio)
4118
4185
error );
4119
4186
}
4120
4187
4188
+ ZIOSTAT_BUMP (ziostat_alloc_class_fallbacks );
4121
4189
error = metaslab_alloc (spa , mc , zio -> io_size , bp ,
4122
4190
zio -> io_prop .zp_copies , zio -> io_txg , NULL , flags ,
4123
4191
& zio -> io_alloc_list , zio , zio -> io_allocator );
@@ -4130,6 +4198,9 @@ zio_dva_allocate(zio_t *zio)
4130
4198
spa_name (spa ), zio , (u_longlong_t )zio -> io_size ,
4131
4199
error );
4132
4200
}
4201
+ ZIOSTAT_BUMP (ziostat_gang_writes );
4202
+ if (flags & METASLAB_GANG_CHILD )
4203
+ ZIOSTAT_BUMP (ziostat_gang_multilevel );
4133
4204
return (zio_write_gang_block (zio , mc ));
4134
4205
}
4135
4206
if (error != 0 ) {
@@ -4221,6 +4292,7 @@ zio_alloc_zil(spa_t *spa, objset_t *os, uint64_t txg, blkptr_t *new_bp,
4221
4292
int flags = METASLAB_ZIL ;
4222
4293
int allocator = (uint_t )cityhash1 (os -> os_dsl_dataset -> ds_object )
4223
4294
% spa -> spa_alloc_count ;
4295
+ ZIOSTAT_BUMP (ziostat_total_allocations );
4224
4296
error = metaslab_alloc (spa , spa_log_class (spa ), size , new_bp , 1 ,
4225
4297
txg , NULL , flags , & io_alloc_list , NULL , allocator );
4226
4298
* slog = (error == 0 );
@@ -4230,6 +4302,7 @@ zio_alloc_zil(spa_t *spa, objset_t *os, uint64_t txg, blkptr_t *new_bp,
4230
4302
& io_alloc_list , NULL , allocator );
4231
4303
}
4232
4304
if (error != 0 ) {
4305
+ ZIOSTAT_BUMP (ziostat_alloc_class_fallbacks );
4233
4306
error = metaslab_alloc (spa , spa_normal_class (spa ), size ,
4234
4307
new_bp , 1 , txg , NULL , flags ,
4235
4308
& io_alloc_list , NULL , allocator );
0 commit comments