@@ -145,10 +145,53 @@ static const int zio_buf_debug_limit = 16384;
145145static const int zio_buf_debug_limit = 0 ;
146146#endif
147147
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+
148173static inline void __zio_execute (zio_t * zio );
149174
150175static void zio_taskq_dispatch (zio_t * , zio_taskq_type_t , boolean_t );
151176
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+
152195void
153196zio_init (void )
154197{
@@ -159,6 +202,19 @@ zio_init(void)
159202 zio_link_cache = kmem_cache_create ("zio_link_cache" ,
160203 sizeof (zio_link_t ), 0 , NULL , NULL , NULL , NULL , NULL , 0 );
161204
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+
162218 for (c = 0 ; c < SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT ; c ++ ) {
163219 size_t size = (c + 1 ) << SPA_MINBLOCKSHIFT ;
164220 size_t align , cflags , data_cflags ;
@@ -286,6 +342,16 @@ zio_fini(void)
286342 VERIFY3P (zio_data_buf_cache [i ], = = , NULL );
287343 }
288344
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+
289355 kmem_cache_destroy (zio_link_cache );
290356 kmem_cache_destroy (zio_cache );
291357
@@ -4053,6 +4119,7 @@ zio_dva_allocate(zio_t *zio)
40534119 mc = spa_preferred_class (spa , zio );
40544120 zio -> io_metaslab_class = mc ;
40554121 }
4122+ ZIOSTAT_BUMP (ziostat_total_allocations );
40564123
40574124 /*
40584125 * Try allocating the block in the usual metaslab class.
@@ -4118,6 +4185,7 @@ zio_dva_allocate(zio_t *zio)
41184185 error );
41194186 }
41204187
4188+ ZIOSTAT_BUMP (ziostat_alloc_class_fallbacks );
41214189 error = metaslab_alloc (spa , mc , zio -> io_size , bp ,
41224190 zio -> io_prop .zp_copies , zio -> io_txg , NULL , flags ,
41234191 & zio -> io_alloc_list , zio , zio -> io_allocator );
@@ -4130,6 +4198,9 @@ zio_dva_allocate(zio_t *zio)
41304198 spa_name (spa ), zio , (u_longlong_t )zio -> io_size ,
41314199 error );
41324200 }
4201+ ZIOSTAT_BUMP (ziostat_gang_writes );
4202+ if (flags & METASLAB_GANG_CHILD )
4203+ ZIOSTAT_BUMP (ziostat_gang_multilevel );
41334204 return (zio_write_gang_block (zio , mc ));
41344205 }
41354206 if (error != 0 ) {
@@ -4221,6 +4292,7 @@ zio_alloc_zil(spa_t *spa, objset_t *os, uint64_t txg, blkptr_t *new_bp,
42214292 int flags = METASLAB_ZIL ;
42224293 int allocator = (uint_t )cityhash1 (os -> os_dsl_dataset -> ds_object )
42234294 % spa -> spa_alloc_count ;
4295+ ZIOSTAT_BUMP (ziostat_total_allocations );
42244296 error = metaslab_alloc (spa , spa_log_class (spa ), size , new_bp , 1 ,
42254297 txg , NULL , flags , & io_alloc_list , NULL , allocator );
42264298 * slog = (error == 0 );
@@ -4230,6 +4302,7 @@ zio_alloc_zil(spa_t *spa, objset_t *os, uint64_t txg, blkptr_t *new_bp,
42304302 & io_alloc_list , NULL , allocator );
42314303 }
42324304 if (error != 0 ) {
4305+ ZIOSTAT_BUMP (ziostat_alloc_class_fallbacks );
42334306 error = metaslab_alloc (spa , spa_normal_class (spa ), size ,
42344307 new_bp , 1 , txg , NULL , flags ,
42354308 & io_alloc_list , NULL , allocator );
0 commit comments