A few tests need to have a valid struct device. One such example is tests which want to be testing devm-managed interfaces.
Add kunit wrapper for root_device_[un]register(), which create a root device and also add a kunit managed clean-up routine for the device destruction upon test exit.
Special note: In some cases the device reference-count does not reach zero and devm-unwinding is not done if device is not sitting on a bus. The root_device_[un]register() are dealing with such devices and thus this interface may not be usable by all in its current form. More information can be found from: https://lore.kernel.org/dri-devel/20221117165311.vovrc7usy4efiytl@houat/
The use of root-devices in the kunit helpers is intended to be an intermediate solution to allow tests which do not require device to sit on a bus avoid directly abusing the root_device_[un]register() while proper kunit device solution is being worked on. Related discussion can be found from: https://lore.kernel.org/lkml/CABVgOSmx3A4Vwos2_8xO-XQrQAw5gvY0nc5zLpLmcJ7FtA...
Signed-off-by: Matti Vaittinen mazziesaccount@gmail.com
--- Change history: v5 => v6: - Kunit resource-managed root_device creation wrapper (new patch)
Please note: This patch uses root-devices (as was suggested) until there is a proper dummy device creation mechanism added in kunit. The root devices are embedded in kunit wrappers to simplify replacing the root-devices with proper solution when it is available.
David Gow has sent out an RFC[1] which should implement these helpers using not-yet-in-tree deferring API. This RFC aims to support kunit_device which should be _the right thing to do_. I added this implementation here because it may (or may not) take a while for the David's RFC to make it's way in-kernel. So, in order to not delay this series I added these helpers which use the existing kunit resource management for clean-up while the new deferring kunit API is not yet in place.
[1] https://lore.kernel.org/linux-kselftest/20230325043104.3761770-1-davidgow@go...
--- include/kunit/device.h | 18 ++++++++++++++++++ lib/kunit/Makefile | 3 ++- lib/kunit/device.c | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 include/kunit/device.h create mode 100644 lib/kunit/device.c
diff --git a/include/kunit/device.h b/include/kunit/device.h new file mode 100644 index 000000000000..f02740b7583b --- /dev/null +++ b/include/kunit/device.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __KUNIT_DEVICE_H__ +#define __KUNIT_DEVICE_H__ + +#include <kunit/test.h> + +struct device; + +/* Register a new device against a KUnit test. */ +struct device *kunit_device_register(struct kunit *test, const char *name); +/* + * Unregister a device created by kunit_device_register() early (i.e., + * before test cleanup). + */ +void kunit_device_unregister(struct kunit *test, struct device *dev); + +#endif diff --git a/lib/kunit/Makefile b/lib/kunit/Makefile index cb417f504996..64449549b990 100644 --- a/lib/kunit/Makefile +++ b/lib/kunit/Makefile @@ -6,7 +6,8 @@ kunit-objs += test.o \ string-stream.o \ assert.o \ try-catch.o \ - executor.o + executor.o \ + device.o
ifeq ($(CONFIG_KUNIT_DEBUGFS),y) kunit-objs += debugfs.o diff --git a/lib/kunit/device.c b/lib/kunit/device.c new file mode 100644 index 000000000000..425f6d62ebd7 --- /dev/null +++ b/lib/kunit/device.c @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <kunit/device.h> +#include <kunit/test.h> + +#include <linux/device.h> + +static void kunit_device_drop(struct kunit_resource *res) +{ + root_device_unregister(res->data); +} + +struct device *kunit_device_register(struct kunit *test, const char *name) +{ + struct device *dev; + + dev = root_device_register(name); + if (IS_ERR_OR_NULL(dev)) + return dev; + + return kunit_alloc_resource(test, NULL, kunit_device_drop, GFP_KERNEL, + dev); +} +EXPORT_SYMBOL_GPL(kunit_device_register); + +static bool kunit_device_match(struct kunit *test, struct kunit_resource *res, + void *match_data) +{ + return res->data == match_data; +} + +void kunit_device_unregister(struct kunit *test, struct device *dev) +{ + kunit_destroy_resource(test, kunit_device_match, dev); +} +EXPORT_SYMBOL_GPL(kunit_device_unregister);