Commit 2f0dbb24 authored by Mark Brown's avatar Mark Brown

regmap: kunit: Ensure that changed bytes are actually different

During the cache sync test we verify that values we expect to have been
written only to the cache do not appear in the hardware. This works most
of the time but since we randomly generate both the original and new values
there is a low probability that these values may actually be the same.
Wrap get_random_bytes() to ensure that the values are different, there
are other tests which should have similar verification that we actually
changed something.

While we're at it refactor the test to use three changed values rather
than attempting to use one of them twice, that just complicates checking
that our new values are actually new.

We use random generation to try to avoid data dependencies in the tests.
Reported-by: default avatarGuenter Roeck <linux@roeck-us.net>
Reviewed-by: default avatarGuenter Roeck <linux@roeck-us.net>
Tested-by: default avatarGuenter Roeck <linux@roeck-us.net>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
Link: https://msgid.link/r/20240211-regmap-kunit-random-change-v3-1-e387a9ea4468@kernel.orgSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent 7011b51f
...@@ -9,6 +9,23 @@ ...@@ -9,6 +9,23 @@
#define BLOCK_TEST_SIZE 12 #define BLOCK_TEST_SIZE 12
static void get_changed_bytes(void *orig, void *new, size_t size)
{
char *o = orig;
char *n = new;
int i;
get_random_bytes(new, size);
/*
* This could be nicer and more efficient but we shouldn't
* super care.
*/
for (i = 0; i < size; i++)
while (n[i] == o[i])
get_random_bytes(&n[i], 1);
}
static const struct regmap_config test_regmap_config = { static const struct regmap_config test_regmap_config = {
.max_register = BLOCK_TEST_SIZE, .max_register = BLOCK_TEST_SIZE,
.reg_stride = 1, .reg_stride = 1,
...@@ -1252,7 +1269,7 @@ static void raw_sync(struct kunit *test) ...@@ -1252,7 +1269,7 @@ static void raw_sync(struct kunit *test)
struct regmap *map; struct regmap *map;
struct regmap_config config; struct regmap_config config;
struct regmap_ram_data *data; struct regmap_ram_data *data;
u16 val[2]; u16 val[3];
u16 *hw_buf; u16 *hw_buf;
unsigned int rval; unsigned int rval;
int i; int i;
...@@ -1266,17 +1283,13 @@ static void raw_sync(struct kunit *test) ...@@ -1266,17 +1283,13 @@ static void raw_sync(struct kunit *test)
hw_buf = (u16 *)data->vals; hw_buf = (u16 *)data->vals;
get_random_bytes(&val, sizeof(val)); get_changed_bytes(&hw_buf[2], &val[0], sizeof(val));
/* Do a regular write and a raw write in cache only mode */ /* Do a regular write and a raw write in cache only mode */
regcache_cache_only(map, true); regcache_cache_only(map, true);
KUNIT_EXPECT_EQ(test, 0, regmap_raw_write(map, 2, val, sizeof(val))); KUNIT_EXPECT_EQ(test, 0, regmap_raw_write(map, 2, val,
if (config.val_format_endian == REGMAP_ENDIAN_BIG) sizeof(u16) * 2));
KUNIT_EXPECT_EQ(test, 0, regmap_write(map, 6, KUNIT_EXPECT_EQ(test, 0, regmap_write(map, 4, val[2]));
be16_to_cpu(val[0])));
else
KUNIT_EXPECT_EQ(test, 0, regmap_write(map, 6,
le16_to_cpu(val[0])));
/* We should read back the new values, and defaults for the rest */ /* We should read back the new values, and defaults for the rest */
for (i = 0; i < config.max_register + 1; i++) { for (i = 0; i < config.max_register + 1; i++) {
...@@ -1285,24 +1298,34 @@ static void raw_sync(struct kunit *test) ...@@ -1285,24 +1298,34 @@ static void raw_sync(struct kunit *test)
switch (i) { switch (i) {
case 2: case 2:
case 3: case 3:
case 6:
if (config.val_format_endian == REGMAP_ENDIAN_BIG) { if (config.val_format_endian == REGMAP_ENDIAN_BIG) {
KUNIT_EXPECT_EQ(test, rval, KUNIT_EXPECT_EQ(test, rval,
be16_to_cpu(val[i % 2])); be16_to_cpu(val[i - 2]));
} else { } else {
KUNIT_EXPECT_EQ(test, rval, KUNIT_EXPECT_EQ(test, rval,
le16_to_cpu(val[i % 2])); le16_to_cpu(val[i - 2]));
} }
break; break;
case 4:
KUNIT_EXPECT_EQ(test, rval, val[i - 2]);
break;
default: default:
KUNIT_EXPECT_EQ(test, config.reg_defaults[i].def, rval); KUNIT_EXPECT_EQ(test, config.reg_defaults[i].def, rval);
break; break;
} }
} }
/*
* The value written via _write() was translated by the core,
* translate the original copy for comparison purposes.
*/
if (config.val_format_endian == REGMAP_ENDIAN_BIG)
val[2] = cpu_to_be16(val[2]);
else
val[2] = cpu_to_le16(val[2]);
/* The values should not appear in the "hardware" */ /* The values should not appear in the "hardware" */
KUNIT_EXPECT_MEMNEQ(test, &hw_buf[2], val, sizeof(val)); KUNIT_EXPECT_MEMNEQ(test, &hw_buf[2], &val[0], sizeof(val));
KUNIT_EXPECT_MEMNEQ(test, &hw_buf[6], val, sizeof(u16));
for (i = 0; i < config.max_register + 1; i++) for (i = 0; i < config.max_register + 1; i++)
data->written[i] = false; data->written[i] = false;
...@@ -1313,8 +1336,7 @@ static void raw_sync(struct kunit *test) ...@@ -1313,8 +1336,7 @@ static void raw_sync(struct kunit *test)
KUNIT_EXPECT_EQ(test, 0, regcache_sync(map)); KUNIT_EXPECT_EQ(test, 0, regcache_sync(map));
/* The values should now appear in the "hardware" */ /* The values should now appear in the "hardware" */
KUNIT_EXPECT_MEMEQ(test, &hw_buf[2], val, sizeof(val)); KUNIT_EXPECT_MEMEQ(test, &hw_buf[2], &val[0], sizeof(val));
KUNIT_EXPECT_MEMEQ(test, &hw_buf[6], val, sizeof(u16));
regmap_exit(map); regmap_exit(map);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment