* [PATCH v5] char: misc: add test cases
@ 2025-06-12 17:32 Thadeu Lima de Souza Cascardo
2025-07-09 13:14 ` kernel test robot
2025-07-30 7:08 ` Geert Uytterhoeven
0 siblings, 2 replies; 6+ messages in thread
From: Thadeu Lima de Souza Cascardo @ 2025-06-12 17:32 UTC (permalink / raw)
To: Arnd Bergmann, Greg Kroah-Hartman
Cc: Andrew Morton, Dirk VanDerMerwe, Vimal Agrawal, linux-kernel,
kernel-dev, Thadeu Lima de Souza Cascardo
Add test cases for static and dynamic minor number allocation and
deallocation.
While at it, improve description and test suite name.
Some of the cases include:
- that static and dynamic allocation reserved the expected minors.
- that registering duplicate minors or duplicate names will fail.
- that failing to create a sysfs file (due to duplicate names) will
deallocate the dynamic minor correctly.
- that dynamic allocation does not allocate a minor number in the static
range.
- that there are no collisions when mixing dynamic and static allocations.
- that opening devices with various minor device numbers work.
- that registering a static number in the dynamic range won't conflict with
a dynamic allocation.
This last test verifies the bug fixed by commit 6d04d2b554b1 ("misc:
misc_minor_alloc to use ida for all dynamic/misc dynamic minors") has not
regressed.
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
---
This improves the miscdevice KUnit test, including a lot of corner cases,
specially ones that would fail before past fixes.
This has been built and tested with different architectures, including
ppc64 (built using its defconfig), riscv, m68k, arm64 and x86_64.
---
Changes in v5:
- Make miscdevice unit test built-in only
- Make unit test require CONFIG_KUNIT=y
- Link to v4: https://lore.kernel.org/r/20250423-misc-dynrange-v4-0-133b5ae4ca18@igalia.com
Changes in v4:
- mark some tests as init-only, since they use init-only symbols
- Link to v3: https://lore.kernel.org/r/20250318-misc-dynrange-v3-0-5c6507cbc2e2@igalia.com
Changes in v3:
- remove code around DYNAMIC_MINORS and the backwards allocation
- try to open devices in tests by using init_mknod plus filp_open
- Link to v2: https://lore.kernel.org/r/20250307-misc-dynrange-v2-0-6fe19032ef76@igalia.com
---
drivers/misc/misc_minor_kunit.c | 589 +++++++++++++++++++++++++++++++++++++++-
lib/Kconfig.debug | 4 +-
2 files changed, 589 insertions(+), 4 deletions(-)
diff --git a/drivers/misc/misc_minor_kunit.c b/drivers/misc/misc_minor_kunit.c
index 293e0fb7e43edc330842722e1132d16cd23e3aa8..30eceac5f1b6402b0f918af6f56602ed1a6c14ec 100644
--- a/drivers/misc/misc_minor_kunit.c
+++ b/drivers/misc/misc_minor_kunit.c
@@ -3,6 +3,9 @@
#include <kunit/test-bug.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/init_syscalls.h>
/* dynamic minor (2) */
static struct miscdevice dev_dynamic_minor = {
@@ -51,19 +54,601 @@ static void kunit_misc_dynamic_minor(struct kunit *test)
misc_deregister(&dev_misc_dynamic_minor);
}
+struct miscdev_test_case {
+ const char *str;
+ int minor;
+};
+
+static struct miscdev_test_case miscdev_test_ranges[] = {
+ {
+ .str = "lower static range, top",
+ .minor = 15,
+ },
+ {
+ .str = "upper static range, bottom",
+ .minor = 130,
+ },
+ {
+ .str = "lower static range, bottom",
+ .minor = 0,
+ },
+ {
+ .str = "upper static range, top",
+ .minor = MISC_DYNAMIC_MINOR - 1,
+ },
+};
+
+KUNIT_ARRAY_PARAM_DESC(miscdev, miscdev_test_ranges, str);
+
+static int miscdev_find_minors(struct kunit_suite *suite)
+{
+ int ret;
+ struct miscdevice miscstat = {
+ .name = "miscstat",
+ };
+ int i;
+
+ for (i = 15; i >= 0; i--) {
+ miscstat.minor = i;
+ ret = misc_register(&miscstat);
+ if (ret == 0)
+ break;
+ }
+
+ if (ret == 0) {
+ kunit_info(suite, "found misc device minor %d available\n",
+ miscstat.minor);
+ miscdev_test_ranges[0].minor = miscstat.minor;
+ misc_deregister(&miscstat);
+ } else {
+ return ret;
+ }
+
+ for (i = 128; i < MISC_DYNAMIC_MINOR; i++) {
+ miscstat.minor = i;
+ ret = misc_register(&miscstat);
+ if (ret == 0)
+ break;
+ }
+
+ if (ret == 0) {
+ kunit_info(suite, "found misc device minor %d available\n",
+ miscstat.minor);
+ miscdev_test_ranges[1].minor = miscstat.minor;
+ misc_deregister(&miscstat);
+ } else {
+ return ret;
+ }
+
+ for (i = 0; i < miscdev_test_ranges[0].minor; i++) {
+ miscstat.minor = i;
+ ret = misc_register(&miscstat);
+ if (ret == 0)
+ break;
+ }
+
+ if (ret == 0) {
+ kunit_info(suite, "found misc device minor %d available\n",
+ miscstat.minor);
+ miscdev_test_ranges[2].minor = miscstat.minor;
+ misc_deregister(&miscstat);
+ } else {
+ return ret;
+ }
+
+ for (i = MISC_DYNAMIC_MINOR - 1; i > miscdev_test_ranges[1].minor; i--) {
+ miscstat.minor = i;
+ ret = misc_register(&miscstat);
+ if (ret == 0)
+ break;
+ }
+
+ if (ret == 0) {
+ kunit_info(suite, "found misc device minor %d available\n",
+ miscstat.minor);
+ miscdev_test_ranges[3].minor = miscstat.minor;
+ misc_deregister(&miscstat);
+ }
+
+ return ret;
+}
+
+static bool is_valid_dynamic_minor(int minor)
+{
+ if (minor < 0)
+ return false;
+ if (minor == MISC_DYNAMIC_MINOR)
+ return false;
+ if (minor >= 0 && minor <= 15)
+ return false;
+ if (minor >= 128 && minor < MISC_DYNAMIC_MINOR)
+ return false;
+ return true;
+}
+
+static int miscdev_test_open(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+static const struct file_operations miscdev_test_fops = {
+ .open = miscdev_test_open,
+};
+
+static void __init miscdev_test_can_open(struct kunit *test, struct miscdevice *misc)
+{
+ int ret;
+ struct file *filp;
+ char *devname;
+
+ devname = kasprintf(GFP_KERNEL, "/dev/%s", misc->name);
+ ret = init_mknod(devname, S_IFCHR | 0600,
+ new_encode_dev(MKDEV(MISC_MAJOR, misc->minor)));
+ if (ret != 0)
+ KUNIT_FAIL(test, "failed to create node\n");
+
+ filp = filp_open(devname, O_RDONLY, 0);
+ if (IS_ERR_OR_NULL(filp))
+ KUNIT_FAIL(test, "failed to open misc device: %ld\n", PTR_ERR(filp));
+ else
+ fput(filp);
+
+ init_unlink(devname);
+ kfree(devname);
+}
+
+static void __init miscdev_test_static_basic(struct kunit *test)
+{
+ struct miscdevice misc_test = {
+ .name = "misc_test",
+ .fops = &miscdev_test_fops,
+ };
+ int ret;
+ const struct miscdev_test_case *params = test->param_value;
+
+ misc_test.minor = params->minor;
+
+ ret = misc_register(&misc_test);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+ KUNIT_EXPECT_EQ(test, misc_test.minor, params->minor);
+
+ if (ret == 0) {
+ miscdev_test_can_open(test, &misc_test);
+ misc_deregister(&misc_test);
+ }
+}
+
+static void __init miscdev_test_dynamic_basic(struct kunit *test)
+{
+ struct miscdevice misc_test = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "misc_test",
+ .fops = &miscdev_test_fops,
+ };
+ int ret;
+
+ ret = misc_register(&misc_test);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+ KUNIT_EXPECT_TRUE(test, is_valid_dynamic_minor(misc_test.minor));
+
+ if (ret == 0) {
+ miscdev_test_can_open(test, &misc_test);
+ misc_deregister(&misc_test);
+ }
+}
+
+static void miscdev_test_twice(struct kunit *test)
+{
+ struct miscdevice misc_test = {
+ .name = "misc_test",
+ .fops = &miscdev_test_fops,
+ };
+ int ret;
+ const struct miscdev_test_case *params = test->param_value;
+
+ misc_test.minor = params->minor;
+
+ ret = misc_register(&misc_test);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+ KUNIT_EXPECT_EQ(test, misc_test.minor, params->minor);
+ if (ret == 0)
+ misc_deregister(&misc_test);
+
+ ret = misc_register(&misc_test);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+ KUNIT_EXPECT_EQ(test, misc_test.minor, params->minor);
+ if (ret == 0)
+ misc_deregister(&misc_test);
+}
+
+static void miscdev_test_duplicate_minor(struct kunit *test)
+{
+ struct miscdevice misc1 = {
+ .name = "misc1",
+ .fops = &miscdev_test_fops,
+ };
+ struct miscdevice misc2 = {
+ .name = "misc2",
+ .fops = &miscdev_test_fops,
+ };
+ int ret;
+ const struct miscdev_test_case *params = test->param_value;
+
+ misc1.minor = params->minor;
+ misc2.minor = params->minor;
+
+ ret = misc_register(&misc1);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+ KUNIT_EXPECT_EQ(test, misc1.minor, params->minor);
+
+ ret = misc_register(&misc2);
+ KUNIT_EXPECT_EQ(test, ret, -EBUSY);
+ if (ret == 0)
+ misc_deregister(&misc2);
+
+ misc_deregister(&misc1);
+}
+
+static void miscdev_test_duplicate_name(struct kunit *test)
+{
+ struct miscdevice misc1 = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "misc1",
+ .fops = &miscdev_test_fops,
+ };
+ struct miscdevice misc2 = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "misc1",
+ .fops = &miscdev_test_fops,
+ };
+ int ret;
+
+ ret = misc_register(&misc1);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+ KUNIT_EXPECT_TRUE(test, is_valid_dynamic_minor(misc1.minor));
+
+ ret = misc_register(&misc2);
+ KUNIT_EXPECT_EQ(test, ret, -EEXIST);
+ if (ret == 0)
+ misc_deregister(&misc2);
+
+ misc_deregister(&misc1);
+}
+
+/*
+ * Test that after a duplicate name failure, the reserved minor number is
+ * freed to be allocated next.
+ */
+static void miscdev_test_duplicate_name_leak(struct kunit *test)
+{
+ struct miscdevice misc1 = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "misc1",
+ .fops = &miscdev_test_fops,
+ };
+ struct miscdevice misc2 = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "misc1",
+ .fops = &miscdev_test_fops,
+ };
+ struct miscdevice misc3 = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "misc3",
+ .fops = &miscdev_test_fops,
+ };
+ int ret;
+ int dyn_minor;
+
+ ret = misc_register(&misc1);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+ KUNIT_EXPECT_TRUE(test, is_valid_dynamic_minor(misc1.minor));
+
+ /*
+ * Find out what is the next minor number available.
+ */
+ ret = misc_register(&misc3);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+ KUNIT_EXPECT_TRUE(test, is_valid_dynamic_minor(misc3.minor));
+ dyn_minor = misc3.minor;
+ misc_deregister(&misc3);
+ misc3.minor = MISC_DYNAMIC_MINOR;
+
+ ret = misc_register(&misc2);
+ KUNIT_EXPECT_EQ(test, ret, -EEXIST);
+ if (ret == 0)
+ misc_deregister(&misc2);
+
+ /*
+ * Now check that we can still get the same minor we found before.
+ */
+ ret = misc_register(&misc3);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+ KUNIT_EXPECT_TRUE(test, is_valid_dynamic_minor(misc3.minor));
+ KUNIT_EXPECT_EQ(test, misc3.minor, dyn_minor);
+ misc_deregister(&misc3);
+
+ misc_deregister(&misc1);
+}
+
+/*
+ * Try to register a static minor with a duplicate name. That might not
+ * deallocate the minor, preventing it from being used again.
+ */
+static void miscdev_test_duplicate_error(struct kunit *test)
+{
+ struct miscdevice miscdyn = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "name1",
+ .fops = &miscdev_test_fops,
+ };
+ struct miscdevice miscstat = {
+ .name = "name1",
+ .fops = &miscdev_test_fops,
+ };
+ struct miscdevice miscnew = {
+ .name = "name2",
+ .fops = &miscdev_test_fops,
+ };
+ int ret;
+ const struct miscdev_test_case *params = test->param_value;
+
+ miscstat.minor = params->minor;
+ miscnew.minor = params->minor;
+
+ ret = misc_register(&miscdyn);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+ KUNIT_EXPECT_TRUE(test, is_valid_dynamic_minor(miscdyn.minor));
+
+ ret = misc_register(&miscstat);
+ KUNIT_EXPECT_EQ(test, ret, -EEXIST);
+ if (ret == 0)
+ misc_deregister(&miscstat);
+
+ ret = misc_register(&miscnew);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+ KUNIT_EXPECT_EQ(test, miscnew.minor, params->minor);
+ if (ret == 0)
+ misc_deregister(&miscnew);
+
+ misc_deregister(&miscdyn);
+}
+
+static void __init miscdev_test_dynamic_only_range(struct kunit *test)
+{
+ int ret;
+ struct miscdevice *miscdev;
+ const int dynamic_minors = 256;
+ int i;
+
+ miscdev = kunit_kmalloc_array(test, dynamic_minors,
+ sizeof(struct miscdevice),
+ GFP_KERNEL | __GFP_ZERO);
+
+ for (i = 0; i < dynamic_minors; i++) {
+ miscdev[i].minor = MISC_DYNAMIC_MINOR;
+ miscdev[i].name = kasprintf(GFP_KERNEL, "misc_test%d", i);
+ miscdev[i].fops = &miscdev_test_fops;
+ ret = misc_register(&miscdev[i]);
+ if (ret != 0)
+ break;
+ /*
+ * This is the bug we are looking for!
+ * We asked for a dynamic minor and got a minor in the static range space.
+ */
+ if (miscdev[i].minor >= 0 && miscdev[i].minor <= 15) {
+ KUNIT_FAIL(test, "misc_register allocated minor %d\n", miscdev[i].minor);
+ i++;
+ break;
+ }
+ KUNIT_EXPECT_TRUE(test, is_valid_dynamic_minor(miscdev[i].minor));
+ }
+
+ for (i--; i >= 0; i--) {
+ miscdev_test_can_open(test, &miscdev[i]);
+ misc_deregister(&miscdev[i]);
+ kfree_const(miscdev[i].name);
+ }
+
+ KUNIT_EXPECT_EQ(test, ret, 0);
+}
+
+static void __init miscdev_test_collision(struct kunit *test)
+{
+ int ret;
+ struct miscdevice *miscdev;
+ struct miscdevice miscstat = {
+ .name = "miscstat",
+ .fops = &miscdev_test_fops,
+ };
+ const int dynamic_minors = 256;
+ int i;
+
+ miscdev = kunit_kmalloc_array(test, dynamic_minors,
+ sizeof(struct miscdevice),
+ GFP_KERNEL | __GFP_ZERO);
+
+ miscstat.minor = miscdev_test_ranges[0].minor;
+ ret = misc_register(&miscstat);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+ KUNIT_EXPECT_EQ(test, miscstat.minor, miscdev_test_ranges[0].minor);
+
+ for (i = 0; i < dynamic_minors; i++) {
+ miscdev[i].minor = MISC_DYNAMIC_MINOR;
+ miscdev[i].name = kasprintf(GFP_KERNEL, "misc_test%d", i);
+ miscdev[i].fops = &miscdev_test_fops;
+ ret = misc_register(&miscdev[i]);
+ if (ret != 0)
+ break;
+ KUNIT_EXPECT_TRUE(test, is_valid_dynamic_minor(miscdev[i].minor));
+ }
+
+ for (i--; i >= 0; i--) {
+ miscdev_test_can_open(test, &miscdev[i]);
+ misc_deregister(&miscdev[i]);
+ kfree_const(miscdev[i].name);
+ }
+
+ misc_deregister(&miscstat);
+
+ KUNIT_EXPECT_EQ(test, ret, 0);
+}
+
+static void __init miscdev_test_collision_reverse(struct kunit *test)
+{
+ int ret;
+ struct miscdevice *miscdev;
+ struct miscdevice miscstat = {
+ .name = "miscstat",
+ .fops = &miscdev_test_fops,
+ };
+ const int dynamic_minors = 256;
+ int i;
+
+ miscdev = kunit_kmalloc_array(test, dynamic_minors,
+ sizeof(struct miscdevice),
+ GFP_KERNEL | __GFP_ZERO);
+
+ for (i = 0; i < dynamic_minors; i++) {
+ miscdev[i].minor = MISC_DYNAMIC_MINOR;
+ miscdev[i].name = kasprintf(GFP_KERNEL, "misc_test%d", i);
+ miscdev[i].fops = &miscdev_test_fops;
+ ret = misc_register(&miscdev[i]);
+ if (ret != 0)
+ break;
+ KUNIT_EXPECT_TRUE(test, is_valid_dynamic_minor(miscdev[i].minor));
+ }
+
+ KUNIT_EXPECT_EQ(test, ret, 0);
+
+ miscstat.minor = miscdev_test_ranges[0].minor;
+ ret = misc_register(&miscstat);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+ KUNIT_EXPECT_EQ(test, miscstat.minor, miscdev_test_ranges[0].minor);
+ if (ret == 0)
+ misc_deregister(&miscstat);
+
+ for (i--; i >= 0; i--) {
+ miscdev_test_can_open(test, &miscdev[i]);
+ misc_deregister(&miscdev[i]);
+ kfree_const(miscdev[i].name);
+ }
+}
+
+static void __init miscdev_test_conflict(struct kunit *test)
+{
+ int ret;
+ struct miscdevice miscdyn = {
+ .name = "miscdyn",
+ .minor = MISC_DYNAMIC_MINOR,
+ .fops = &miscdev_test_fops,
+ };
+ struct miscdevice miscstat = {
+ .name = "miscstat",
+ .fops = &miscdev_test_fops,
+ };
+
+ ret = misc_register(&miscdyn);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+ KUNIT_EXPECT_TRUE(test, is_valid_dynamic_minor(miscdyn.minor));
+
+ /*
+ * Try to register a static minor with the same minor as the
+ * dynamic one.
+ */
+ miscstat.minor = miscdyn.minor;
+ ret = misc_register(&miscstat);
+ KUNIT_EXPECT_EQ(test, ret, -EBUSY);
+ if (ret == 0)
+ misc_deregister(&miscstat);
+
+ miscdev_test_can_open(test, &miscdyn);
+
+ misc_deregister(&miscdyn);
+}
+
+static void __init miscdev_test_conflict_reverse(struct kunit *test)
+{
+ int ret;
+ struct miscdevice miscdyn = {
+ .name = "miscdyn",
+ .minor = MISC_DYNAMIC_MINOR,
+ .fops = &miscdev_test_fops,
+ };
+ struct miscdevice miscstat = {
+ .name = "miscstat",
+ .fops = &miscdev_test_fops,
+ };
+
+ /*
+ * Find the first available dynamic minor to use it as a static
+ * minor later on.
+ */
+ ret = misc_register(&miscdyn);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+ KUNIT_EXPECT_TRUE(test, is_valid_dynamic_minor(miscdyn.minor));
+ miscstat.minor = miscdyn.minor;
+ misc_deregister(&miscdyn);
+
+ ret = misc_register(&miscstat);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+ KUNIT_EXPECT_EQ(test, miscstat.minor, miscdyn.minor);
+
+ /*
+ * Try to register a dynamic minor after registering a static minor
+ * within the dynamic range. It should work but get a different
+ * minor.
+ */
+ miscdyn.minor = MISC_DYNAMIC_MINOR;
+ ret = misc_register(&miscdyn);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+ KUNIT_EXPECT_NE(test, miscdyn.minor, miscstat.minor);
+ KUNIT_EXPECT_TRUE(test, is_valid_dynamic_minor(miscdyn.minor));
+ if (ret == 0)
+ misc_deregister(&miscdyn);
+
+ miscdev_test_can_open(test, &miscstat);
+
+ misc_deregister(&miscstat);
+}
+
static struct kunit_case test_cases[] = {
KUNIT_CASE(kunit_dynamic_minor),
KUNIT_CASE(kunit_static_minor),
KUNIT_CASE(kunit_misc_dynamic_minor),
+ KUNIT_CASE_PARAM(miscdev_test_twice, miscdev_gen_params),
+ KUNIT_CASE_PARAM(miscdev_test_duplicate_minor, miscdev_gen_params),
+ KUNIT_CASE(miscdev_test_duplicate_name),
+ KUNIT_CASE(miscdev_test_duplicate_name_leak),
+ KUNIT_CASE_PARAM(miscdev_test_duplicate_error, miscdev_gen_params),
{}
};
static struct kunit_suite test_suite = {
- .name = "misc_minor_test",
+ .name = "miscdev",
+ .suite_init = miscdev_find_minors,
.test_cases = test_cases,
};
kunit_test_suite(test_suite);
+static struct kunit_case __refdata test_init_cases[] = {
+ KUNIT_CASE_PARAM(miscdev_test_static_basic, miscdev_gen_params),
+ KUNIT_CASE(miscdev_test_dynamic_basic),
+ KUNIT_CASE(miscdev_test_dynamic_only_range),
+ KUNIT_CASE(miscdev_test_collision),
+ KUNIT_CASE(miscdev_test_collision_reverse),
+ KUNIT_CASE(miscdev_test_conflict),
+ KUNIT_CASE(miscdev_test_conflict_reverse),
+ {}
+};
+
+static struct kunit_suite test_init_suite = {
+ .name = "miscdev_init",
+ .suite_init = miscdev_find_minors,
+ .test_cases = test_init_cases,
+};
+kunit_test_init_section_suite(test_init_suite);
+
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Vimal Agrawal");
-MODULE_DESCRIPTION("misc minor testing");
+MODULE_AUTHOR("Thadeu Lima de Souza Cascardo <cascardo@igalia.com>");
+MODULE_DESCRIPTION("Test module for misc character devices");
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index ebe33181b6e6e0fb4243b400e9187881707efe23..03c0eef3753760eca21a5fb0d0a457f6c2b76b5d 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -2506,8 +2506,8 @@ config TEST_IDA
tristate "Perform selftest on IDA functions"
config TEST_MISC_MINOR
- tristate "miscdevice KUnit test" if !KUNIT_ALL_TESTS
- depends on KUNIT
+ bool "miscdevice KUnit test" if !KUNIT_ALL_TESTS
+ depends on KUNIT=y
default KUNIT_ALL_TESTS
help
Kunit test for miscdevice API, specially its behavior in respect to
---
base-commit: 19272b37aa4f83ca52bdf9c16d5d81bdd1354494
change-id: 20250307-misc-dynrange-d54c92a5e319
Best regards,
--
Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v5] char: misc: add test cases
2025-06-12 17:32 [PATCH v5] char: misc: add test cases Thadeu Lima de Souza Cascardo
@ 2025-07-09 13:14 ` kernel test robot
2025-07-09 13:23 ` Thadeu Lima de Souza Cascardo
2025-07-30 7:08 ` Geert Uytterhoeven
1 sibling, 1 reply; 6+ messages in thread
From: kernel test robot @ 2025-07-09 13:14 UTC (permalink / raw)
To: Thadeu Lima de Souza Cascardo
Cc: oe-lkp, lkp, linux-kernel, Arnd Bergmann, Greg Kroah-Hartman,
Andrew Morton, Dirk VanDerMerwe, Vimal Agrawal, kernel-dev,
Thadeu Lima de Souza Cascardo, oliver.sang
Hello,
kernel test robot noticed "sysfs:cannot_create_duplicate_filename" on:
commit: 127b049d35f10765f429aa2a97aa649ea9ac0b2f ("[PATCH v5] char: misc: add test cases")
url: https://github.com/intel-lab-lkp/linux/commits/Thadeu-Lima-de-Souza-Cascardo/char-misc-add-test-cases/20250613-013440
patch link: https://lore.kernel.org/all/20250612-misc-dynrange-v5-1-6f35048f7273@igalia.com/
patch subject: [PATCH v5] char: misc: add test cases
in testcase: kunit
version:
with following parameters:
group: group-00
config: x86_64-rhel-9.4-kunit
compiler: gcc-12
test machine: 8 threads 1 sockets Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz (Haswell) with 16G memory
(please refer to attached dmesg/kmsg for entire log/backtrace)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <oliver.sang@intel.com>
| Closes: https://lore.kernel.org/oe-lkp/202507091056.5d48c1a2-lkp@intel.com
[ 112.908177][ T1] ok 2 upper static range, bottom
[ 112.914070][ T1] ok 3 lower static range, bottom
[ 112.920216][ T1] ok 4 upper static range, top
[ 112.925861][ T1] # miscdev_test_duplicate_minor: pass:4 fail:0 skip:0 total:4
[ 112.931240][ T1] ok 5 miscdev_test_duplicate_minor
[ 112.939321][ T2928] sysfs: cannot create duplicate filename '/devices/virtual/misc/misc1'
[ 112.953103][ T2928] CPU: 0 UID: 0 PID: 2928 Comm: kunit_try_catch Tainted: G S N 6.16.0-rc1-00001-g127b049d35f1 #1 PREEMPT(voluntary)
[ 112.953110][ T2928] Tainted: [S]=CPU_OUT_OF_SPEC, [N]=TEST
[ 112.953111][ T2928] Hardware name: Dell Inc. OptiPlex 9020/0DNKMN, BIOS A05 12/05/2013
[ 112.953113][ T2928] Call Trace:
[ 112.953115][ T2928] <TASK>
[ 112.953117][ T2928] dump_stack_lvl (kbuild/src/consumer/lib/dump_stack.c:123 (discriminator 1))
[ 112.953124][ T2928] sysfs_warn_dup (kbuild/src/consumer/fs/sysfs/dir.c:32 (discriminator 1))
[ 112.953129][ T2928] sysfs_create_dir_ns (kbuild/src/consumer/fs/sysfs/dir.c:63)
[ 112.953133][ T2928] ? __pfx_sysfs_create_dir_ns (kbuild/src/consumer/fs/sysfs/dir.c:41)
The kernel config and materials to reproduce are available at:
https://download.01.org/0day-ci/archive/20250709/202507091056.5d48c1a2-lkp@intel.com
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v5] char: misc: add test cases
2025-07-09 13:14 ` kernel test robot
@ 2025-07-09 13:23 ` Thadeu Lima de Souza Cascardo
2025-07-11 6:46 ` Oliver Sang
0 siblings, 1 reply; 6+ messages in thread
From: Thadeu Lima de Souza Cascardo @ 2025-07-09 13:23 UTC (permalink / raw)
To: kernel test robot
Cc: oe-lkp, lkp, linux-kernel, Arnd Bergmann, Greg Kroah-Hartman,
Andrew Morton, Dirk VanDerMerwe, Vimal Agrawal, kernel-dev
On Wed, Jul 09, 2025 at 09:14:04PM +0800, kernel test robot wrote:
> Hello,
>
> kernel test robot noticed "sysfs:cannot_create_duplicate_filename" on:
>
> commit: 127b049d35f10765f429aa2a97aa649ea9ac0b2f ("[PATCH v5] char: misc: add test cases")
> url: https://github.com/intel-lab-lkp/linux/commits/Thadeu-Lima-de-Souza-Cascardo/char-misc-add-test-cases/20250613-013440
> patch link: https://lore.kernel.org/all/20250612-misc-dynrange-v5-1-6f35048f7273@igalia.com/
> patch subject: [PATCH v5] char: misc: add test cases
>
> in testcase: kunit
> version:
> with following parameters:
>
> group: group-00
>
>
>
> config: x86_64-rhel-9.4-kunit
> compiler: gcc-12
> test machine: 8 threads 1 sockets Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz (Haswell) with 16G memory
>
> (please refer to attached dmesg/kmsg for entire log/backtrace)
>
>
>
> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <oliver.sang@intel.com>
> | Closes: https://lore.kernel.org/oe-lkp/202507091056.5d48c1a2-lkp@intel.com
>
>
> [ 112.908177][ T1] ok 2 upper static range, bottom
> [ 112.914070][ T1] ok 3 lower static range, bottom
> [ 112.920216][ T1] ok 4 upper static range, top
> [ 112.925861][ T1] # miscdev_test_duplicate_minor: pass:4 fail:0 skip:0 total:4
> [ 112.931240][ T1] ok 5 miscdev_test_duplicate_minor
> [ 112.939321][ T2928] sysfs: cannot create duplicate filename '/devices/virtual/misc/misc1'
> [ 112.953103][ T2928] CPU: 0 UID: 0 PID: 2928 Comm: kunit_try_catch Tainted: G S N 6.16.0-rc1-00001-g127b049d35f1 #1 PREEMPT(voluntary)
> [ 112.953110][ T2928] Tainted: [S]=CPU_OUT_OF_SPEC, [N]=TEST
> [ 112.953111][ T2928] Hardware name: Dell Inc. OptiPlex 9020/0DNKMN, BIOS A05 12/05/2013
> [ 112.953113][ T2928] Call Trace:
> [ 112.953115][ T2928] <TASK>
> [ 112.953117][ T2928] dump_stack_lvl (kbuild/src/consumer/lib/dump_stack.c:123 (discriminator 1))
> [ 112.953124][ T2928] sysfs_warn_dup (kbuild/src/consumer/fs/sysfs/dir.c:32 (discriminator 1))
> [ 112.953129][ T2928] sysfs_create_dir_ns (kbuild/src/consumer/fs/sysfs/dir.c:63)
> [ 112.953133][ T2928] ? __pfx_sysfs_create_dir_ns (kbuild/src/consumer/fs/sysfs/dir.c:41)
>
>
> The kernel config and materials to reproduce are available at:
> https://download.01.org/0day-ci/archive/20250709/202507091056.5d48c1a2-lkp@intel.com
>
>
> --
> 0-DAY CI Kernel Test Service
> https://github.com/intel/lkp-tests/wiki
This failure is intentional, it is part of the test. How can we make the
robot ignore it in this specific instance?
Regards.
Cascardo.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v5] char: misc: add test cases
2025-07-09 13:23 ` Thadeu Lima de Souza Cascardo
@ 2025-07-11 6:46 ` Oliver Sang
0 siblings, 0 replies; 6+ messages in thread
From: Oliver Sang @ 2025-07-11 6:46 UTC (permalink / raw)
To: Thadeu Lima de Souza Cascardo
Cc: oe-lkp, lkp, linux-kernel, Arnd Bergmann, Greg Kroah-Hartman,
Andrew Morton, Dirk VanDerMerwe, Vimal Agrawal, kernel-dev,
oliver.sang
hi, Cascardo,
On Wed, Jul 09, 2025 at 10:23:38AM -0300, Thadeu Lima de Souza Cascardo wrote:
> On Wed, Jul 09, 2025 at 09:14:04PM +0800, kernel test robot wrote:
> > Hello,
> >
> > kernel test robot noticed "sysfs:cannot_create_duplicate_filename" on:
> >
> > commit: 127b049d35f10765f429aa2a97aa649ea9ac0b2f ("[PATCH v5] char: misc: add test cases")
> > url: https://github.com/intel-lab-lkp/linux/commits/Thadeu-Lima-de-Souza-Cascardo/char-misc-add-test-cases/20250613-013440
> > patch link: https://lore.kernel.org/all/20250612-misc-dynrange-v5-1-6f35048f7273@igalia.com/
> > patch subject: [PATCH v5] char: misc: add test cases
> >
> > in testcase: kunit
> > version:
> > with following parameters:
> >
> > group: group-00
> >
> >
> >
> > config: x86_64-rhel-9.4-kunit
> > compiler: gcc-12
> > test machine: 8 threads 1 sockets Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz (Haswell) with 16G memory
> >
> > (please refer to attached dmesg/kmsg for entire log/backtrace)
> >
> >
> >
> > If you fix the issue in a separate patch/commit (i.e. not just a new version of
> > the same patch/commit), kindly add following tags
> > | Reported-by: kernel test robot <oliver.sang@intel.com>
> > | Closes: https://lore.kernel.org/oe-lkp/202507091056.5d48c1a2-lkp@intel.com
> >
> >
> > [ 112.908177][ T1] ok 2 upper static range, bottom
> > [ 112.914070][ T1] ok 3 lower static range, bottom
> > [ 112.920216][ T1] ok 4 upper static range, top
> > [ 112.925861][ T1] # miscdev_test_duplicate_minor: pass:4 fail:0 skip:0 total:4
> > [ 112.931240][ T1] ok 5 miscdev_test_duplicate_minor
> > [ 112.939321][ T2928] sysfs: cannot create duplicate filename '/devices/virtual/misc/misc1'
> > [ 112.953103][ T2928] CPU: 0 UID: 0 PID: 2928 Comm: kunit_try_catch Tainted: G S N 6.16.0-rc1-00001-g127b049d35f1 #1 PREEMPT(voluntary)
> > [ 112.953110][ T2928] Tainted: [S]=CPU_OUT_OF_SPEC, [N]=TEST
> > [ 112.953111][ T2928] Hardware name: Dell Inc. OptiPlex 9020/0DNKMN, BIOS A05 12/05/2013
> > [ 112.953113][ T2928] Call Trace:
> > [ 112.953115][ T2928] <TASK>
> > [ 112.953117][ T2928] dump_stack_lvl (kbuild/src/consumer/lib/dump_stack.c:123 (discriminator 1))
> > [ 112.953124][ T2928] sysfs_warn_dup (kbuild/src/consumer/fs/sysfs/dir.c:32 (discriminator 1))
> > [ 112.953129][ T2928] sysfs_create_dir_ns (kbuild/src/consumer/fs/sysfs/dir.c:63)
> > [ 112.953133][ T2928] ? __pfx_sysfs_create_dir_ns (kbuild/src/consumer/fs/sysfs/dir.c:41)
> >
> >
> > The kernel config and materials to reproduce are available at:
> > https://download.01.org/0day-ci/archive/20250709/202507091056.5d48c1a2-lkp@intel.com
> >
> >
> > --
> > 0-DAY CI Kernel Test Service
> > https://github.com/intel/lkp-tests/wiki
>
> This failure is intentional, it is part of the test. How can we make the
> robot ignore it in this specific instance?
got it, we will avoid the report for this specific instance in the future.
>
> Regards.
> Cascardo.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v5] char: misc: add test cases
2025-06-12 17:32 [PATCH v5] char: misc: add test cases Thadeu Lima de Souza Cascardo
2025-07-09 13:14 ` kernel test robot
@ 2025-07-30 7:08 ` Geert Uytterhoeven
2025-07-30 11:05 ` Thadeu Lima de Souza Cascardo
1 sibling, 1 reply; 6+ messages in thread
From: Geert Uytterhoeven @ 2025-07-30 7:08 UTC (permalink / raw)
To: Thadeu Lima de Souza Cascardo
Cc: Arnd Bergmann, Greg Kroah-Hartman, Andrew Morton,
Dirk VanDerMerwe, Vimal Agrawal, linux-kernel, kernel-dev,
open list:KERNEL SELFTEST FRAMEWORK, KUnit Development
Hi Thadeu,,
On Sun, 15 Jun 2025 at 23:31, Thadeu Lima de Souza Cascardo
<cascardo@igalia.com> wrote:
>
> Add test cases for static and dynamic minor number allocation and
> deallocation.
>
> While at it, improve description and test suite name.
>
> Some of the cases include:
>
> - that static and dynamic allocation reserved the expected minors.
>
> - that registering duplicate minors or duplicate names will fail.
>
> - that failing to create a sysfs file (due to duplicate names) will
> deallocate the dynamic minor correctly.
>
> - that dynamic allocation does not allocate a minor number in the static
> range.
>
> - that there are no collisions when mixing dynamic and static allocations.
>
> - that opening devices with various minor device numbers work.
>
> - that registering a static number in the dynamic range won't conflict with
> a dynamic allocation.
>
> This last test verifies the bug fixed by commit 6d04d2b554b1 ("misc:
> misc_minor_alloc to use ida for all dynamic/misc dynamic minors") has not
> regressed.
>
> Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
Thanks for your patch, which is now commit 74d8361be3441dff ("char:
misc: add test cases") in linus/master stable/master
> Changes in v5:
> - Make miscdevice unit test built-in only
> - Make unit test require CONFIG_KUNIT=y
Why were these changes made? This means the test is no longer available
if KUNIT=m, and I can no longer just load the module when I want to
run the test.
> - Link to v4: https://lore.kernel.org/r/20250423-misc-dynrange-v4-0-133b5ae4ca18@igalia.com
> --- a/lib/Kconfig.debug
> +++ b/lib/Kconfig.debug
> @@ -2506,8 +2506,8 @@ config TEST_IDA
> tristate "Perform selftest on IDA functions"
>
> config TEST_MISC_MINOR
> - tristate "miscdevice KUnit test" if !KUNIT_ALL_TESTS
> - depends on KUNIT
> + bool "miscdevice KUnit test" if !KUNIT_ALL_TESTS
> + depends on KUNIT=y
> default KUNIT_ALL_TESTS
> help
> Kunit test for miscdevice API, specially its behavior in respect to
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v5] char: misc: add test cases
2025-07-30 7:08 ` Geert Uytterhoeven
@ 2025-07-30 11:05 ` Thadeu Lima de Souza Cascardo
0 siblings, 0 replies; 6+ messages in thread
From: Thadeu Lima de Souza Cascardo @ 2025-07-30 11:05 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Arnd Bergmann, Greg Kroah-Hartman, Andrew Morton,
Dirk VanDerMerwe, Vimal Agrawal, linux-kernel, kernel-dev,
open list:KERNEL SELFTEST FRAMEWORK, KUnit Development
On Wed, Jul 30, 2025 at 09:08:57AM +0200, Geert Uytterhoeven wrote:
> Hi Thadeu,,
>
> On Sun, 15 Jun 2025 at 23:31, Thadeu Lima de Souza Cascardo
> <cascardo@igalia.com> wrote:
> >
> > Add test cases for static and dynamic minor number allocation and
> > deallocation.
> >
> > While at it, improve description and test suite name.
> >
> > Some of the cases include:
> >
> > - that static and dynamic allocation reserved the expected minors.
> >
> > - that registering duplicate minors or duplicate names will fail.
> >
> > - that failing to create a sysfs file (due to duplicate names) will
> > deallocate the dynamic minor correctly.
> >
> > - that dynamic allocation does not allocate a minor number in the static
> > range.
> >
> > - that there are no collisions when mixing dynamic and static allocations.
> >
> > - that opening devices with various minor device numbers work.
> >
> > - that registering a static number in the dynamic range won't conflict with
> > a dynamic allocation.
> >
> > This last test verifies the bug fixed by commit 6d04d2b554b1 ("misc:
> > misc_minor_alloc to use ida for all dynamic/misc dynamic minors") has not
> > regressed.
> >
> > Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
>
> Thanks for your patch, which is now commit 74d8361be3441dff ("char:
> misc: add test cases") in linus/master stable/master
>
> > Changes in v5:
> > - Make miscdevice unit test built-in only
> > - Make unit test require CONFIG_KUNIT=y
>
> Why were these changes made? This means the test is no longer available
> if KUNIT=m, and I can no longer just load the module when I want to
> run the test.
>
These were made because a bug was found that devices with minor > 255 could
not be opened. So I added a test for that, which used __init functions, so
the test now had to be built-in. The alternative is to make these functions
not __init anymore and export them. Those functions are init_mknod and
init_unlink.
I will see if I can cook an RFC later today.
Cascardo.
> > - Link to v4: https://lore.kernel.org/r/20250423-misc-dynrange-v4-0-133b5ae4ca18@igalia.com
>
> > --- a/lib/Kconfig.debug
> > +++ b/lib/Kconfig.debug
> > @@ -2506,8 +2506,8 @@ config TEST_IDA
> > tristate "Perform selftest on IDA functions"
> >
> > config TEST_MISC_MINOR
> > - tristate "miscdevice KUnit test" if !KUNIT_ALL_TESTS
> > - depends on KUNIT
> > + bool "miscdevice KUnit test" if !KUNIT_ALL_TESTS
> > + depends on KUNIT=y
> > default KUNIT_ALL_TESTS
> > help
> > Kunit test for miscdevice API, specially its behavior in respect to
>
> Gr{oetje,eeting}s,
>
> Geert
>
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
>
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
> -- Linus Torvalds
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2025-07-30 11:05 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-12 17:32 [PATCH v5] char: misc: add test cases Thadeu Lima de Souza Cascardo
2025-07-09 13:14 ` kernel test robot
2025-07-09 13:23 ` Thadeu Lima de Souza Cascardo
2025-07-11 6:46 ` Oliver Sang
2025-07-30 7:08 ` Geert Uytterhoeven
2025-07-30 11:05 ` Thadeu Lima de Souza Cascardo
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).