Skip to content

Commit 88020b9

Browse files
authored
Add kstats tracking gang allocations
Gang blocks have a significant impact on the long and short term performance of a zpool, but there is not a lot of observability into whether they're being used. This change adds gang-specific kstats to ZFS, to better allow users to see whether ganging is happening. Sponsored-by: Klara, Inc. Sponsored-by: Wasabi Technology, Inc. Reviewed-by: Alexander Motin <[email protected]> Reviewed-by: Tony Hutter <[email protected]> Signed-off-by: Paul Dagnelie <[email protected]> Closes #17003
1 parent 4049651 commit 88020b9

File tree

1 file changed

+73
-0
lines changed

1 file changed

+73
-0
lines changed

module/zfs/zio.c

+73
Original file line numberDiff line numberDiff line change
@@ -145,10 +145,53 @@ static const int zio_buf_debug_limit = 16384;
145145
static 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+
148173
static inline void __zio_execute(zio_t *zio);
149174

150175
static 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+
152195
void
153196
zio_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

Comments
 (0)