Add a KUnit test for strnlen() to verify correctness across
different string lengths and memory alignments.
Signed-off-by: Feng Jiang <jiangfeng@kylinos.cn>
---
lib/tests/string_kunit.c | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/lib/tests/string_kunit.c b/lib/tests/string_kunit.c
index 9f4fc72f0886..1d08850e439c 100644
--- a/lib/tests/string_kunit.c
+++ b/lib/tests/string_kunit.c
@@ -126,6 +126,35 @@ static void string_test_strlen(struct kunit *test)
}
}
+static void string_test_strnlen(struct kunit *test)
+{
+ char *s;
+ size_t len, offset;
+ const size_t buf_size = 16 + 128 + 1; /* max_offset + max_len + '\0' */
+
+ s = kunit_kzalloc(test, buf_size, GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, s);
+
+ memset(s, 'A', buf_size);
+ s[buf_size - 1] = '\0';
+
+ for (offset = 0; offset < 16; offset++) {
+ for (len = 0; len <= 128; len++) {
+ s[offset + len] = '\0';
+
+ if (len > 0)
+ KUNIT_EXPECT_EQ(test, strnlen(s + offset, len - 1), len - 1);
+
+ KUNIT_EXPECT_EQ(test, strnlen(s + offset, len), len);
+
+ KUNIT_EXPECT_EQ(test, strnlen(s + offset, len + 1), len);
+ KUNIT_EXPECT_EQ(test, strnlen(s + offset, len + 10), len);
+
+ s[offset + len] = 'A';
+ }
+ }
+}
+
static void string_test_strchr(struct kunit *test)
{
const char *test_string = "abcdefghijkl";
@@ -641,6 +670,7 @@ static struct kunit_case string_test_cases[] = {
KUNIT_CASE(string_test_memset32),
KUNIT_CASE(string_test_memset64),
KUNIT_CASE(string_test_strlen),
+ KUNIT_CASE(string_test_strnlen),
KUNIT_CASE(string_test_strchr),
KUNIT_CASE(string_test_strnchr),
KUNIT_CASE(string_test_strspn),
--
2.25.1
On Wed, Jan 7, 2026 at 4:35 AM Feng Jiang <jiangfeng@kylinos.cn> wrote:
>
> Add a KUnit test for strnlen() to verify correctness across
> different string lengths and memory alignments.
Same comment as per patch 1 (it would probably require to call for
arch_strnlen() or something like this).
...
> + for (offset = 0; offset < 16; offset++) {
> + for (len = 0; len <= 128; len++) {
You want to define these two limits to avoid the possible issues in
the future if the code gets changed.
> + }
--
With Best Regards,
Andy Shevchenko
On 2026/1/7 19:56, Andy Shevchenko wrote:
> On Wed, Jan 7, 2026 at 4:35 AM Feng Jiang <jiangfeng@kylinos.cn> wrote:
>>
>> Add a KUnit test for strnlen() to verify correctness across
>> different string lengths and memory alignments.
>
> Same comment as per patch 1 (it would probably require to call for
> arch_strnlen() or something like this).
Thanks, makes sense.
I'll add the performance benchmarking (random filling + timing) in V2.
Since string functions are typically exported directly by each architecture
without an arch_ prefix, I'll introduce a generic_strnlen() (based on
lib/string.c) within the test for comparison.
> ...
>
>> + for (offset = 0; offset < 16; offset++) {
>> + for (len = 0; len <= 128; len++) {
>
> You want to define these two limits to avoid the possible issues in
> the future if the code gets changed.
Got it, will define these limits as macros in V2. Thanks!
--
With Best Regards,
Feng Jiang
On Thu, Jan 08, 2026 at 02:53:58PM +0800, Feng Jiang wrote: > On 2026/1/7 19:56, Andy Shevchenko wrote: > > On Wed, Jan 7, 2026 at 4:35 AM Feng Jiang <jiangfeng@kylinos.cn> wrote: ... > >> Add a KUnit test for strnlen() to verify correctness across > >> different string lengths and memory alignments. > > > > Same comment as per patch 1 (it would probably require to call for > > arch_strnlen() or something like this). > > Thanks, makes sense. > > I'll add the performance benchmarking (random filling + timing) in V2. > > Since string functions are typically exported directly by each architecture > without an arch_ prefix, I'll introduce a generic_strnlen() (based on > lib/string.c) within the test for comparison. Probably you want to make the existing one to have that name and use it inside the test and in the fallback wrapper. We don't want to have duplicate code, it is bad from maintenance perspective. -- With Best Regards, Andy Shevchenko
On 2026/1/8 15:26, Andy Shevchenko wrote: > On Thu, Jan 08, 2026 at 02:53:58PM +0800, Feng Jiang wrote: >> On 2026/1/7 19:56, Andy Shevchenko wrote: >>> On Wed, Jan 7, 2026 at 4:35 AM Feng Jiang <jiangfeng@kylinos.cn> wrote: > > ... > >>>> Add a KUnit test for strnlen() to verify correctness across >>>> different string lengths and memory alignments. >>> >>> Same comment as per patch 1 (it would probably require to call for >>> arch_strnlen() or something like this). >> >> Thanks, makes sense. >> >> I'll add the performance benchmarking (random filling + timing) in V2. >> >> Since string functions are typically exported directly by each architecture >> without an arch_ prefix, I'll introduce a generic_strnlen() (based on >> lib/string.c) within the test for comparison. > > Probably you want to make the existing one to have that name and use it inside > the test and in the fallback wrapper. We don't want to have duplicate code, it > is bad from maintenance perspective. > Thanks for the suggestions! To avoid code duplication, I'll rename the generic implementation in lib/string.c to __generic_strnlen() and keep the original strnlen() as a wrapper. Then I'll use the generic one in the KUnit test for comparison. Does this approach look good to you? -- With Best Regards, Feng Jiang
On Thu, Jan 08, 2026 at 06:00:21PM +0800, Feng Jiang wrote: > On 2026/1/8 15:26, Andy Shevchenko wrote: > > On Thu, Jan 08, 2026 at 02:53:58PM +0800, Feng Jiang wrote: > >> On 2026/1/7 19:56, Andy Shevchenko wrote: > >>> On Wed, Jan 7, 2026 at 4:35 AM Feng Jiang <jiangfeng@kylinos.cn> wrote: ... > >>>> Add a KUnit test for strnlen() to verify correctness across > >>>> different string lengths and memory alignments. > >>> > >>> Same comment as per patch 1 (it would probably require to call for > >>> arch_strnlen() or something like this). > >> > >> Thanks, makes sense. > >> > >> I'll add the performance benchmarking (random filling + timing) in V2. > >> > >> Since string functions are typically exported directly by each architecture > >> without an arch_ prefix, I'll introduce a generic_strnlen() (based on > >> lib/string.c) within the test for comparison. > > > > Probably you want to make the existing one to have that name and use it inside > > the test and in the fallback wrapper. We don't want to have duplicate code, it > > is bad from maintenance perspective. > > Thanks for the suggestions! > > To avoid code duplication, I'll rename the generic implementation in lib/string.c > to __generic_strnlen() and keep the original strnlen() as a wrapper. Then I'll use > the generic one in the KUnit test for comparison. > > Does this approach look good to you? To me, yes. To others, we will know later on when you send a new version. -- With Best Regards, Andy Shevchenko
© 2016 - 2026 Red Hat, Inc.