mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-12-26 03:09:34 +03:00
RAIDZ parity kstat rework
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
This commit is contained in:
parent
c9187d867f
commit
26a08b5ca9
@ -233,8 +233,8 @@ impl ## _rec_ ## code(void *rmp, const int *tgtidx) \
|
|||||||
|
|
||||||
|
|
||||||
typedef struct raidz_impl_kstat {
|
typedef struct raidz_impl_kstat {
|
||||||
kstat_named_t gen[RAIDZ_GEN_NUM]; /* gen method speed kiB/s */
|
uint64_t gen[RAIDZ_GEN_NUM]; /* gen method speed B/s */
|
||||||
kstat_named_t rec[RAIDZ_REC_NUM]; /* rec method speed kiB/s */
|
uint64_t rec[RAIDZ_REC_NUM]; /* rec method speed B/s */
|
||||||
} raidz_impl_kstat_t;
|
} raidz_impl_kstat_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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)];
|
static raidz_impl_ops_t *raidz_supp_impl[ARRAY_SIZE(raidz_all_maths)];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* kstats values for supported impl & original methods
|
* kstats values for supported implementations
|
||||||
* Values represent per disk throughput of 8 disk+parity raidz vdev (Bps)
|
* 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];
|
static raidz_impl_kstat_t raidz_impl_kstats[ARRAY_SIZE(raidz_all_maths) + 1];
|
||||||
|
|
||||||
@ -263,33 +263,83 @@ const char *raidz_rec_name[] = {
|
|||||||
"rec_pq", "rec_pr", "rec_qr", "rec_pqr"
|
"rec_pq", "rec_pr", "rec_qr", "rec_pqr"
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
#define RAIDZ_KSTAT_LINE_LEN (17 + 10*12 + 1)
|
||||||
init_raidz_kstat(raidz_impl_kstat_t *rs, const char *name)
|
|
||||||
|
static int
|
||||||
|
raidz_math_kstat_headers(char *buf, size_t size)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
const size_t impl_name_len = strnlen(name, KSTAT_STRLEN);
|
ssize_t off;
|
||||||
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++) {
|
ASSERT3U(size, >=, RAIDZ_KSTAT_LINE_LEN);
|
||||||
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;
|
off = snprintf(buf, size, "%-17s", "implementation");
|
||||||
rs->gen[i].value.ui64 = 0;
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
ASSERT3U(size, >=, RAIDZ_KSTAT_LINE_LEN);
|
||||||
|
|
||||||
|
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]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < RAIDZ_REC_NUM; i++) {
|
(void) snprintf(buf + off, size - off, "\n");
|
||||||
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);
|
|
||||||
|
|
||||||
rs->rec[i].data_type = KSTAT_DATA_UINT64;
|
return (0);
|
||||||
rs->rec[i].value.ui64 = 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)
|
#define BENCH_D_COLS (8ULL)
|
||||||
@ -355,22 +405,22 @@ benchmark_raidz_impl(raidz_map_t *bench_rm, const int fn, benchmark_fn bench_fn)
|
|||||||
speed /= (t_diff * BENCH_COLS);
|
speed /= (t_diff * BENCH_COLS);
|
||||||
|
|
||||||
if (bench_fn == benchmark_gen_impl)
|
if (bench_fn == benchmark_gen_impl)
|
||||||
raidz_impl_kstats[impl].gen[fn].value.ui64 = speed;
|
raidz_impl_kstats[impl].gen[fn] = speed;
|
||||||
else
|
else
|
||||||
raidz_impl_kstats[impl].rec[fn].value.ui64 = speed;
|
raidz_impl_kstats[impl].rec[fn] = speed;
|
||||||
|
|
||||||
/* Update fastest implementation method */
|
/* Update fastest implementation method */
|
||||||
if (speed > best_speed) {
|
if (speed > best_speed) {
|
||||||
best_speed = speed;
|
best_speed = speed;
|
||||||
|
|
||||||
if (bench_fn == benchmark_gen_impl) {
|
if (bench_fn == benchmark_gen_impl) {
|
||||||
|
fstat->gen[fn] = impl;
|
||||||
vdev_raidz_fastest_impl.gen[fn] =
|
vdev_raidz_fastest_impl.gen[fn] =
|
||||||
curr_impl->gen[fn];
|
curr_impl->gen[fn];
|
||||||
fstat->gen[fn].value.ui64 = speed;
|
|
||||||
} else {
|
} else {
|
||||||
|
fstat->rec[fn] = impl;
|
||||||
vdev_raidz_fastest_impl.rec[fn] =
|
vdev_raidz_fastest_impl.rec[fn] =
|
||||||
curr_impl->rec[fn];
|
curr_impl->rec[fn];
|
||||||
fstat->rec[fn].value.ui64 = speed;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -393,18 +443,12 @@ vdev_raidz_math_init(void)
|
|||||||
if (curr_impl->init)
|
if (curr_impl->init)
|
||||||
curr_impl->init();
|
curr_impl->init();
|
||||||
|
|
||||||
if (curr_impl->is_supported()) {
|
if (curr_impl->is_supported())
|
||||||
/* init kstat */
|
|
||||||
init_raidz_kstat(&raidz_impl_kstats[c],
|
|
||||||
curr_impl->name);
|
|
||||||
raidz_supp_impl[c++] = (raidz_impl_ops_t *) curr_impl;
|
raidz_supp_impl[c++] = (raidz_impl_ops_t *) curr_impl;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
membar_producer(); /* complete raidz_supp_impl[] init */
|
membar_producer(); /* complete raidz_supp_impl[] init */
|
||||||
raidz_supp_impl_cnt = c; /* number of supported impl */
|
raidz_supp_impl_cnt = c; /* number of supported impl */
|
||||||
|
|
||||||
init_raidz_kstat(&(raidz_impl_kstats[raidz_supp_impl_cnt]), "fastest");
|
|
||||||
|
|
||||||
#if !defined(_KERNEL)
|
#if !defined(_KERNEL)
|
||||||
/* Skip benchmarking and use last implementation as fastest */
|
/* Skip benchmarking and use last implementation as fastest */
|
||||||
memcpy(&vdev_raidz_fastest_impl, raidz_supp_impl[raidz_supp_impl_cnt-1],
|
memcpy(&vdev_raidz_fastest_impl, raidz_supp_impl[raidz_supp_impl_cnt-1],
|
||||||
@ -452,13 +496,16 @@ vdev_raidz_math_init(void)
|
|||||||
kmem_free(bench_zio, sizeof (zio_t));
|
kmem_free(bench_zio, sizeof (zio_t));
|
||||||
|
|
||||||
/* install kstats for all impl */
|
/* install kstats for all impl */
|
||||||
raidz_math_kstat = kstat_create("zfs", 0, "vdev_raidz_bench",
|
raidz_math_kstat = kstat_create("zfs", 0, "vdev_raidz_bench", "misc",
|
||||||
"misc", KSTAT_TYPE_NAMED,
|
KSTAT_TYPE_RAW, 0, KSTAT_FLAG_VIRTUAL);
|
||||||
sizeof (raidz_impl_kstat_t) / sizeof (kstat_named_t) *
|
|
||||||
(raidz_supp_impl_cnt + 1), KSTAT_FLAG_VIRTUAL);
|
|
||||||
|
|
||||||
if (raidz_math_kstat != NULL) {
|
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);
|
kstat_install(raidz_math_kstat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user