Skip to content

Commit

Permalink
RAIDZ parity kstat rework
Browse files Browse the repository at this point in the history
Print table with speed of methods for each implementation.
Last line describes contents of [fastest] selection.

Signed-off-by: Gvozden Neskovic <neskovic@gmail.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #4860
  • Loading branch information
ironMann authored and behlendorf committed Jul 19, 2016
1 parent c9187d8 commit 26a08b5
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 42 deletions.
4 changes: 2 additions & 2 deletions include/sys/vdev_raidz_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,8 @@ impl ## _rec_ ## code(void *rmp, const int *tgtidx) \


typedef struct raidz_impl_kstat {
kstat_named_t gen[RAIDZ_GEN_NUM]; /* gen method speed kiB/s */
kstat_named_t rec[RAIDZ_REC_NUM]; /* rec method speed kiB/s */
uint64_t gen[RAIDZ_GEN_NUM]; /* gen method speed B/s */
uint64_t rec[RAIDZ_REC_NUM]; /* rec method speed B/s */
} raidz_impl_kstat_t;

/*
Expand Down
127 changes: 87 additions & 40 deletions module/zfs/vdev_raidz_math.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ static size_t raidz_supp_impl_cnt = 0;
static raidz_impl_ops_t *raidz_supp_impl[ARRAY_SIZE(raidz_all_maths)];

/*
* kstats values for supported impl & original methods
* Values represent per disk throughput of 8 disk+parity raidz vdev (Bps)
* kstats values for supported implementations
* Values represent per disk throughput of 8 disk+parity raidz vdev [B/s]
*/
static raidz_impl_kstat_t raidz_impl_kstats[ARRAY_SIZE(raidz_all_maths) + 1];

Expand Down Expand Up @@ -263,33 +263,83 @@ const char *raidz_rec_name[] = {
"rec_pq", "rec_pr", "rec_qr", "rec_pqr"
};

static void
init_raidz_kstat(raidz_impl_kstat_t *rs, const char *name)
#define RAIDZ_KSTAT_LINE_LEN (17 + 10*12 + 1)

static int
raidz_math_kstat_headers(char *buf, size_t size)
{
int i;
const size_t impl_name_len = strnlen(name, KSTAT_STRLEN);
const size_t op_name_max = (KSTAT_STRLEN - 2) > impl_name_len ?
KSTAT_STRLEN - impl_name_len - 2 : 0;

for (i = 0; i < RAIDZ_GEN_NUM; i++) {
strncpy(rs->gen[i].name, name, impl_name_len);
strncpy(rs->gen[i].name + impl_name_len, "_", 1);
strncpy(rs->gen[i].name + impl_name_len + 1,
raidz_gen_name[i], op_name_max);

rs->gen[i].data_type = KSTAT_DATA_UINT64;
rs->gen[i].value.ui64 = 0;
}
ssize_t off;

ASSERT3U(size, >=, RAIDZ_KSTAT_LINE_LEN);

off = snprintf(buf, size, "%-17s", "implementation");

for (i = 0; i < ARRAY_SIZE(raidz_gen_name); i++)
off += snprintf(buf + off, size - off, "%-12s",
raidz_gen_name[i]);

for (i = 0; i < ARRAY_SIZE(raidz_rec_name); i++)
off += snprintf(buf + off, size - off, "%-12s",
raidz_rec_name[i]);

(void) snprintf(buf + off, size - off, "\n");

return (0);
}

