[PATCH 13/17] raid6_kunit: use KUNIT_CASE_PARAM

Christoph Hellwig
2026-03-24T06:44:40Z

The raid6 test combines various generation and recovery algorithms. Use
KUNIT_CASE_PARAM and provide a generator that iterates over the possible
combinations instead of looping inside a single test instance.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
lib/raid/raid6/tests/raid6_kunit.c | 120 ++++++++++++++++-------------
1 file changed, 68 insertions(+), 52 deletions(-)

diff --git a/lib/raid/raid6/tests/raid6_kunit.c b/lib/raid/raid6/tests/raid6_kunit.c
index abc854cf4a98..7095952ad8e3 100644
--- a/lib/raid/raid6/tests/raid6_kunit.c
+++ b/lib/raid/raid6/tests/raid6_kunit.c
@@ -21,6 +21,15 @@ static char data[NDISKS][PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
static char recovi[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
static char recovj[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));

+struct test_args {
+ unsigned int recov_idx;
+ const struct raid6_recov_calls *recov;
+ unsigned int gen_idx;
+ const struct raid6_calls *gen;
+};
+
+static struct test_args args;
+
static void makedata(int start, int stop)
{
int i;
@@ -43,9 +52,10 @@ static char member_type(int d)
}
}

-static void test_disks(struct kunit *test, const struct raid6_calls *calls,
- const struct raid6_recov_calls *ra, int faila, int failb)
+static void test_recover(struct kunit *test, int faila, int failb)
{
+ const struct test_args *ta = test->param_value;
+
memset(recovi, 0xf0, PAGE_SIZE);
memset(recovj, 0xba, PAGE_SIZE);

@@ -64,25 +74,23 @@ static void test_disks(struct kunit *test, const struct raid6_calls *calls,
goto skip;

/* P+Q failure. Just rebuild the syndrome. */
- calls->gen_syndrome(NDISKS, PAGE_SIZE, dataptrs);
+ ta->gen->gen_syndrome(NDISKS, PAGE_SIZE, dataptrs);
} else if (failb == NDISKS - 2) {
/* data+P failure. */
- ra->datap(NDISKS, PAGE_SIZE, faila, dataptrs);
+ ta->recov->datap(NDISKS, PAGE_SIZE, faila, dataptrs);
} else {
/* data+data failure. */
- ra->data2(NDISKS, PAGE_SIZE, faila, failb, dataptrs);
+ ta->recov->data2(NDISKS, PAGE_SIZE, faila, failb, dataptrs);
}

KUNIT_EXPECT_MEMEQ_MSG(test, data[faila], recovi, PAGE_SIZE,
- "algo=%-8s/%-8s faila miscompared: %3d[%c] (failb=%3d[%c])\n",
- calls->name, ra->name,
- faila, member_type(faila),
- failb, member_type(failb));
+ "faila miscompared: %3d[%c] (failb=%3d[%c])\n",
+ faila, member_type(faila),
+ failb, member_type(failb));
KUNIT_EXPECT_MEMEQ_MSG(test, data[failb], recovj, PAGE_SIZE,
- "algo=%-8s/%-8s failb miscompared: %3d[%c] (faila=%3d[%c])\n",
- calls->name, ra->name,
- failb, member_type(failb),
- faila, member_type(faila));
+ "failb miscompared: %3d[%c] (faila=%3d[%c])\n",
+ failb, member_type(failb),
+ faila, member_type(faila));

skip:
dataptrs[faila] = data[faila];
@@ -91,58 +99,65 @@ static void test_disks(struct kunit *test, const struct raid6_calls *calls,

static void raid6_test(struct kunit *test)
{
+ const struct test_args *ta = test->param_value;
int i, j, p1, p2;
- unsigned int r, g;
-
- for (r = 0; ; r++) {
- const struct raid6_recov_calls *ra = raid6_recov_algo_find(r);
-
- if (!ra)
- break;
-
- for (g = 0; ; g++) {
- const struct raid6_calls *calls = raid6_algo_find(g);
-
- if (!calls)
- break;

- /* Nuke syndromes */
- memset(data[NDISKS - 2], 0xee, PAGE_SIZE);
- memset(data[NDISKS - 1], 0xee, PAGE_SIZE);
+ /* Nuke syndromes */
+ memset(data[NDISKS - 2], 0xee, PAGE_SIZE);
+ memset(data[NDISKS - 1], 0xee, PAGE_SIZE);

- /* Generate assumed good syndrome */
- calls->gen_syndrome(NDISKS, PAGE_SIZE,
- (void **)&dataptrs);
+ /* Generate assumed good syndrome */
+ ta->gen->gen_syndrome(NDISKS, PAGE_SIZE, (void **)&dataptrs);

- for (i = 0; i < NDISKS-1; i++)
- for (j = i+1; j < NDISKS; j++)
- test_disks(test, calls, ra, i, j);
+ for (i = 0; i < NDISKS - 1; i++)
+ for (j = i + 1; j < NDISKS; j++)
+ test_recover(test, i, j);

- if (!calls->xor_syndrome)
- continue;
+ if (!ta->gen->xor_syndrome)
+ return;

- for (p1 = 0; p1 < NDISKS-2; p1++)
- for (p2 = p1; p2 < NDISKS-2; p2++) {
+ for (p1 = 0; p1 < NDISKS - 2; p1++) {
+ for (p2 = p1; p2 < NDISKS - 2; p2++) {
+ /* Simulate rmw run */
+ ta->gen->xor_syndrome(NDISKS, p1, p2, PAGE_SIZE,
+ (void **)&dataptrs);
+ makedata(p1, p2);
+ ta->gen->xor_syndrome(NDISKS, p1, p2, PAGE_SIZE,
+ (void **)&dataptrs);

- /* Simulate rmw run */
- calls->xor_syndrome(NDISKS, p1, p2, PAGE_SIZE,
- (void **)&dataptrs);
- makedata(p1, p2);
- calls->xor_syndrome(NDISKS, p1, p2, PAGE_SIZE,
- (void **)&dataptrs);
+ for (i = 0; i < NDISKS - 1; i++)
+ for (j = i + 1; j < NDISKS; j++)
+ test_recover(test, i, j);
+ }
+ }
+}

- for (i = 0; i < NDISKS-1; i++)
- for (j = i+1; j < NDISKS; j++)
- test_disks(test, calls,
- ra, i, j);
- }
+static const void *raid6_gen_params(struct kunit *test, const void *prev,
+ char *desc)
+{
+ if (!args.gen) {
+next_algo:
+ args.recov_idx = 0;
+ args.gen = raid6_algo_find(args.gen_idx);
+ if (!args.gen)
+ return NULL;
+ }

- }
+ if (args.recov)
+ args.recov_idx++;
+ args.recov = raid6_recov_algo_find(args.recov_idx);
+ if (!args.recov) {
+ args.gen_idx++;
+ goto next_algo;
}
+
+ snprintf(desc, KUNIT_PARAM_DESC_SIZE, "gen=%s recov=%s",
+ args.gen->name, args.recov->name);
+ return &args;
}

static struct kunit_case raid6_test_cases[] = {
- KUNIT_CASE(raid6_test),
+ KUNIT_CASE_PARAM(raid6_test, raid6_gen_params),
{},
};

@@ -150,6 +165,7 @@ static int raid6_suite_init(struct kunit_suite *suite)
{
prandom_seed_state(&rng, RAID6_KUNIT_SEED);
makedata(0, NDISKS - 1);
+ memset(&args, 0, sizeof(args));
return 0;
}

--
2.47.3