Skip to content

Commit 91f3622

Browse files
mcmilkcperciva
authored andcommitted
Faster checksum benchmark on system boot
While booting, only the needed 256KiB benchmarks are done now. The delay for checking all checksums occurs when requested via: - Linux: cat /proc/spl/kstat/zfs/chksum_bench - FreeBSD: sysctl kstat.zfs.misc.chksum_bench Reported by: Lahiru Gunathilake <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Reviewed-by: Alexander Motin <[email protected]> Signed-off-by: Tino Reichardt <[email protected]> Co-authored-by: Colin Percival <[email protected]> Closes #17563 Closes #17560
1 parent a5ba57a commit 91f3622

File tree

1 file changed

+40
-29
lines changed

1 file changed

+40
-29
lines changed

module/zfs/zfs_chksum.c

Lines changed: 40 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,6 @@
3131
#include <sys/blake3.h>
3232
#include <sys/sha2.h>
3333

34-
/* limit benchmarking to max 256KiB, when EdonR is slower then this: */
35-
#define LIMIT_PERF_MBS 300
36-
3734
typedef struct {
3835
const char *name;
3936
const char *impl;
@@ -51,9 +48,15 @@ typedef struct {
5148
zio_checksum_tmpl_free_t *(free);
5249
} chksum_stat_t;
5350

51+
#define AT_STARTUP 0
52+
#define AT_BENCHMARK 1
53+
#define AT_DONE 2
54+
5455
static chksum_stat_t *chksum_stat_data = 0;
55-
static int chksum_stat_cnt = 0;
5656
static kstat_t *chksum_kstat = NULL;
57+
static int chksum_stat_limit = AT_STARTUP;
58+
static int chksum_stat_cnt = 0;
59+
static void chksum_benchmark(void);
5760

5861
/*
5962
* Sample output on i3-1005G1 System:
@@ -128,6 +131,9 @@ chksum_kstat_data(char *buf, size_t size, void *data)
128131
static void *
129132
chksum_kstat_addr(kstat_t *ksp, loff_t n)
130133
{
134+
/* full benchmark */
135+
chksum_benchmark();
136+
131137
if (n < chksum_stat_cnt)
132138
ksp->ks_private = (void *)(chksum_stat_data + n);
133139
else
@@ -175,47 +181,36 @@ chksum_run(chksum_stat_t *cs, abd_t *abd, void *ctx, int round,
175181
kpreempt_enable();
176182

177183
run_bw = size * run_count * NANOSEC;
178-
run_bw /= run_time_ns; /* B/s */
184+
run_bw /= run_time_ns; /* B/s */
179185
*result = run_bw/1024/1024; /* MiB/s */
180186
}
181187

182-
#define LIMIT_INIT 0
183-
#define LIMIT_NEEDED 1
184-
#define LIMIT_NOLIMIT 2
185-
186188
static void
187189
chksum_benchit(chksum_stat_t *cs)
188190
{
189191
abd_t *abd;
190192
void *ctx = 0;
191193
void *salt = &cs->salt.zcs_bytes;
192-
static int chksum_stat_limit = LIMIT_INIT;
193194

194195
memset(salt, 0, sizeof (cs->salt.zcs_bytes));
195196
if (cs->init)
196197
ctx = cs->init(&cs->salt);
197198

199+
/* benchmarks in startup mode */
200+
if (chksum_stat_limit == AT_STARTUP) {
201+
abd = abd_alloc_linear(1<<18, B_FALSE);
202+
chksum_run(cs, abd, ctx, 5, &cs->bs256k);
203+
goto done;
204+
}
205+
198206
/* allocate test memory via abd linear interface */
199207
abd = abd_alloc_linear(1<<20, B_FALSE);
208+
209+
/* benchmarks when requested */
200210
chksum_run(cs, abd, ctx, 1, &cs->bs1k);
201211
chksum_run(cs, abd, ctx, 2, &cs->bs4k);
202212
chksum_run(cs, abd, ctx, 3, &cs->bs16k);
203213
chksum_run(cs, abd, ctx, 4, &cs->bs64k);
204-
chksum_run(cs, abd, ctx, 5, &cs->bs256k);
205-
206-
/* check if we ran on a slow cpu */
207-
if (chksum_stat_limit == LIMIT_INIT) {
208-
if (cs->bs1k < LIMIT_PERF_MBS) {
209-
chksum_stat_limit = LIMIT_NEEDED;
210-
} else {
211-
chksum_stat_limit = LIMIT_NOLIMIT;
212-
}
213-
}
214-
215-
/* skip benchmarks >= 1MiB when the CPU is to slow */
216-
if (chksum_stat_limit == LIMIT_NEEDED)
217-
goto abort;
218-
219214
chksum_run(cs, abd, ctx, 6, &cs->bs1m);
220215
abd_free(abd);
221216

@@ -224,7 +219,7 @@ chksum_benchit(chksum_stat_t *cs)
224219
chksum_run(cs, abd, ctx, 7, &cs->bs4m);
225220
chksum_run(cs, abd, ctx, 8, &cs->bs16m);
226221

227-
abort:
222+
done:
228223
abd_free(abd);
229224

230225
/* free up temp memory */
@@ -242,16 +237,21 @@ chksum_benchmark(void)
242237
/* we need the benchmark only for the kernel module */
243238
return;
244239
#endif
245-
246240
chksum_stat_t *cs;
247241
uint64_t max;
248242
uint32_t id, cbid = 0, id_save;
249243
const zfs_impl_t *blake3 = zfs_impl_get_ops("blake3");
250244
const zfs_impl_t *sha256 = zfs_impl_get_ops("sha256");
251245
const zfs_impl_t *sha512 = zfs_impl_get_ops("sha512");
252246

247+
/* benchmarks are done */
248+
if (chksum_stat_limit == AT_DONE)
249+
return;
250+
251+
253252
/* count implementations */
254-
chksum_stat_cnt = 2;
253+
chksum_stat_cnt = 1; /* edonr */
254+
chksum_stat_cnt += 1; /* skein */
255255
chksum_stat_cnt += sha256->getcnt();
256256
chksum_stat_cnt += sha512->getcnt();
257257
chksum_stat_cnt += blake3->getcnt();
@@ -331,6 +331,17 @@ chksum_benchmark(void)
331331
}
332332
}
333333
blake3->setid(id_save);
334+
335+
switch (chksum_stat_limit) {
336+
case AT_STARTUP:
337+
/* next time we want a full benchmark */
338+
chksum_stat_limit = AT_BENCHMARK;
339+
break;
340+
case AT_BENCHMARK:
341+
/* no further benchmarks */
342+
chksum_stat_limit = AT_DONE;
343+
break;
344+
}
334345
}
335346

336347
void
@@ -340,7 +351,7 @@ chksum_init(void)
340351
blake3_per_cpu_ctx_init();
341352
#endif
342353

343-
/* Benchmark supported implementations */
354+
/* 256KiB benchmark */
344355
chksum_benchmark();
345356

346357
/* Install kstats for all implementations */

0 commit comments

Comments
 (0)