static int
raidz_math_kstat_data(char *buf, size_t size, void *data)
{
raidz_impl_kstat_t * fstat = &raidz_impl_kstats[raidz_supp_impl_cnt];
raidz_impl_kstat_t * cstat = (raidz_impl_kstat_t *) data;
ssize_t off = 0;
int i;

for (i = 0; i < RAIDZ_REC_NUM; i++) {
strncpy(rs->rec[i].name, name, impl_name_len);
strncpy(rs->rec[i].name + impl_name_len, "_", 1);
strncpy(rs->rec[i].name + impl_name_len + 1,
raidz_rec_name[i], op_name_max);
ASSERT3U(size, >=, RAIDZ_KSTAT_LINE_LEN);

rs->rec[i].data_type = KSTAT_DATA_UINT64;
rs->rec[i].value.ui64 = 0;
if (cstat == fstat) {
off += snprintf(buf + off, size - off, "%-17s", "fastest");

for (i = 0; i < ARRAY_SIZE(raidz_gen_name); i++) {
int id = fstat->gen[i];
off += snprintf(buf + off, size - off, "%-12s",
raidz_supp_impl[id]->name);
}
for (i = 0; i < ARRAY_SIZE(raidz_rec_name); i++) {
int id = fstat->rec[i];
off += snprintf(buf + off, size - off, "%-12s",
raidz_supp_impl[id]->name);
}
} else {
ptrdiff_t id = cstat - raidz_impl_kstats;

off += snprintf(buf + off, size - off, "%-17s",
raidz_supp_impl[id]->name);

for (i = 0; i < ARRAY_SIZE(raidz_gen_name); i++)
off += snprintf(buf + off, size - off, "%-12llu",
(u_longlong_t) cstat->gen[i]);

for (i = 0; i < ARRAY_SIZE(raidz_rec_name); i++)
off += snprintf(buf + off, size - off, "%-12llu",
(u_longlong_t) cstat->rec[i]);
}

(void) snprintf(buf + off, size - off, "\n");

return (0);
}

static void *
raidz_math_kstat_addr(kstat_t *ksp, loff_t n)
{
if (n <= raidz_supp_impl_cnt)
ksp->ks_private = (void *) (raidz_impl_kstats + n);
else
ksp->ks_private = NULL;

return (ksp->ks_private);
}

#define BENCH_D_COLS (8ULL)
Expand Down Expand Up @@ -355,22 +405,22 @@ benchmark_raidz_impl(raidz_map_t *bench_rm, const int fn, benchmark_fn bench_fn)
speed /= (t_diff * BENCH_COLS);

if (bench_fn == benchmark_gen_impl)
raidz_impl_kstats[impl].gen[fn].value.ui64 = speed;
raidz_impl_kstats[impl].gen[fn] = speed;
else
raidz_impl_kstats[impl].rec[fn].value.ui64 = speed;
raidz_impl_kstats[impl].rec[fn] = speed;

/* Update fastest implementation method */
if (speed > best_speed) {
best_speed = speed;

if (bench_fn == benchmark_gen_impl) {
fstat->gen[fn] = impl;
vdev_raidz_fastest_impl.gen[fn] =
curr_impl->gen[fn];
fstat->gen[fn].value.ui64 = speed;
} else {
fstat->rec[fn] = impl;
vdev_raidz_fastest_impl.rec[fn] =
curr_impl->rec[fn];
fstat->rec[fn].value.ui64 = speed;
}
}
}
Expand All @@ -393,18 +443,12 @@ vdev_raidz_math_init(void)
if (curr_impl->init)
curr_impl->init();

if (curr_impl->is_supported()) {
/* init kstat */
init_raidz_kstat(&raidz_impl_kstats[c],
curr_impl->name);
if (curr_impl->is_supported())
raidz_supp_impl[c++] = (raidz_impl_ops_t *) curr_impl;
}
}
membar_producer(); /* complete raidz_supp_impl[] init */
raidz_supp_impl_cnt = c; /* number of supported impl */

init_raidz_kstat(&(raidz_impl_kstats[raidz_supp_impl_cnt]), "fastest");

#if !defined(_KERNEL)
/* Skip benchmarking and use last implementation as fastest */
memcpy(&vdev_raidz_fastest_impl, raidz_supp_impl[raidz_supp_impl_cnt-1],
Expand Down Expand Up @@ -452,13 +496,16 @@ vdev_raidz_math_init(void)
kmem_free(bench_zio, sizeof (zio_t));

/* install kstats for all impl */
raidz_math_kstat = kstat_create("zfs", 0, "vdev_raidz_bench",
"misc", KSTAT_TYPE_NAMED,
sizeof (raidz_impl_kstat_t) / sizeof (kstat_named_t) *
(raidz_supp_impl_cnt + 1), KSTAT_FLAG_VIRTUAL);
raidz_math_kstat = kstat_create("zfs", 0, "vdev_raidz_bench", "misc",
KSTAT_TYPE_RAW, 0, KSTAT_FLAG_VIRTUAL);

if (raidz_math_kstat != NULL) {
raidz_math_kstat->ks_data = raidz_impl_kstats;
raidz_math_kstat->ks_data = NULL;
raidz_math_kstat->ks_ndata = UINT32_MAX;
kstat_set_raw_ops(raidz_math_kstat,
raidz_math_kstat_headers,
raidz_math_kstat_data,
raidz_math_kstat_addr);
kstat_install(raidz_math_kstat);
}

Expand Down

0 comments on commit 26a08b5

Please sign in to comment.