Skip to content

Commit df97b26

Browse files
committed
Faster checksum benchmark on system boot
While booting, only the needed 256KiB benchmarks are done now. The long delay for testing all checksums is done on request: - Linux: cat /proc/spl/kstat/zfs/chksum_bench - FreeBSD: sysctl kstat.zfs.misc.chksum_bench Signed-off-by: Tino Reichardt <[email protected]> Closes #17560
1 parent bf38c15 commit df97b26

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
@@ -32,9 +32,6 @@
3232
#include <sys/blake3.h>
3333
#include <sys/sha2.h>
3434

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

52+
#define AT_STARTUP 0
53+
#define AT_BENCHMARK 1
54+
#define AT_DONE 2
55+
5556
static chksum_stat_t *chksum_stat_data = 0;
56-
static int chksum_stat_cnt = 0;
5757
static kstat_t *chksum_kstat = NULL;
58+
static int chksum_stat_limit = AT_STARTUP;
59+
static int chksum_stat_cnt = 0;
60+
static void chksum_benchmark(void);
5861

5962
/*
6063
* Sample output on i3-1005G1 System:
@@ -129,6 +132,9 @@ chksum_kstat_data(char *buf, size_t size, void *data)
129132
static void *
130133
chksum_kstat_addr(kstat_t *ksp, loff_t n)
131134
{
135+
/* full benchmark */
136+
chksum_benchmark();
137+
132138
if (n < chksum_stat_cnt)
133139
ksp->ks_private = (void *)(chksum_stat_data + n);
134140
else
@@ -176,47 +182,36 @@ chksum_run(chksum_stat_t *cs, abd_t *abd, void *ctx, int round,
176182
kpreempt_enable();
177183

178184
run_bw = size * run_count * NANOSEC;
179-
run_bw /= run_time_ns; /* B/s */
185+
run_bw /= run_time_ns; /* B/s */
180186
*result = run_bw/1024/1024; /* MiB/s */
181187
}
182188

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

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

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

@@ -225,7 +220,7 @@ chksum_benchit(chksum_stat_t *cs)
225220
chksum_run(cs, abd, ctx, 7, &cs->bs4m);
226221
chksum_run(cs, abd, ctx, 8, &cs->bs16m);
227222

228-
abort:
223+
done:
229224
abd_free(abd);
230225

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

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

337348
void
@@ -341,7 +352,7 @@ chksum_init(void)
341352
blake3_per_cpu_ctx_init();
342353
#endif
343354

344-
/* Benchmark supported implementations */
355+
/* 256KiB benchmark */
345356
chksum_benchmark();
346357

347358
/* Install kstats for all implementations */

0 commit comments

Comments
 (0)