raid6: improve the runtime selection benchmark

Use plain ktime_get_ns for the timing, use 8 + 2 disks for a realistic
load, and report the throughput on the data disks as that is what storage
systems are measured on.

Link: https://lore.kernel.org/20260715144825.95432-8-hch@lst.de
Signed-off-by: Christoph Hellwig <hch@lst.de>
Cc: Eric Biggers <ebiggers@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
Christoph Hellwig
2026-07-30 19:50:13 -07:00
committed by Andrew Morton
parent 2d5958f9d9
commit d335ba3a33
+35 -42
View File
@@ -152,40 +152,37 @@ void raid6_recov_datap(int disks, size_t bytes, int faila, void **ptrs)
}
EXPORT_SYMBOL_GPL(raid6_recov_datap);
#define RAID6_TIME_JIFFIES_LG2 4
#define RAID6_TEST_DISKS 8
#define BENCH_SIZE SZ_4K
#define NR_SRCS 8
#define NR_DISKS (NR_SRCS + 2)
#define REPS 800U
static int raid6_choose_gen(void *(*const dptrs)[RAID6_TEST_DISKS],
const int disks)
static int raid6_choose_gen(void *dptrs[NR_DISKS], const int disks)
{
/* work on the second half of the disks */
int start = (disks >> 1) - 1, stop = disks - 3;
const struct raid6_calls *best = NULL;
unsigned long bestgenperf = 0;
unsigned int i;
for (i = 0; i < raid6_nr_algos; i++) {
const struct raid6_calls *algo = raid6_algos[i];
unsigned long perf = 0, j0, j1;
unsigned long perf = 0;
u64 t;
int i;
preempt_disable();
j0 = jiffies;
while ((j1 = jiffies) == j0)
cpu_relax();
while (time_before(jiffies,
j1 + (1<<RAID6_TIME_JIFFIES_LG2))) {
algo->gen_syndrome(disks, PAGE_SIZE, *dptrs);
perf++;
}
t = ktime_get_ns();
for (i = 0; i < REPS; i++)
algo->gen_syndrome(disks, BENCH_SIZE, dptrs);
t = max(ktime_get_ns() - t, 1);
preempt_enable();
/* bytes/ns == GB/s, multiply by 1000 to get MB/s [not MiB/s] */
perf = div64_u64((u64)BENCH_SIZE * REPS * NR_SRCS * 1000, t);
if (perf > bestgenperf) {
bestgenperf = perf;
best = algo;
}
pr_info("raid6: %-8s gen() %5ld MB/s\n", algo->name,
(perf * HZ * (disks-2)) >>
(20 - PAGE_SHIFT + RAID6_TIME_JIFFIES_LG2));
pr_info("raid6: %-8s gen() %5lu MB/s\n", algo->name, perf);
}
if (!best) {
@@ -197,28 +194,24 @@ static int raid6_choose_gen(void *(*const dptrs)[RAID6_TEST_DISKS],
static_call_update(raid6_xor_syndrome_impl, best->xor_syndrome);
pr_info("raid6: using algorithm %s gen() %ld MB/s\n",
best->name,
(bestgenperf * HZ * (disks - 2)) >>
(20 - PAGE_SHIFT + RAID6_TIME_JIFFIES_LG2));
best->name, bestgenperf);
if (best->xor_syndrome) {
unsigned long perf = 0, j0, j1;
/* work on the second half of the disks */
int start = (disks / 2) - 1, stop = disks - 3;
u64 t;
preempt_disable();
j0 = jiffies;
while ((j1 = jiffies) == j0)
cpu_relax();
while (time_before(jiffies,
j1 + (1 << RAID6_TIME_JIFFIES_LG2))) {
best->xor_syndrome(disks, start, stop,
PAGE_SIZE, *dptrs);
perf++;
}
t = ktime_get_ns();
for (i = 0; i < REPS; i++)
best->xor_syndrome(disks, start, stop, BENCH_SIZE,
dptrs);
t = max(ktime_get_ns() - t, 1);
preempt_enable();
pr_info("raid6: .... xor() %ld MB/s, rmw enabled\n",
(perf * HZ * (disks - 2)) >>
(20 - PAGE_SHIFT + RAID6_TIME_JIFFIES_LG2 + 1));
pr_info("raid6: .... xor() %llu MB/s, rmw enabled\n",
div64_u64((u64)BENCH_SIZE * REPS * NR_SRCS / 2 * 1000,
t));
}
return 0;
@@ -230,9 +223,9 @@ static int raid6_choose_gen(void *(*const dptrs)[RAID6_TEST_DISKS],
static int __init raid6_select_algo(void)
{
const int disks = RAID6_TEST_DISKS;
const int disks = NR_DISKS;
void *dptrs[NR_DISKS];
char *disk_ptr, *p;
void *dptrs[RAID6_TEST_DISKS];
int i, cycle;
int error;
@@ -243,7 +236,7 @@ static int __init raid6_select_algo(void)
}
/* prepare the buffer and fill it circularly with gfmul table */
disk_ptr = kmalloc(PAGE_SIZE * RAID6_TEST_DISKS, GFP_KERNEL);
disk_ptr = kmalloc_array(NR_DISKS, BENCH_SIZE, GFP_KERNEL);
if (!disk_ptr) {
pr_err("raid6: Yikes! No memory available.\n");
return -ENOMEM;
@@ -251,19 +244,19 @@ static int __init raid6_select_algo(void)
p = disk_ptr;
for (i = 0; i < disks; i++)
dptrs[i] = p + PAGE_SIZE * i;
dptrs[i] = p + BENCH_SIZE * i;
cycle = ((disks - 2) * PAGE_SIZE) / 65536;
cycle = ((disks - 2) * BENCH_SIZE) / 65536;
for (i = 0; i < cycle; i++) {
memcpy(p, raid6_gfmul, 65536);
p += 65536;
}
if ((disks - 2) * PAGE_SIZE % 65536)
memcpy(p, raid6_gfmul, (disks - 2) * PAGE_SIZE % 65536);
if ((disks - 2) * BENCH_SIZE % 65536)
memcpy(p, raid6_gfmul, (disks - 2) * BENCH_SIZE % 65536);
/* select raid gen_syndrome function */
error = raid6_choose_gen(&dptrs, disks);
error = raid6_choose_gen(dptrs, disks);
kfree(disk_ptr);