From: sunliming@linux.dev
To: song@kernel.org, yukuai@fnnas.com, akpm@linux-foundation.org
Cc: linux-raid@vger.kernel.org, linux-kernel@vger.kernel.org,
sunliming <sunliming@kylinos.cn>
Subject: [PATCH RESEND v3 1/3] lib/raid6: Divide the raid6 algorithm selection process into two parts
Date: Fri, 20 Mar 2026 14:00:19 +0800 [thread overview]
Message-ID: <20260320060021.30762-2-sunliming@linux.dev> (raw)
In-Reply-To: <20260320060021.30762-1-sunliming@linux.dev>
From: sunliming <sunliming@kylinos.cn>
Divide the RAID6 algorithm selection process into two parts: fast selection
and benchmark selection. To prepare for the asynchronous processing of
the benchmark phase.
Signed-off-by: sunliming <sunliming@kylinos.cn>
---
lib/raid6/algos.c | 76 +++++++++++++++++++++++++++++++++--------------
1 file changed, 54 insertions(+), 22 deletions(-)
diff --git a/lib/raid6/algos.c b/lib/raid6/algos.c
index 799e0e5eac26..c21e3ad99d97 100644
--- a/lib/raid6/algos.c
+++ b/lib/raid6/algos.c
@@ -152,8 +152,32 @@ static inline const struct raid6_recov_calls *raid6_choose_recov(void)
return best;
}
-static inline const struct raid6_calls *raid6_choose_gen(
- void *(*const dptrs)[RAID6_TEST_DISKS], const int disks)
+/* Quick selection: select the highest priority valid algorithm. */
+static inline int raid6_choose_gen_fast(void)
+{
+ int ret = 0;
+ const struct raid6_calls *const *algo;
+ const struct raid6_calls *best = NULL;
+
+ for (best = NULL, algo = raid6_algos; *algo; algo++)
+ if (!best || (*algo)->priority > best->priority)
+ if (!(*algo)->valid || (*algo)->valid())
+ best = *algo;
+
+ if (best) {
+ raid6_call = *best;
+ pr_info("raid6: skipped pq benchmark and selected %s\n",
+ best->name);
+ } else {
+ pr_err("raid6: No valid algorithm found even for fast selection!\n");
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static inline const struct raid6_calls *raid6_gen_benchmark(
+ void *(*const dptrs)[RAID6_TEST_DISKS], const int disks)
{
unsigned long perf, bestgenperf, j0, j1;
int start = (disks>>1)-1, stop = disks-3; /* work on the second half of the disks */
@@ -165,11 +189,6 @@ static inline const struct raid6_calls *raid6_choose_gen(
if ((*algo)->valid && !(*algo)->valid())
continue;
- if (!IS_ENABLED(CONFIG_RAID6_PQ_BENCHMARK)) {
- best = *algo;
- break;
- }
-
perf = 0;
preempt_disable();
@@ -200,12 +219,6 @@ static inline const struct raid6_calls *raid6_choose_gen(
raid6_call = *best;
- if (!IS_ENABLED(CONFIG_RAID6_PQ_BENCHMARK)) {
- pr_info("raid6: skipped pq benchmark and selected %s\n",
- best->name);
- goto out;
- }
-
pr_info("raid6: using algorithm %s gen() %ld MB/s\n",
best->name,
(bestgenperf * HZ * (disks - 2)) >>
@@ -239,15 +252,13 @@ static inline const struct raid6_calls *raid6_choose_gen(
/* Try to pick the best algorithm */
/* This code uses the gfmul table as convenient data set to abuse */
-int __init raid6_select_algo(void)
+static int raid6_choose_gen_benmark(void)
{
const int disks = RAID6_TEST_DISKS;
-
const struct raid6_calls *gen_best;
- const struct raid6_recov_calls *rec_best;
char *disk_ptr, *p;
void *dptrs[RAID6_TEST_DISKS];
- int i, cycle;
+ int i, cycle, ret = 0;
/* prepare the buffer and fill it circularly with gfmul table */
disk_ptr = (char *)__get_free_pages(GFP_KERNEL, RAID6_TEST_DISKS_ORDER);
@@ -269,15 +280,36 @@ int __init raid6_select_algo(void)
if ((disks - 2) * PAGE_SIZE % 65536)
memcpy(p, raid6_gfmul, (disks - 2) * PAGE_SIZE % 65536);
- /* select raid gen_syndrome function */
- gen_best = raid6_choose_gen(&dptrs, disks);
+ gen_best = raid6_gen_benchmark(&dptrs, disks);
+ if (!gen_best)
+ ret = -EINVAL;
+
+ free_pages((unsigned long)disk_ptr, RAID6_TEST_DISKS_ORDER);
+
+ return ret;
+}
+
+int __init raid6_select_algo(void)
+{
+ int ret = 0;
+ const struct raid6_recov_calls *rec_best = NULL;
+
+ /* select raid gen_syndrome functions */
+ if (!IS_ENABLED(CONFIG_RAID6_PQ_BENCHMARK))
+ ret = raid6_choose_gen_fast();
+ else
+ ret = raid6_choose_gen_benmark();
+
+ if (ret < 0)
+ goto out;
/* select raid recover functions */
rec_best = raid6_choose_recov();
+ if (!rec_best)
+ ret = -EINVAL;
- free_pages((unsigned long)disk_ptr, RAID6_TEST_DISKS_ORDER);
-
- return gen_best && rec_best ? 0 : -EINVAL;
+out:
+ return ret;
}
static void raid6_exit(void)
--
2.25.1
next prev parent reply other threads:[~2026-03-20 6:02 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-20 6:00 [PATCH RESEND v3 0/3] lib/raid6: Optimize raid6_select_algo to ensure sunliming
2026-03-20 6:00 ` sunliming [this message]
2026-03-20 6:00 ` [PATCH RESEND v3 2/3] lib/raid6: Optimizing the raid6_select_algo time through asynchronous processing sunliming
-- strict thread matches above, loose matches on Subject: below --
2026-03-20 6:07 [PATCH RESEND v3 0/3] lib/raid6: Optimize raid6_select_algo to ensure sunliming
2026-03-20 6:07 ` [PATCH RESEND v3 1/3] lib/raid6: Divide the raid6 algorithm selection process into two parts sunliming
2026-03-24 7:55 ` Christoph Hellwig
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260320060021.30762-2-sunliming@linux.dev \
--to=sunliming@linux.dev \
--cc=akpm@linux-foundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-raid@vger.kernel.org \
--cc=song@kernel.org \
--cc=sunliming@kylinos.cn \
--cc=yukuai@fnnas.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.