Support ROHM BU27034 ALS sensor
Subsystems (10)
Matti Vaittinen
maintainerv5 cover Support ROHM BU27034 ALS sensor
Support ROHM BU27034 ALS sensor
This series adds support for ROHM BU27034 Ambient Light Sensor.
The BU27034 has configurable gain and measurement (integration) time settings. Both of these have inversely proportional relation to the sensor's intensity channel scale.
Many users only set the scale, which means that many drivers attempt to 'guess' the best gain+time combination to meet the scale. Usually this is the biggest integration time which allows setting the requested scale. Typically, increasing the integration time has better accuracy than increasing the gain, which often amplifies the noise as well as the real signal.
However, there may be cases where more responsive sensors are needed. So, in some cases the longest integration times may not be what the user prefers. The driver has no way of knowing this.
Hence, the approach taken by this series is to allow user to set both the scale and the integration time with following logic:
1. When scale is set, the existing integration time is tried to be maintained as a first priority.
1a) If the requested scale can't be met by current time, then also
other time + gain combinations are searched. If scale can be met by some other integration time, then the new time may be applied. If the time setting is common for all channels, then also other channels must be able to maintain their scale with this new time (by changing their gain). The new times are scanned in the order of preference (typically the longest times first).
1b) If the requested scale can be met using current time, then only
the gain for the channel is changed.
2. When the integration time change - scale is tried to be maintained. When integration time change is requested also gain for all impacted channels is adjusted so that the scale is not changed, or is chaned as little as possible. This is different from the RFCv1 where the request was rejected if suitable gain couldn't be found for some channel(s).
This logic is simple. When total gain (either caused by time or hw-gain) is doubled, the scale gets halved. Also, the supported times are given a 'multiplier' value which tells how much they increase the total gain.
However, when I wrote this logic in bu27034 driver, I made quite a few errors on the way - and driver got pretty big. As I am writing drivers for two other sensors (RGB C/IR + flicker BU27010 and RGB C/IR BU27008) with similar gain-time-scale logic I thought that adding common helpers for these computations might be wise. I hope this way all the bugs will be concentrated in one place and not in every individual driver ;)
Hence, this series also intriduces IIO gain-time-scale helpers (abbreviated as gts-helpers) + a couple of KUnit tests for the most hairy parts.
Speaking of which - testing the devm interfaces requires a 'dummy device'. There were neat helpers in DRM tests for creating and freeing such a device. This series moves those helpers to more generic location. What is worth noting is that there is something similar ongoing in the CCF territory:
https://lore.kernel.org/all/[email protected]/
These efforts should be somehow coordinated in order to avoid any avoid conflicts.
Finally, these added helpers do provide some value also for drivers which only:
a) allow gain change
or
b) allow changing both the time and gain while trying to maintain the scale.
For a) we provide the gain - selector (register value) table format + selector to gain look-ups, gain <-> scale conversions and the available scales helpers.
For latter case we also provide the time-tables, and actually all the APIs should be usable by setting the time multiplier to 1. (not testeted thoroughly though).
The patch 1/8 introduces the helpers for creating/dropping a test device for devm-tests. It can be applied alone.
The patches 2/8 (convert DRM tests to use new helper) depends on patch 1/8 but is othervice not part of this series. It can be applied to DRM tree after the dependency to 1/8 is handled.
The patch 5/8 (IIO GTS tests) also depends on the patch 1/8 (and also other patches in the series).
Rest of the series should be Ok to be applied with/without the patches 1/8, 2/8, 5/8 - although the 5/8 would be "nice to have" together with the rest of the series for the testability reasons.
Revision history:
v4 => v5: Mostly fixes to review comments from Andy and Jonathan.
- more accurate change-log in individual patches
- copy code from DRM test helper instead of moving it to simplify merging
- document all exported GTS helpers.
- inline a few GTS helpers
- use again Milli lux for the bu27034 with RAW IIO_LIGHT channel and scale
- Fix bug from added in v4 bu27034 time setting.
v3 => v4: (Still mostly fixes to review comments from Andy and Jonathan)
- more accurate change-log in individual patches
- dt-binding and maintainer patches unchanged.
- dropped unused helpers and converted ones currently used only internally to static.
- extracted "dummy device" creation helpers from DRM tests.
- added tests for devm APIs
- dropped scale for PROCESSED channel in BU27034 and converted mLux values to luxes
- dropped channel 2 GAIN setting which can't be done due to HW limitations.
v2 => v3: (Mostly fixes to review comments from Andy and Jonathan)
- dt-binding and maintainer patches unchanged.
- iio-gts-helper tests: Use namespaces
- iio-gts-helpers + bu27034 plenty of changes. See more comprehensive changelog in individual patches.
RFCv1 => v2:
dt-bindings:
- Fix binding file name and id by using comma instead of a hyphen to separate the vendor and part names.
gts-helpers:
- fix include guardian
- Improve kernel doc for iio_init_iio_gts.
- Add iio_gts_scale_to_total_gain
- Add iio_gts_total_gain_to_scale
- Fix review comments from Jonathan
- add documentation to few functions
- replace 0xffffffffffffffffLLU by U64_MAX
- some styling fixes
- drop unnecessary NULL checks
- order function arguments by in / out purpose
- drop GAIN_SCALE_ITIME_MS()
- Add helpers for available scales and times
- Rename to iio-gts-helpers
gts-tests:
- add tests for available scales/times helpers
- adapt to renamed iio-gts-helpers.h header
bu27034-driver:
- (really) protect read-only registers
- fix get and set gain
- buffered mode
- Protect the whole sequences including meas_en/meas_dis to avoid messing up the enable / disable order
- typofixes / doc improvements
- change dropped GAIN_SCALE_ITIME_MS() to GAIN_SCALE_ITIME_US()
- use more accurate scale for lux channel (milli lux)
- provide available scales / integration times (using helpers).
- adapt to renamed iio-gts-helpers.h file
- bu27034 - longer lines in Kconfig
- Drop bu27034_meas_en and bu27034_meas_dis wrappers.
- Change device-name from bu27034-als to bu27034
MAINTAINERS:
- Add iio-list
---
Matti Vaittinen (8):
drivers: kunit: Generic helpers for test device creation drm/tests: helpers: Use generic helpers
dt-bindings: iio: light: Support ROHM BU27034
iio: light: Add gain-time-scale helpers
iio: test: test gain-time-scale helpers
MAINTAINERS: Add IIO gain-time-scale helpers
iio: light: ROHM BU27034 Ambient Light Sensor
MAINTAINERS: Add ROHM BU27034
.../bindings/iio/light/rohm,bu27034.yaml | 46 + MAINTAINERS | 14 + drivers/base/test/Kconfig | 5 + drivers/base/test/Makefile | 2 + drivers/base/test/test_kunit_device.c | 83 + drivers/gpu/drm/Kconfig | 2 + .../gpu/drm/tests/drm_client_modeset_test.c | 5 +- drivers/gpu/drm/tests/drm_kunit_helpers.c | 69 - drivers/gpu/drm/tests/drm_managed_test.c | 5 +- drivers/gpu/drm/tests/drm_modes_test.c | 5 +- drivers/gpu/drm/tests/drm_probe_helper_test.c | 5 +- drivers/gpu/drm/vc4/Kconfig | 1 + drivers/gpu/drm/vc4/tests/vc4_mock.c | 3 +- .../gpu/drm/vc4/tests/vc4_test_pv_muxing.c | 9 +- drivers/iio/Kconfig | 3 + drivers/iio/Makefile | 1 + drivers/iio/industrialio-gts-helper.c | 1064 ++++++++++++ drivers/iio/light/Kconfig | 14 + drivers/iio/light/Makefile | 1 + drivers/iio/light/rohm-bu27034.c | 1482 +++++++++++++++++ drivers/iio/test/Kconfig | 14 + drivers/iio/test/Makefile | 1 + drivers/iio/test/iio-test-gts.c | 542 ++++++ include/drm/drm_kunit_helpers.h | 7 +- include/kunit/platform_device.h | 13 + include/linux/iio/iio-gts-helper.h | 206 +++ 26 files changed, 3515 insertions(+), 87 deletions(-) create mode 100644 Documentation/devicetree/bindings/iio/light/rohm,bu27034.yaml create mode 100644 drivers/base/test/test_kunit_device.c create mode 100644 drivers/iio/industrialio-gts-helper.c create mode 100644 drivers/iio/light/rohm-bu27034.c create mode 100644 drivers/iio/test/iio-test-gts.c create mode 100644 include/kunit/platform_device.h create mode 100644 include/linux/iio/iio-gts-helper.h
base-commit: eeac8ede17557680855031c6f305ece2378af326
Signature · 14 lines
2.39.2 -- Matti Vaittinen, Linux device drivers ROHM Semiconductors, Finland SWDC Kiviharjunlenkki 1E 90220 OULU FINLAND ~~~ "I don't think so," said Rene Descartes. Just then he vanished ~~~ Simon says - in Latin please. ~~~ "non cogito me" dixit Rene Descarte, deinde evanescavit ~~~ Thanks to Simon Glass for the translation =]
Matti Vaittinen
maintainerPATCH v5 1/8 drivers: kunit: Generic helpers for test device creation
The creation of a dummy device in order to test managed interfaces is a generally useful test feature. The drm test helpers drm_kunit_helper_alloc_device() and drm_kunit_helper_free_device() are doing exactly this. It makes no sense that each and every component which intends to be testing managed interfaces will create similar helpers so stole these for more generic use.
---
Changes:
v4 => v5:
- Add accidentally dropped header and email recipients
- do not rename + move helpers from DRM but add temporary dublicates to simplify merging. (This patch does not touch DRM and can be merged separately. DRM patch and IIO test patch still depend on this one).
Please note that there's something similar ongoing in the CCF:
https://lore.kernel.org/all/[email protected]/
I do like the simplicity of these DRM-originated helpers so I think they're worth. I do equally like the Stephen's idea of having the "dummy platform device" related helpers under drivers/base and the header being in include/kunit/platform_device.h which is similar to real platform device under include/linux/platform_device.h
--- drivers/base/test/Kconfig | 5 ++ drivers/base/test/Makefile | 2 + drivers/base/test/test_kunit_device.c | 83 +++++++++++++++++++++++++++ include/kunit/platform_device.h | 13 +++++ 4 files changed, 103 insertions(+) create mode 100644 drivers/base/test/test_kunit_device.c create mode 100644 include/kunit/platform_device.h
drivers/base/test/Kconfig +5 -0
@@ -1,4 +1,9 @@ # SPDX-License-Identifier: GPL-2.0 + +config TEST_KUNIT_DEVICE_HELPERS + depends on KUNIT + tristate + config TEST_ASYNC_DRIVER_PROBE tristate "Build kernel module to test asynchronous driver probing" depends on m
drivers/base/test/Makefile +2 -0
@@ -1,5 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_TEST_ASYNC_DRIVER_PROBE) += test_async_driver_probe.o +obj-$(CONFIG_TEST_KUNIT_DEVICE_HELPERS) += test_kunit_device.o + obj-$(CONFIG_DRIVER_PE_KUNIT_TEST) += property-entry-test.o CFLAGS_property-entry-test.o += $(DISABLE_STRUCTLEAK_PLUGIN)
drivers/base/test/test_kunit_device.c new file +83 -0
83 lines not on this page · raw message
include/kunit/platform_device.h new file +13 -0
@@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __KUNIT_PLATFORM_DEVICE__ +#define __KUNIT_PLATFORM_DEVICE__ + +#include <kunit/test.h> + +struct device ; + +struct device *test_kunit_helper_alloc_device (struct kunit *test); +void test_kunit_helper_free_device (struct kunit *test,struct device *dev); + +#endif
Signature · 14 lines
2.39.2 -- Matti Vaittinen, Linux device drivers ROHM Semiconductors, Finland SWDC Kiviharjunlenkki 1E 90220 OULU FINLAND ~~~ "I don't think so," said Rene Descartes. Just then he vanished ~~~ Simon says - in Latin please. ~~~ "non cogito me" dixit Rene Descarte, deinde evanescavit ~~~ Thanks to Simon Glass for the translation =]
Greg Kroah-Hartman
maintainerRe: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
Quoted 4 lines · Matti Vaittinen
include/kunit/platform_device.h new file +1
-0@@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */
include/kunit/platform_device.h line 11
Quoted 10 lines
include/kunit/platform_device.h new file +10
-0+ +#ifndef __KUNIT_PLATFORM_DEVICE__ +#define __KUNIT_PLATFORM_DEVICE__ + +#include <kunit/test.h> + +struct device ; + +struct device *test_kunit_helper_alloc_device (struct kunit *test); +void test_kunit_helper_free_device (struct kunit *test,struct device *dev);
Why are you calling this a "platform_device" when it isn't a platform device at all?
Why not just say "device.h" here?
thanks,
greg k-h
Greg Kroah-Hartman
maintainerRe: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
In reply to Matti VaittinenQuoted 8 lines · Matti Vaittinen
drivers/base/test/test_kunit_device.c new file +5
-0@@ -0,0 +1,83 @@ +// SPDX-License-Identifier: GPL-2.0 +/* +* These helpers have been extracted from drm test code at +* drm_kunit_helpers.c which was authored by +* Maxime Ripard <[email protected]>
drivers/base/test/test_kunit_device.c line 15
Quoted 10 lines
drivers/base/test/test_kunit_device.c new file +10
-0+*/ + +#include <linux/device.h> +#include <linux/platform_device.h> + +#include <kunit/platform_device.h> + +#define KUNIT_DEVICE_NAME "test-kunit-mock-device" + +static int fake_probe (struct platform_device *pdev)
Please do not abuse platform devices and drivers for things that are not actually platform devices and drivers.
Quoted 6 lines
drivers/base/test/test_kunit_device.c new file +6
-0+{ +return 0 ; +} + +static int fake_remove (struct platform_device *pdev) +{
drivers/base/test/test_kunit_device.c line 31
Quoted 10 lines
drivers/base/test/test_kunit_device.c new file +10
-0+return 0 ; +} + +static struct platform_driver fake_platform_driver = { + .probe = fake_probe, + .remove = fake_remove, + .driver = { + .name =KUNIT_DEVICE_NAME , + }, +};
Why do you need this fake platform driver at all?
Why not just use a virtual device?
drivers/base/test/test_kunit_device.c line 40
Quoted 9 lines
drivers/base/test/test_kunit_device.c new file +9
-0+ +/** +* test_kunit_helper_alloc_device - Allocate a mock device for a KUnit test +* @test: The test context object +* +* This allocates a fake struct &device to create a mock for a KUnit +* test. The device will also be bound to a fake driver. It will thus be +* able to leverage the usual infrastructure and most notably the +* device-managed resources just like a "real" device.
What specific "usual infrastructure" are you wanting to access here?
And again, if you want a fake device, make a virtual one, by just calling device_create().
Or are you wanting to do "more" with that device pointer than device_create() can give you?
Again, please do not abuse the platform device infrastructure for things it was never ment to do (i.e. create fake devices that are not really a platform device.)
thanks,
greg k-h
Matti Vaittinen
maintainerRe: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
Hi Greg,
Thanks for looking at this.
Quoted 42 lines · Greg Kroah-Hartman
Quoted 8 lines · Matti Vaittinen
drivers/base/test/test_kunit_device.c new file +5
-0@@ -0,0 +1,83 @@ +// SPDX-License-Identifier: GPL-2.0 +/* +* These helpers have been extracted from drm test code at +* drm_kunit_helpers.c which was authored by +* Maxime Ripard <[email protected]> drivers/base/test/test_kunit_device.c line 15
Quoted 10 lines
drivers/base/test/test_kunit_device.c new file +10
-0+*/ + +#include <linux/device.h> +#include <linux/platform_device.h> + +#include <kunit/platform_device.h> + +#define KUNIT_DEVICE_NAME "test-kunit-mock-device" + +static int fake_probe (struct platform_device *pdev)Please do not abuse platform devices and drivers for things that are not actually platform devices and drivers.
Quoted 6 lines
drivers/base/test/test_kunit_device.c new file +6
-0+{ +return 0 ; +} + +static int fake_remove (struct platform_device *pdev) +{drivers/base/test/test_kunit_device.c line 31
Quoted 10 lines
drivers/base/test/test_kunit_device.c new file +10
-0+return 0 ; +} + +static struct platform_driver fake_platform_driver = { + .probe = fake_probe, + .remove = fake_remove, + .driver = { + .name =KUNIT_DEVICE_NAME , + }, +};Why do you need this fake platform driver at all?
Quoted 1 line
Why not just use a virtual device?
I can only answer on my behalf. In my case the answer to why I used platform_devices is practicality. I wanted to test devm_ APIs using KUnit tests and I was pointed to an existing implementation in DRM (seen in these patches). It didn't seem to make any sense to re-invent the wheel by writing another implementation for the existing in-tree functionality.
Maybe Maxime had a better reason to go with the platform devices.
Quoted 9 lines
drivers/base/test/test_kunit_device.c line 40
Quoted 8 lines
drivers/base/test/test_kunit_device.c new file +8
-0+/** +* test_kunit_helper_alloc_device - Allocate a mock device for a KUnit test +* @test: The test context object +* +* This allocates a fake struct &device to create a mock for a KUnit +* test. The device will also be bound to a fake driver. It will thus be +* able to leverage the usual infrastructure and most notably the +* device-managed resources just like a "real" device.
Quoted 7 lines
What specific "usual infrastructure" are you wanting to access here?
And again, if you want a fake device, make a virtual one, by just calling
device_create().Or are you wanting to do "more" with that device pointer than
device_create()can give you?
Personally, I was (am) only interested in devm_ unwinding. I guess thedevice_create(), device_add(), device_remove()... (didn't study this sequence in details so sorry if there is errors) could've been sufficient for me. I haven't looked how much of the code that there is for 'platform devices' should be duplicated to support that sequence for testability purposes.
The biggest thing for me is that I don't like the idea of creating own 'test device' in <add subsystem here> while we already have some in DRM (or others). Thus, I do see value in adding generic helpers for supporting running KUnit tests on devm_* APIs. Hence it'd be good to have _some_ support for it. And having them in drivers/base/test seemed like a correct place to me. What I really don't know is if there are legitimate use-cases for using platform_devices in DRM tests. Perhaps Maxime can shed light on that.
Yours,
-- Matti
Signature · 5 lines
Matti Vaittinen Linux kernel developer at ROHM Semiconductors Oulu Finland ~~ When things go utterly wrong vim users can always type :help! ~~
Greg Kroah-Hartman
maintainerRe: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
Quoted 47 lines · Matti Vaittinen
Hi Greg,
Thanks for looking at this.
Quoted 42 lines · Greg Kroah-Hartman
Quoted 8 lines · Matti Vaittinen
drivers/base/test/test_kunit_device.c new file +5
-0@@ -0,0 +1,83 @@ +// SPDX-License-Identifier: GPL-2.0 +/* +* These helpers have been extracted from drm test code at +* drm_kunit_helpers.c which was authored by +* Maxime Ripard <[email protected]> drivers/base/test/test_kunit_device.c line 15
Quoted 10 lines
drivers/base/test/test_kunit_device.c new file +10
-0+*/ + +#include <linux/device.h> +#include <linux/platform_device.h> + +#include <kunit/platform_device.h> + +#define KUNIT_DEVICE_NAME "test-kunit-mock-device" + +static int fake_probe (struct platform_device *pdev)Please do not abuse platform devices and drivers for things that are not actually platform devices and drivers.
Quoted 6 lines
drivers/base/test/test_kunit_device.c new file +6
-0+{ +return 0 ; +} + +static int fake_remove (struct platform_device *pdev) +{drivers/base/test/test_kunit_device.c line 31
Quoted 10 lines
drivers/base/test/test_kunit_device.c new file +10
-0+return 0 ; +} + +static struct platform_driver fake_platform_driver = { + .probe = fake_probe, + .remove = fake_remove, + .driver = { + .name =KUNIT_DEVICE_NAME , + }, +};Why do you need this fake platform driver at all?
Quoted 7 lines
Quoted 1 line
Why not just use a virtual device?
I can only answer on my behalf. In my case the answer to why I used
platform_devicesis practicality. I wanted to testdevm_APIs using KUnit tests and I was pointed to an existing implementation in DRM (seen in these patches). It didn't seem to make any sense to re-invent the wheel by writing another implementation for the existing in-tree functionality.
That's fine, but please, let's do this right if it's going to be in the driver core, that way we can actually test the driver core code as well.
Quoted 17 lines
Quoted 9 lines
drivers/base/test/test_kunit_device.c line 40
Quoted 8 lines
drivers/base/test/test_kunit_device.c new file +8
-0+/** +* test_kunit_helper_alloc_device - Allocate a mock device for a KUnit test +* @test: The test context object +* +* This allocates a fake struct &device to create a mock for a KUnit +* test. The device will also be bound to a fake driver. It will thus be +* able to leverage the usual infrastructure and most notably the +* device-managed resources just like a "real" device. Quoted 7 lines
What specific "usual infrastructure" are you wanting to access here?
And again, if you want a fake device, make a virtual one, by just calling
device_create().Or are you wanting to do "more" with that device pointer than
device_create()can give you?
Quoted 6 lines
Personally, I was (am) only interested in
devm_unwinding. I guess thedevice_create(),device_add(),device_remove()... (didn't study this sequence in details so sorry if there is errors) could've been sufficient for me. I haven't looked how much of the code that there is for 'platform devices' should be duplicated to support that sequence for testability purposes.
Any device can access devm_ code, there's no need for it to be a platform device at all.
Quoted 5 lines
The biggest thing for me is that I don't like the idea of creating own 'test device' in <add subsystem here> while we already have some in DRM (or others). Thus, I do see value in adding generic helpers for supporting running KUnit tests on devm_* APIs. Hence it'd be good to have _some_ support for it.
I agree, let's use a virtual device and a virtual bus (you can use the auxbus code for this as that's all there for this type of thing) and then you can test the devm_* code, _AND_ you can test the driver core at the same time.
Quoted 4 lines
And having them in
drivers/base/testseemed like a correct place to me. What I really don't know is if there are legitimate use-cases for usingplatform_devicesin DRM tests. Perhaps Maxime can shed light on that.
I agree that this could be in drivers/base/test/ but then let's test the driver core, not just provide a dummy platform device.
If you want to test the platform driver/device api, that would be great too, that can be plaform device/driver specific, but don't use one for some other random driver core functionality please.
thanks,
greg k-h
Re: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
Quoted 34 lines · Greg Kroah-Hartman
Quoted 23 lines · Matti Vaittinen
Hi Greg,
Thanks for looking at this.
Quoted 10 lines · Greg Kroah-Hartman
Quoted 8 lines · Matti Vaittinen
+/**
+ *test_kunit_helper_alloc_device- Allocate a mock device for a KUnit test
+ * @test: The test context object
+ *
+ * This allocates a fake struct &device to create a mock for a KUnit
+ * test. The device will also be bound to a fake driver. It will thus be
+ * able to leverage the usual infrastructure and most notably the
+ * device-managed resources just like a "real" device.Quoted 7 lines
What specific "usual infrastructure" are you wanting to access here?
And again, if you want a fake device, make a virtual one, by just calling
device_create().Or are you wanting to do "more" with that device pointer than
device_create()can give you?Quoted 6 lines
Personally, I was (am) only interested in
devm_unwinding. I guess thedevice_create(),device_add(),device_remove()... (didn't study this sequence in details so sorry if there is errors) could've been sufficient for me. I haven't looked how much of the code that there is for 'platform devices' should be duplicated to support that sequence for testability purposes.Any device can access
devm_code, there's no need for it to be a platform device at all.
Quoted 8 lines
Quoted 5 lines
The biggest thing for me is that I don't like the idea of creating own 'test device' in <add subsystem here> while we already have some in DRM (or others). Thus, I do see value in adding generic helpers for supporting running KUnit tests on devm_* APIs. Hence it'd be good to have _some_ support for it.
I agree, let's use a virtual device and a virtual bus (you can use the auxbus code for this as that's all there for this type of thing)
Hm. The auxiliary_devices require parent. What would be the best way to deal with that in KUnit tests?
Quoted 8 lines
then you can test the devm_* code, _AND_ you can test the driver core at the same time.
Quoted 4 lines
And having them in
drivers/base/testseemed like a correct place to me. What I really don't know is if there are legitimate use-cases for usingplatform_devicesin DRM tests. Perhaps Maxime can shed light on that.
Quoted 6 lines
I agree that this could be in
drivers/base/test/but then let's test the driver core, not just provide a dummy platform device.If you want to test the platform driver/device api, that would be great too, that can be plaform device/driver specific, but don't use one for some other random driver core functionality please.
I am very conservative what comes to adding unit tests due to the huge inertia they add to any further development. I usually only add tests to APIs which I know won't require changing (I don't know such in-kernel APIs) - or to functions which I think are error-prone. So, I am probably one of the last persons adding UTs to code I don't know :)
Yours,
-- Matti
Signature · 5 lines
Matti Vaittinen Linux kernel developer at ROHM Semiconductors Oulu Finland ~~ When things go utterly wrong vim users can always type :help! ~~
Greg Kroah-Hartman
maintainerRe: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
Quoted 41 lines · Matti
Quoted 40 lines · Greg Kroah-Hartman
Quoted 23 lines · Matti Vaittinen
Hi Greg,
Thanks for looking at this.
Quoted 10 lines · Greg Kroah-Hartman
Quoted 8 lines · Matti Vaittinen
+/**
+ *test_kunit_helper_alloc_device- Allocate a mock device for a KUnit test
+ * @test: The test context object
+ *
+ * This allocates a fake struct &device to create a mock for a KUnit
+ * test. The device will also be bound to a fake driver. It will thus be
+ * able to leverage the usual infrastructure and most notably the
+ * device-managed resources just like a "real" device.Quoted 7 lines
What specific "usual infrastructure" are you wanting to access here?
And again, if you want a fake device, make a virtual one, by just calling
device_create().Or are you wanting to do "more" with that device pointer than
device_create()can give you?Quoted 6 lines
Personally, I was (am) only interested in
devm_unwinding. I guess thedevice_create(),device_add(),device_remove()... (didn't study this sequence in details so sorry if there is errors) could've been sufficient for me. I haven't looked how much of the code that there is for 'platform devices' should be duplicated to support that sequence for testability purposes.Any device can access
devm_code, there's no need for it to be a platform device at all.Quoted 5 lines
The biggest thing for me is that I don't like the idea of creating own 'test device' in <add subsystem here> while we already have some in DRM (or others). Thus, I do see value in adding generic helpers for supporting running KUnit tests on devm_* APIs. Hence it'd be good to have _some_ support for it.
Quoted 5 lines
Quoted 2 lines
I agree, let's use a virtual device and a virtual bus (you can use the auxbus code for this as that's all there for this type of thing)
Hm. The
auxiliary_devicesrequire parent. What would be the best way to deal with that in KUnit tests?
If you use NULL as the parent, it goes into the root.
Quoted 11 lines
Quoted 11 lines
then you can test the devm_* code, _AND_ you can test the driver core at the same time.
Quoted 4 lines
And having them in
drivers/base/testseemed like a correct place to me. What I really don't know is if there are legitimate use-cases for usingplatform_devicesin DRM tests. Perhaps Maxime can shed light on that.I agree that this could be in
drivers/base/test/but then let's test the driver core, not just provide a dummy platform device.
Quoted 8 lines
Quoted 3 lines
If you want to test the platform driver/device api, that would be great too, that can be plaform device/driver specific, but don't use one for some other random driver core functionality please.
I am very conservative what comes to adding unit tests due to the huge inertia they add to any further development. I usually only add tests to APIs which I know won't require changing (I don't know such in-kernel APIs)
So anything that is changing doesn't get a test? If you only test things that don't change then no tests fail, and so, why have the test at all?
On the contrary, tests should be used to verify things that are changing all the time, to ensure that we don't break things. That's why we need them, not to just validate that old code still is going ok.
The driver core is changing, and so, I would love to see tests for it to ensure that I don't break anything over time. That should NOT slow down development but rather, speed it up as it ensures that things still work properly.
Quoted 2 lines
- or to functions which I think are error-prone. So, I am probably one of the last persons adding UTs to code I don't know :)
That's fine, you don't have to add test code for stuff you don't know.
But again, do NOT abuse a platform device for this, that's not ok, and the in-kernel code that does do this should be fixed up.
thanks,
greg k-h
Matti Vaittinen
maintainerRe: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
Quoted 8 lines · Greg Kroah-Hartman
Quoted 7 lines · Matti
Quoted 6 lines · Greg Kroah-Hartman
Quoted 5 lines · Matti Vaittinen
Hi Greg,
Thanks for looking at this.
On 3/22/23 14:07, Greg Kroah-Hartman wrote:
Quoted 8 lines
Quoted 6 lines
Quoted 1 line
Quoted 1 line
Quoted 1 line · Matti Vaittinen
I am very conservative what comes to adding unit tests due to the huge inertia they add to any further development. I usually only add tests to APIs which I know won't require changing (I don't know such in-kernel APIs)
So anything that is changing doesn't get a test?
No. I think you misread me. I didn't say I don't like adding tests to code which changes. I said, I don't like adding tests to APIs which change.
If you only test
Quoted 2 lines
things that don't change then no tests fail, and so, why have the test at all?
Because implementation cascading into functions below an API may change even if the API stays unchanged.
Quoted 2 lines
On the contrary, tests should be used to verify things that are changing all the time, to ensure that we don't break things.
This is only true when your test code stays valid. Problem with excessive amount of tests is that more we have callers for an API, harder changing that API becomes. I've seen a point where people stop fixing "unimportant" things just because the amount of work fixing all impacted UT-cases would take. I know that many things went wrong before that project ended up to the point - but what I picked up with me is that carelessly added UTs do really hinder further development.
That's why we need
Quoted 6 lines
them, not to just validate that old code still is going ok.
The driver core is changing, and so, I would love to see tests for it to ensure that I don't break anything over time. That should NOT slow down development but rather, speed it up as it ensures that things still work properly.
I agree that there are cases where UTs are very handy and can add confidence that things work as intended. Still, my strong opinion is that people should consider what parts of code are really worth testing - and how to do the tests so that the amount of maintenance required by the tests stays low. It's definitely _not fun_ to do refactoring for minor improvement when 400+ unit-test cases break. It's a point when many developers start seeing fixing this minor culprit much less important... And when people stop fixing minor things ... major things start to be just around the corner.
Quoted 8 lines
Quoted 3 lines
- or to functions which I think are error-prone. So, I am probably one of the last persons adding UTs to code I don't know :)
That's fine, you don't have to add test code for stuff you don't know.
But again, do NOT abuse a platform device for this, that's not ok, and the in-kernel code that does do this should be fixed up.
As suggested by David in another mail - I'll go with the root_device_[un]register(). I'll drop this patch entirely. Thanks for help, this was once again very educating :)
Yours,
-- Matti
Signature · 5 lines
Matti Vaittinen Linux kernel developer at ROHM Semiconductors Oulu Finland ~~ When things go utterly wrong vim users can always type :help! ~~
Greg Kroah-Hartman
maintainerRe: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
Quoted 16 lines · Matti Vaittinen
Quoted 15 lines · Greg Kroah-Hartman
Quoted 13 lines · Matti
Quoted 7 lines · Greg Kroah-Hartman
Quoted 6 lines · Matti Vaittinen
Hi Greg,
Thanks for looking at this.
Quoted 1 line · Greg Kroah-Hartman
On Wed, Mar 22, 2023 at 11:05:55AM +0200, Matti Vaittinen wrote:
I am very conservative what comes to adding unit tests due to the huge inertia they add to any further development. I usually only add tests to APIs which I know won't require changing (I don't know such in-kernel APIs)
Quoted 4 lines
Quoted 1 line
So anything that is changing doesn't get a test?
No. I think you misread me. I didn't say I don't like adding tests to code which changes. I said, I don't like adding tests to APIs which change.
Then you should not be writing any in-kernel tests as all of our APIs change all the time.
Quoted 6 lines
If you only test
Quoted 2 lines
things that don't change then no tests fail, and so, why have the test at all?
Because implementation cascading into functions below an API may change even if the API stays unchanged.
Then it needs to be fixed.
Quoted 10 lines
Quoted 2 lines
On the contrary, tests should be used to verify things that are changing all the time, to ensure that we don't break things.
This is only true when your test code stays valid. Problem with excessive amount of tests is that more we have callers for an API, harder changing that API becomes. I've seen a point where people stop fixing "unimportant" things just because the amount of work fixing all impacted UT-cases would take. I know that many things went wrong before that project ended up to the point - but what I picked up with me is that carelessly added UTs do really hinder further development.
Again, in-kernel apis change at any moment. I just changed one that was over 15 years old. Don't get stuck into thinking that you can only write tests for stuff that is "stable" as nothing in the kernel is "stable" and can change at any point in time. You fix up all the in-kernel users of the api, and the tests, and all is good. That's how kernel development works.
Quoted 8 lines
That's why we need
Quoted 6 lines
them, not to just validate that old code still is going ok.
The driver core is changing, and so, I would love to see tests for it to ensure that I don't break anything over time. That should NOT slow down development but rather, speed it up as it ensures that things still work properly.
Quoted 8 lines
I agree that there are cases where UTs are very handy and can add confidence that things work as intended. Still, my strong opinion is that people should consider what parts of code are really worth testing - and how to do the tests so that the amount of maintenance required by the tests stays low. It's definitely
_notfun_to do refactoring for minor improvement when 400+ unit-test cases break. It's a point when many developers start seeing fixing this minor culprit much less important... And when people stop fixing minor things ... major things start to be just around the corner.
If people stop fixing minor things then the kernel development process is dead. Based on all the changes that go into it right now, we are far from having that problem.
So write valid tests, if we get to the point where we have too much of a problem fixing up the tests than the real users of apis, then we can revisit it. But for now, that's not an issue.
And again, remember, and api can, and will, change at any moment in time, you can never know what will be "stable" as we do not have such a thing.
thanks,
greg k-h
Matti Vaittinen
maintainerRe: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
This is a low priority babbling - feel free to skip if busy.
Quoted 46 lines · Greg Kroah-Hartman
Quoted 16 lines · Matti Vaittinen
Quoted 15 lines · Greg Kroah-Hartman
Quoted 13 lines · Matti
Quoted 7 lines · Greg Kroah-Hartman
Quoted 6 lines · Matti Vaittinen
Hi Greg,
Thanks for looking at this.
Quoted 1 line · Greg Kroah-Hartman
On Wed, Mar 22, 2023 at 11:05:55AM +0200, Matti Vaittinen wrote:
I am very conservative what comes to adding unit tests due to the huge inertia they add to any further development. I usually only add tests to APIs which I know won't require changing (I don't know such in-kernel APIs)
Quoted 4 lines
Quoted 1 line
So anything that is changing doesn't get a test?
No. I think you misread me. I didn't say I don't like adding tests to code which changes. I said, I don't like adding tests to APIs which change.
Then you should not be writing any in-kernel tests as all of our APIs change all the time.
Quoted 6 lines
If you only test
Quoted 2 lines
things that don't change then no tests fail, and so, why have the test at all?
Because implementation cascading into functions below an API may change even if the API stays unchanged.
Then it needs to be fixed.
Quoted 10 lines
Quoted 2 lines
On the contrary, tests should be used to verify things that are changing all the time, to ensure that we don't break things.
This is only true when your test code stays valid. Problem with excessive amount of tests is that more we have callers for an API, harder changing that API becomes. I've seen a point where people stop fixing "unimportant" things just because the amount of work fixing all impacted UT-cases would take. I know that many things went wrong before that project ended up to the point - but what I picked up with me is that carelessly added UTs do really hinder further development.
Again, in-kernel apis change at any moment.
Quoted 6 lines · I agree. This is why I initially
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
APIs which I know won't require changing (I don't know such in-kernel APIs)
Don't get stuck into thinking that you can only
write tests for stuff that is "stable" as nothing in the kernel is "stable" and can change at any point in time.
I don't. But I don't either think that UTs come with no cost. Thus I do only write tests when I see a _real need_ for one. If the APIs would be guaranteed not to change, then I would understand writing the tests for each and every "thing" without much of thinking if "the thing" is worth the test.
Quoted 3 lines
You fix up all the
in-kernel users of the api, and the tests, and all is good. That's how kernel development works.
Sure. This is how it works and how I think it should work. But I also have seen how this 'UT work overhead' has made people to decide not to touch things. Not in kernel but in other project. This is a real thing which can happen - many engineers like me are lazy bastards :)
Quoted 17 lines
Quoted 8 lines
That's why we need
Quoted 6 lines
them, not to just validate that old code still is going ok.
The driver core is changing, and so, I would love to see tests for it to ensure that I don't break anything over time. That should NOT slow down development but rather, speed it up as it ensures that things still work properly.
Quoted 8 lines
I agree that there are cases where UTs are very handy and can add confidence that things work as intended. Still, my strong opinion is that people should consider what parts of code are really worth testing - and how to do the tests so that the amount of maintenance required by the tests stays low. It's definitely
_notfun_to do refactoring for minor improvement when 400+ unit-test cases break. It's a point when many developers start seeing fixing this minor culprit much less important... And when people stop fixing minor things ... major things start to be just around the corner.
Quoted 3 lines
If people stop fixing minor things then the kernel development process is dead. Based on all the changes that go into it right now, we are far from having that problem.
And I am so happy for that. Kernel/drivers are still fun to work with. My personal preference is to keep it that way :)
Quoted 3 lines
So write valid tests, if we get to the point where we have too much of a problem fixing up the tests than the real users of apis, then we can revisit it. But for now, that's not an issue.
The beginning of your sentence hits the point. Write valid tests. I just encourage people to occasionally ask if the test they write is really a valid one. :)
Quoted 3 lines
And again, remember, and api can, and will, change at any moment in time, you can never know what will be "stable" as we do not have such a thing.
We agree on this.
Signature · 5 lines
Matti Vaittinen Linux kernel developer at ROHM Semiconductors Oulu Finland ~~ When things go utterly wrong vim users can always type :help! ~~
Matti Vaittinen
maintainerRe: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
In reply to Greg Kroah-HartmanQuoted 16 lines · Greg Kroah-Hartman
Quoted 15 lines · Matti
Quoted 14 lines · Greg Kroah-Hartman
Quoted 12 lines · Matti Vaittinen
Hi Greg,
Thanks for looking at this.
Quoted 1 line · Greg Kroah-Hartman
On Wed, Mar 22, 2023 at 11:05:55AM +0200, Matti Vaittinen wrote:
The biggest thing for me is that I don't like the idea of creating own 'test device' in <add subsystem here> while we already have some in DRM (or others). Thus, I do see value in adding generic helpers for supporting running KUnit tests on devm_* APIs. Hence it'd be good to have _some_ support for it.
Quoted 7 lines
Quoted 5 lines
Quoted 2 lines
I agree, let's use a virtual device and a virtual bus (you can use the auxbus code for this as that's all there for this type of thing)
Hm. The
auxiliary_devicesrequire parent. What would be the best way to deal with that in KUnit tests?If you use NULL as the parent, it goes into the root.
As far as I read this is not the case with auxiliary devices. Judging the docs they were intended to be representing some part of a (parent) device. I see the auxiliary_device_init() has explicit check for parent being populated:
int auxiliary_device_init(struct auxiliary_device *auxdev)
{
struct device *dev = &auxdev->dev;
if (!dev->parent) {
pr_err("auxiliary_device has a NULL dev->parent\n");
return -EINVAL;
}As I wrote in another mail, I thought of using a root_device for this IIO test as was suggested by David. To tell the truth, implementing a kunit bus device is starting to feel a bit overwhelming... I started just adding a driver for a light sensor, ended up adding a helper for IIO gain-time-scale conversions and I am slightly reluctant to going the extra-extra mile of adding some UT infrastructure in the context of this driver work...
Well, let's see. Maybe I change my mind after a good night's sleep :)
Yours,
-- Matti
Signature · 5 lines
Matti Vaittinen Linux kernel developer at ROHM Semiconductors Oulu Finland ~~ When things go utterly wrong vim users can always type :help! ~~
Greg Kroah-Hartman
maintainerRe: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
Quoted 30 lines · Matti Vaittinen
Quoted 16 lines · Greg Kroah-Hartman
Quoted 15 lines · Matti
Quoted 14 lines · Greg Kroah-Hartman
Quoted 12 lines · Matti Vaittinen
Hi Greg,
Thanks for looking at this.
Quoted 1 line · Greg Kroah-Hartman
On Wed, Mar 22, 2023 at 11:05:55AM +0200, Matti Vaittinen wrote:
The biggest thing for me is that I don't like the idea of creating own 'test device' in <add subsystem here> while we already have some in DRM (or others). Thus, I do see value in adding generic helpers for supporting running KUnit tests on devm_* APIs. Hence it'd be good to have _some_ support for it.
Quoted 7 lines
Quoted 5 lines
Quoted 2 lines
I agree, let's use a virtual device and a virtual bus (you can use the auxbus code for this as that's all there for this type of thing)
Hm. The
auxiliary_devicesrequire parent. What would be the best way to deal with that in KUnit tests?If you use NULL as the parent, it goes into the root.
As far as I read this is not the case with auxiliary devices. Judging the docs they were intended to be representing some part of a (parent) device. I see the
auxiliary_device_init()has explicit check for parent being populated:
Quoted 8 lines
int
auxiliary_device_init(struct auxiliary_device *auxdev){ struct device *dev = &auxdev->dev; if (!dev->parent) { pr_err("auxiliary_device has a NULL dev->parent\n"); return -EINVAL; }
Yes as it wants to "split" a device up into smaller devices. So make a real device that it can hang off of.
Quoted 6 lines
As I wrote in another mail, I thought of using a
root_devicefor this IIO test as was suggested by David. To tell the truth, implementing a kunit bus device is starting to feel a bit overwhelming... I started just adding a driver for a light sensor, ended up adding a helper for IIO gain-time-scale conversions and I am slightly reluctant to going the extra-extra mile of adding some UT infrastructure in the context of this driver work...
I think it is worth it as the driver core has no tests. So it obviously must be correct, right? :)
thanks,
greg k-h
Matti Vaittinen
maintainerRe: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
Quoted 35 lines · Greg Kroah-Hartman
Quoted 34 lines · Matti Vaittinen
Quoted 16 lines · Greg Kroah-Hartman
Quoted 15 lines · Matti
Quoted 14 lines · Greg Kroah-Hartman
Quoted 12 lines · Matti Vaittinen
Hi Greg,
Thanks for looking at this.
Quoted 1 line · Greg Kroah-Hartman
On Wed, Mar 22, 2023 at 11:05:55AM +0200, Matti Vaittinen wrote:
The biggest thing for me is that I don't like the idea of creating own 'test device' in <add subsystem here> while we already have some in DRM (or others). Thus, I do see value in adding generic helpers for supporting running KUnit tests on devm_* APIs. Hence it'd be good to have _some_ support for it.
Quoted 7 lines
Quoted 5 lines
Quoted 2 lines
I agree, let's use a virtual device and a virtual bus (you can use the auxbus code for this as that's all there for this type of thing)
Hm. The
auxiliary_devicesrequire parent. What would be the best way to deal with that in KUnit tests?If you use NULL as the parent, it goes into the root.
As far as I read this is not the case with auxiliary devices. Judging the docs they were intended to be representing some part of a (parent) device. I see the
auxiliary_device_init()has explicit check for parent being populated:int
auxiliary_device_init(struct auxiliary_device *auxdev){ struct device *dev = &auxdev->dev;
Quoted 7 lines
Quoted 4 lines
if (!dev->parent) { pr_err("auxiliary_device has a NULL dev->parent\n"); return -EINVAL; }Yes as it wants to "split" a device up into smaller devices. So make a real device that it can hang off of.
Yep. This is what led me to the root_device_register()... :rolleyes: And seein the root-device alone could do what I need - adding auxiliary device on top of it just for the sake of adding one seems a bit of an over-engineering to me :)
Quoted 9 lines
Quoted 6 lines
As I wrote in another mail, I thought of using a
root_devicefor this IIO test as was suggested by David. To tell the truth, implementing a kunit bus device is starting to feel a bit overwhelming... I started just adding a driver for a light sensor, ended up adding a helper for IIO gain-time-scale conversions and I am slightly reluctant to going the extra-extra mile of adding some UT infrastructure in the context of this driver work...I think it is worth it as the driver core has no tests. So it obviously must be correct, right? :)
Doh. Greg, I hate you :) How could one argue with something like this? I think I will submit the v6 with the root_device_register() due to the aux-device requiring it in any case. I know that will end up to your table still as IIO is going through your hands anyways.
I will however take a look at what Maxime said about devm unwinding not being done w/o a bus because I think I saw the unwinding done in these IIO tests even when using the root_device_register() root_device_unregister(). If the unwinding really is not done, then I will come back to this auxiliary device rehearsal
Signature · 5 lines
Matti Vaittinen Linux kernel developer at ROHM Semiconductors Oulu Finland ~~ When things go utterly wrong vim users can always type :help! ~~
Re: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
In reply to Greg Kroah-HartmanQuoted 24 lines · Greg Kroah-Hartman
Quoted 17 lines
Quoted 9 lines
Quoted 8 lines
+/**
+ *test_kunit_helper_alloc_device- Allocate a mock device for a KUnit test
+ * @test: The test context object
+ *
+ * This allocates a fake struct &device to create a mock for a KUnit
+ * test. The device will also be bound to a fake driver. It will thus be
+ * able to leverage the usual infrastructure and most notably the
+ * device-managed resources just like a "real" device.Quoted 7 lines
What specific "usual infrastructure" are you wanting to access here?
And again, if you want a fake device, make a virtual one, by just calling
device_create().Or are you wanting to do "more" with that device pointer than
device_create()can give you?Quoted 6 lines
Personally, I was (am) only interested in
devm_unwinding. I guess thedevice_create(),device_add(),device_remove()... (didn't study this sequence in details so sorry if there is errors) could've been sufficient for me. I haven't looked how much of the code that there is for 'platform devices' should be duplicated to support that sequence for testability purposes.
Quoted 2 lines
Any device can access
devm_code, there's no need for it to be a platform device at all.
Sure but the resources are only released if the device is part of a bus, so it can't be a root_device (or bare device) either
Maxime
Greg Kroah-Hartman
maintainerRe: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
Quoted 25 lines · Maxime Ripard
Quoted 24 lines · Greg Kroah-Hartman
Quoted 23 lines
Quoted 9 lines
Quoted 8 lines
+/**
+ *test_kunit_helper_alloc_device- Allocate a mock device for a KUnit test
+ * @test: The test context object
+ *
+ * This allocates a fake struct &device to create a mock for a KUnit
+ * test. The device will also be bound to a fake driver. It will thus be
+ * able to leverage the usual infrastructure and most notably the
+ * device-managed resources just like a "real" device.Quoted 7 lines
What specific "usual infrastructure" are you wanting to access here?
And again, if you want a fake device, make a virtual one, by just calling
device_create().Or are you wanting to do "more" with that device pointer than
device_create()can give you?Personally, I was (am) only interested in
devm_unwinding. I guess thedevice_create(),device_add(),device_remove()... (didn't study this sequence in details so sorry if there is errors) could've been sufficient for me. I haven't looked how much of the code that there is for 'platform devices' should be duplicated to support that sequence for testability purposes.
Quoted 5 lines
Quoted 2 lines
Any device can access
devm_code, there's no need for it to be a platform device at all.Sure but the resources are only released if the device is part of a bus, so it can't be a
root_device(or bare device) either
The resources are not cleaned up when the device is freed no matter if it's on a bus or not? If so, then that's a bug that needs to be fixed, and tested :)
thanks,
greg k-h
Matti Vaittinen
maintainerRe: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
Hi Maxime, all
Quoted 29 lines · Greg Kroah-Hartman
Quoted 28 lines · Maxime Ripard
Quoted 26 lines · Greg Kroah-Hartman
Quoted 17 lines
Quoted 9 lines
Quoted 8 lines
+/**
+ *test_kunit_helper_alloc_device- Allocate a mock device for a KUnit test
+ * @test: The test context object
+ *
+ * This allocates a fake struct &device to create a mock for a KUnit
+ * test. The device will also be bound to a fake driver. It will thus be
+ * able to leverage the usual infrastructure and most notably the
+ * device-managed resources just like a "real" device.Quoted 7 lines
What specific "usual infrastructure" are you wanting to access here?
And again, if you want a fake device, make a virtual one, by just calling
device_create().Or are you wanting to do "more" with that device pointer than
device_create()can give you?Quoted 6 lines
Personally, I was (am) only interested in
devm_unwinding. I guess thedevice_create(),device_add(),device_remove()... (didn't study this sequence in details so sorry if there is errors) could've been sufficient for me. I haven't looked how much of the code that there is for 'platform devices' should be duplicated to support that sequence for testability purposes.Any device can access
devm_code, there's no need for it to be a platform device at all.
Quoted 6 lines
Quoted 2 lines
Sure but the resources are only released if the device is part of a bus, so it can't be a
root_device(or bare device) eitherThe resources are not cleaned up when the device is freed no matter if it's on a bus or not? If so, then that's a bug that needs to be fixed, and tested :)
This is strange. I just ran a test on a beaglebone black using Linux 6.3.0-rc2 + the IIO patches we se here (but the IIO test patch modified to use the root_device_register() and root_device_unregister().
I passed the device pointer from root_device_register() to the devm_iio_init_iio_gts()
// snip
dev = root_device_register(IIO_GTS_TEST_DEV);
KUNIT_EXPECT_NOT_ERR_OR_NULL(test, dev);
if (IS_ERR_OR_NULL(dev))
return NULL;
ret = devm_iio_init_iio_gts(dev, TEST_SCALE_1X, 0, g_table, num_g,
i_table, num_i, gts);- and saw the tables for available scales allocated:
if (gts.num_avail_all_scales)
pr_info("GTS: table allocation succeeded\n");
else
pr_info("GTS: table allocation failed\n");
pr_info("gts: num_avail_all_scales %d\n", gts.num_avail_all_scales);
(this printed:
[ 52.132966] # Subtest: iio-gain-time-scale [ 52.132982] 1..7 [ 52.157455] GTS: table allocation succeeded [ 52.164077] gts: num_avail_all_scales 16
Next I unregister the root-device and check if the unwinding code which frees the tables and zeroes the scale count was ran:
root_device_unregister(dev);
pr_info("gts: num_avail_all_scales %d\n", gts.num_avail_all_scales);
if (gts.num_avail_all_scales)
pr_info("devm unwinding not done\n");
else
pr_info("devm unwinding succeeded\n");Which printed:
[ 52.168101] gts: num_avail_all_scales 0 [ 52.171957] devm unwinding succeeded
I can send patch(es) just for testing this on other machines if someone want's to see if the lack of devm unwinding is somehow architecture specific (which sounds very strange to me) - although using this IIO series just for checking the unwinding is a bit of an overkill. I just happened to have these tests at my hands / in my tree for testing.
In any case, devm unwinding using root_device_[un]register() seems to "work on my machine".
Naxime, what was the environment where you observed lack of unwinding? (Huh, I am so afraid of sending this post out - I've experienced too many "Oh, boy - how I didn't notice THAT" moments in the past and maybe I am again overlooking something...)
Yours,
-- Matti
Signature · 5 lines
Matti Vaittinen Linux kernel developer at ROHM Semiconductors Oulu Finland ~~ When things go utterly wrong vim users can always type :help! ~~
Re: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
Quoted 91 lines · Matti Vaittinen
Hi Maxime, all
Quoted 29 lines · Greg Kroah-Hartman
Quoted 28 lines · Maxime Ripard
Quoted 26 lines · Greg Kroah-Hartman
Quoted 17 lines
Quoted 9 lines
Quoted 8 lines
+/**
+ *test_kunit_helper_alloc_device- Allocate a mock device for a KUnit test
+ * @test: The test context object
+ *
+ * This allocates a fake struct &device to create a mock for a KUnit
+ * test. The device will also be bound to a fake driver. It will thus be
+ * able to leverage the usual infrastructure and most notably the
+ * device-managed resources just like a "real" device.Quoted 7 lines
What specific "usual infrastructure" are you wanting to access here?
And again, if you want a fake device, make a virtual one, by just calling
device_create().Or are you wanting to do "more" with that device pointer than
device_create()can give you?Quoted 6 lines
Personally, I was (am) only interested in
devm_unwinding. I guess thedevice_create(),device_add(),device_remove()... (didn't study this sequence in details so sorry if there is errors) could've been sufficient for me. I haven't looked how much of the code that there is for 'platform devices' should be duplicated to support that sequence for testability purposes.Any device can access
devm_code, there's no need for it to be a platform device at all.Quoted 6 lines
Quoted 2 lines
Sure but the resources are only released if the device is part of a bus, so it can't be a
root_device(or bare device) eitherThe resources are not cleaned up when the device is freed no matter if it's on a bus or not? If so, then that's a bug that needs to be fixed, and tested :)
This is strange. I just ran a test on a beaglebone black using Linux 6.3.0-rc2 + the IIO patches we se here (but the IIO test patch modified to use the
root_device_register()androot_device_unregister().I passed the device pointer from
root_device_register()to thedevm_iio_init_iio_gts()// snip
dev = root_device_register(IIO_GTS_TEST_DEV); KUNIT_EXPECT_NOT_ERR_OR_NULL(test, dev); if (IS_ERR_OR_NULL(dev)) return NULL; ret = devm_iio_init_iio_gts(dev, TEST_SCALE_1X, 0, g_table, num_g, i_table, num_i, gts);- and saw the tables for available scales allocated:
if (gts.num_avail_all_scales)
pr_info("GTS: table allocation succeeded\n"); else pr_info("GTS: table allocation failed\n"); pr_info("gts: num_avail_all_scales %d\n", gts.num_avail_all_scales);(this printed:
[ 52.132966] # Subtest: iio-gain-time-scale [ 52.132982] 1..7 [ 52.157455] GTS: table allocation succeeded [ 52.164077] gts: num_avail_all_scales 16Next I unregister the root-device and check if the unwinding code which frees the tables and zeroes the scale count was ran:
root_device_unregister(dev); pr_info("gts: num_avail_all_scales %d\n", gts.num_avail_all_scales); if (gts.num_avail_all_scales) pr_info("devm unwinding not done\n"); else pr_info("devm unwinding succeeded\n");Which printed:
[ 52.168101] gts: num_avail_all_scales 0 [ 52.171957] devm unwinding succeededI can send patch(es) just for testing this on other machines if someone want's to see if the lack of devm unwinding is somehow architecture specific (which sounds very strange to me) - although using this IIO series just for checking the unwinding is a bit of an overkill. I just happened to have these tests at my hands / in my tree for testing.
Quoted 7 lines
In any case, devm unwinding using root_device_[un]register() seems to "work on my machine".
Naxime, what was the environment where you observed lack of unwinding? (Huh, I am so afraid of sending this post out - I've experienced too many "Oh, boy
- how I didn't notice THAT" moments in the past and maybe I am again overlooking something...)
This is the description of what was happening:
https://lore.kernel.org/dri-devel/20221117165311.vovrc7usy4efiytl@houat/
Maxime
Matti Vaittinen
maintainerRe: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
Quoted 4 lines · Maxime Ripard
On Thu, Mar 23, 2023 at 02:16:52PM +0200, Matti Vaittinen wrote:
This is the description of what was happening:
https://lore.kernel.org/dri-devel/20221117165311.vovrc7usy4efiytl@houat/
Thanks Maxime. Do I read this correcty. The devm_ unwinding not being done when root_device_register() is used is not because root_device_unregister() would not trigger the unwinding - but rather because DRM code on top of this device keeps the refcount increased?
If this is the case, then it sounds like a DRM specific issue to me. Whether it is a feature or bug is beyond my knowledge. Still, I would not say using the root_device_[un]register() in generic code is not feasible - unless all other subsytems have similar refcount handling.
Sure thing using root_device_register() root_device_unregister() in DRM does not work as such. This, however, does not mean the generic kunit helpers should use platform_devices to force unwinding?
Well, It's almost the best season for ice-fishing in Finland so opening a can of worms is not that bad, right? :)
Thanks for the education people! I did learn a thing or two Today.
Yours,
-- Matti
Signature · 5 lines
Matti Vaittinen Linux kernel developer at ROHM Semiconductors Oulu Finland ~~ When things go utterly wrong vim users can always type :help! ~~
Re: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
Quoted 10 lines · Matti Vaittinen
Quoted 4 lines · Maxime Ripard
On Thu, Mar 23, 2023 at 02:16:52PM +0200, Matti Vaittinen wrote:
This is the description of what was happening:
https://lore.kernel.org/dri-devel/20221117165311.vovrc7usy4efiytl@houat/Thanks Maxime. Do I read this correcty. The
devm_unwinding not being done whenroot_device_register()is used is not becauseroot_device_unregister()would not trigger the unwinding - but rather because DRM code on top of this device keeps the refcount increased?
There's a difference of behaviour between a root_device and any device with a bus: the root_device will only release the devm resources when it's freed (in device_release), but a bus device will also do it in device_del (through bus_remove_device() -> device_release_driver() -> device_release_driver_internal() -> __device_release_driver() -> device_unbind_cleanup(), which are skipped (in multiple places) if there's no bus and no driver attached to the device).
It does affect DRM, but I'm pretty sure it will affect any framework that deals with device hotplugging by deferring the framework structure until the last (userspace) user closes its file descriptor. So I'd assume that v4l2 and cec at least are also affected, and most likely others.
Quoted 1 line
If this is the case, then it sounds like a DRM specific issue to me.
I mean, I guess. One could also argue that it's because IIO doesn't properly deal with hotplugging. I'm not sure how that helps. Those are common helpers which should accommodate every framework, and your second patch breaks the kunit tests for DRM anyway.
Quoted 7 lines
Whether it is a feature or bug is beyond my knowledge. Still, I would not say using the root_device_[un]register() in generic code is not feasible - unless all other subsytems have similar refcount handling.
Sure thing using
root_device_register()root_device_unregister()in DRM does not work as such. This, however, does not mean the generic kunit helpers should useplatform_devicesto force unwinding?
platform_devices were a quick way to get a device that would have a bus and a driver bound to fall into the right patch above. We probably shouldn't use platform_devices and a kunit_device sounds like the best idea, but the test linked in the original mail I pointed you to should work with whatever we come up with. It works with multiple (platform, PCI, USB, etc) buses, so the mock we create should behave like their real world equivalents.
Maxime
Matti Vaittinen
maintainerRe: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
Quoted 20 lines · Maxime Ripard
Quoted 10 lines · Matti Vaittinen
Quoted 4 lines · Maxime Ripard
On Thu, Mar 23, 2023 at 02:16:52PM +0200, Matti Vaittinen wrote:
This is the description of what was happening:
https://lore.kernel.org/dri-devel/20221117165311.vovrc7usy4efiytl@houat/Thanks Maxime. Do I read this correcty. The
devm_unwinding not being done whenroot_device_register()is used is not becauseroot_device_unregister()would not trigger the unwinding - but rather because DRM code on top of this device keeps the refcount increased?There's a difference of behaviour between a
root_deviceand any device with a bus: theroot_devicewill only release the devm resources when it's freed (indevice_release), but a bus device will also do it indevice_del(throughbus_remove_device()->device_release_driver()->device_release_driver_internal()->__device_release_driver()->device_unbind_cleanup(), which are skipped (in multiple places) if there's no bus and no driver attached to the device).
Quoted 5 lines
It does affect DRM, but I'm pretty sure it will affect any framework that deals with device hotplugging by deferring the framework structure until the last (userspace) user closes its file descriptor. So I'd assume that v4l2 and cec at least are also affected, and most likely others.
Thanks for the explanation and patience :)
Quoted 5 lines
Quoted 2 lines
If this is the case, then it sounds like a DRM specific issue to me.
I mean, I guess. One could also argue that it's because IIO doesn't properly deal with hotplugging.
I must say I haven't been testing the IIO registration API. I've only tested the helper API which is not backed up by any "IIO device". (This is fine for the helper because it must by design be cleaned-up only after the IIO-deregistration).
After your explanation here, I am not convinced IIO wouldn't see the same issue if I was testing the devm_iio_device_alloc() & co.
Quoted 2 lines
I'm not sure how that helps. Those are
common helpers which should accommodate every framework,
Ok. Fair enough. Besides, if the root-device was sufficient - then I would actually not see the need for a helper. People could in that case directly use the root_device_register(). So, if helpers are provided they should be backed up by a device with a bus then.
Quoted 2 lines
and your second
patch breaks the kunit tests for DRM anyway.
Oh, I must have made an error there. It was supposed to be just a refactoring with no functional changes. Sorry about that. Anyways, that patch can be forgotten as Greg opposes using the platform devices in generic helpers.
Quoted 8 lines
Quoted 7 lines
Whether it is a feature or bug is beyond my knowledge. Still, I would not say using the root_device_[un]register() in generic code is not feasible - unless all other subsytems have similar refcount handling.
Sure thing using
root_device_register()root_device_unregister()in DRM does not work as such. This, however, does not mean the generic kunit helpers should useplatform_devicesto force unwinding?
Quoted 7 lines
platform_deviceswere a quick way to get a device that would have a bus and a driver bound to fall into the right patch above. We probably shouldn't useplatform_devicesand akunit_devicesounds like the best idea, but the test linked in the original mail I pointed you to should work with whatever we come up with. It works with multiple (platform, PCI, USB, etc) buses, so the mock we create should behave like their real world equivalents.
Thanks for the patience and the explanation. Now I understand a generic test device needs to sit on a bus.
As I said, in my very specific IIO related test the test device does not need a bus. Hence I'll drop the 'generic helpers' from this series.
Yours,
-- Matti
Signature · 5 lines
Matti Vaittinen Linux kernel developer at ROHM Semiconductors Oulu Finland ~~ When things go utterly wrong vim users can always type :help! ~~
Re: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
Quoted 22 lines · Matti Vaittinen
Quoted 20 lines · Maxime Ripard
Quoted 10 lines · Matti Vaittinen
Quoted 4 lines · Maxime Ripard
On Thu, Mar 23, 2023 at 02:16:52PM +0200, Matti Vaittinen wrote:
This is the description of what was happening:
https://lore.kernel.org/dri-devel/20221117165311.vovrc7usy4efiytl@houat/Thanks Maxime. Do I read this correcty. The
devm_unwinding not being done whenroot_device_register()is used is not becauseroot_device_unregister()would not trigger the unwinding - but rather because DRM code on top of this device keeps the refcount increased?There's a difference of behaviour between a
root_deviceand any device with a bus: theroot_devicewill only release the devm resources when it's freed (indevice_release), but a bus device will also do it indevice_del(throughbus_remove_device()->device_release_driver()->device_release_driver_internal()->__device_release_driver()->device_unbind_cleanup(), which are skipped (in multiple places) if there's no bus and no driver attached to the device).
Quoted 8 lines
Quoted 5 lines
It does affect DRM, but I'm pretty sure it will affect any framework that deals with device hotplugging by deferring the framework structure until the last (userspace) user closes its file descriptor. So I'd assume that v4l2 and cec at least are also affected, and most likely others.
Thanks for the explanation and patience :)
Thanks from me as well -- this has certainly helped me understand some of the details of the driver model that had slipped past me.
Quoted 14 lines
Quoted 5 lines
Quoted 2 lines
If this is the case, then it sounds like a DRM specific issue to me.
I mean, I guess. One could also argue that it's because IIO doesn't properly deal with hotplugging.
I must say I haven't been testing the IIO registration API. I've only tested the helper API which is not backed up by any "IIO device". (This is fine for the helper because it must by design be cleaned-up only after the IIO-deregistration).
After your explanation here, I am not convinced IIO wouldn't see the same issue if I was testing the
devm_iio_device_alloc()& co.
Quoted 8 lines
Quoted 2 lines
I'm not sure how that helps. Those are
common helpers which should accommodate every framework,Ok. Fair enough. Besides, if the root-device was sufficient - then I would actually not see the need for a helper. People could in that case directly use the
root_device_register(). So, if helpers are provided they should be backed up by a device with a bus then.
I think there is _some_ value in helpers even without a bus, but it's much more limited:
- It's less confusing if KUnit test devices are using kunit labelled structs and functions.
- Helpers could use KUnit's resource management API to ensure any device created is properly unregistered and removed when the test exits (particularly if it exits early due to, e.g., an assertion).
I've played around implementing those with a proper struct kunit_device and the automatic cleanup on test failure, and thus far it -- like root_device_register -- works for all of the tests except the drm-test-managed one.
So if we really wanted to, we could use KUnit-specific helpers for just those tests which currently work with root_device_register(), but if we're going to try to implement a KUnit bus -- which I think is at least worth investigating -- I'd rather not either hold up otherwise good tests on helper development, or rush a helper out only to have to change it a lot when we see exactly what the bus implementation would look like.
Quoted 23 lines
Quoted 2 lines
and your second
patch breaks the kunit tests for DRM anyway.Oh, I must have made an error there. It was supposed to be just a refactoring with no functional changes. Sorry about that. Anyways, that patch can be forgotten as Greg opposes using the platform devices in generic helpers.
Quoted 8 lines
Quoted 7 lines
Whether it is a feature or bug is beyond my knowledge. Still, I would not say using the root_device_[un]register() in generic code is not feasible - unless all other subsytems have similar refcount handling.
Sure thing using
root_device_register()root_device_unregister()in DRM does not work as such. This, however, does not mean the generic kunit helpers should useplatform_devicesto force unwinding?Quoted 7 lines
platform_deviceswere a quick way to get a device that would have a bus and a driver bound to fall into the right patch above. We probably shouldn't useplatform_devicesand akunit_devicesounds like the best idea, but the test linked in the original mail I pointed you to should work with whatever we come up with. It works with multiple (platform, PCI, USB, etc) buses, so the mock we create should behave like their real world equivalents.
Quoted 6 lines
Thanks for the patience and the explanation. Now I understand a generic test device needs to sit on a bus.
As I said, in my very specific IIO related test the test device does not need a bus. Hence I'll drop the 'generic helpers' from this series.
I think that sounds like a good strategy for now, and we can work on a set of 'generic helpers' which have an associated bus and struct kunit_device in the meantime. If we can continue to use root_device_register until those are ready, that'd be very convenient. Certainly, the helpers I'm playing with at the moment have a few other dependencies I'd want to land first, so I suspect they wouldn't be done in time for 6.4. It'd also make sense to see if we can make sure any such helpers could either work well with (or at least not conflict with) tests which use devicetree.
Regardless, thanks very much for putting all of the effort in to working this out. I think we have a much better idea of the requirements for this sort of thing now.
Cheers,
-- David
Matti Vaittinen
maintainerRe: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
Quoted 12 lines · David Gow
Quoted 10 lines · Matti Vaittinen
Quoted 3 lines · Maxime Ripard
Quoted 2 lines · Matti Vaittinen
Quoted 1 line · Maxime Ripard
On Thu, Mar 23, 2023 at 02:16:52PM +0200, Matti Vaittinen wrote:
Ok. Fair enough. Besides, if the root-device was sufficient - then I would actually not see the need for a helper. People could in that case directly use the
root_device_register(). So, if helpers are provided they should be backed up by a device with a bus then.
Quoted 7 lines
I think there is _some_ value in helpers even without a bus, but it's much more limited:
- It's less confusing if KUnit test devices are using kunit labelled structs and functions.
- Helpers could use KUnit's resource management API to ensure any device created is properly unregistered and removed when the test exits (particularly if it exits early due to, e.g., an assertion).
Ah. That's true. Being able to abort the test on error w/o being forced to do a clean-up dance for the dummy device would be convenient.
Quoted 5 lines
I've played around implementing those with a proper struct
kunit_deviceand the automatic cleanup on test failure, and thus far it -- likeroot_device_register-- works for all of the tests except the drm-test-managed one.
Quoted 7 lines
So if we really wanted to, we could use KUnit-specific helpers for just those tests which currently work with
root_device_register(), but if we're going to try to implement a KUnit bus -- which I think is at least worth investigating -- I'd rather not either hold up otherwise good tests on helper development, or rush a helper out only to have to change it a lot when we see exactly what the bus implementation would look like.
It's easy for me to agree.
Quoted 8 lines
Quoted 3 lines
As I said, in my very specific IIO related test the test device does not need a bus. Hence I'll drop the 'generic helpers' from this series.
I think that sounds like a good strategy for now, and we can work on a set of 'generic helpers' which have an associated bus and struct
kunit_devicein the meantime. If we can continue to useroot_device_registeruntil those are ready, that'd be very convenient.
Would it be a tiny bit more acceptable if we did add a very simple:
#define kunit_root_device_register(name) root_device_register(name) #define kunit_root_device_unregister(dev) root_device_unregister(dev)
to include/kunit/device.h (or somesuch)
This should help us later to at least spot the places where root_device_[un]register() is abused and (potentially mass-)covert them to use the proper helpers when they're available.
Yours,
-- Matti
Signature · 5 lines
Matti Vaittinen Linux kernel developer at ROHM Semiconductors Oulu Finland ~~ When things go utterly wrong vim users can always type :help! ~~
Re: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
Quoted 51 lines · Matti Vaittinen
Quoted 12 lines · David Gow
Quoted 10 lines · Matti Vaittinen
Quoted 3 lines · Maxime Ripard
Quoted 2 lines · Matti Vaittinen
Quoted 1 line · Maxime Ripard
On Thu, Mar 23, 2023 at 02:16:52PM +0200, Matti Vaittinen wrote:
Ok. Fair enough. Besides, if the root-device was sufficient - then I would actually not see the need for a helper. People could in that case directly use the
root_device_register(). So, if helpers are provided they should be backed up by a device with a bus then.Quoted 7 lines
I think there is _some_ value in helpers even without a bus, but it's much more limited:
- It's less confusing if KUnit test devices are using kunit labelled structs and functions.
- Helpers could use KUnit's resource management API to ensure any device created is properly unregistered and removed when the test exits (particularly if it exits early due to, e.g., an assertion).Ah. That's true. Being able to abort the test on error w/o being forced to do a clean-up dance for the dummy device would be convenient.
Quoted 5 lines
I've played around implementing those with a proper struct
kunit_deviceand the automatic cleanup on test failure, and thus far it -- likeroot_device_register-- works for all of the tests except the drm-test-managed one.Quoted 7 lines
So if we really wanted to, we could use KUnit-specific helpers for just those tests which currently work with
root_device_register(), but if we're going to try to implement a KUnit bus -- which I think is at least worth investigating -- I'd rather not either hold up otherwise good tests on helper development, or rush a helper out only to have to change it a lot when we see exactly what the bus implementation would look like.It's easy for me to agree.
Quoted 8 lines
Quoted 3 lines
As I said, in my very specific IIO related test the test device does not need a bus. Hence I'll drop the 'generic helpers' from this series.
I think that sounds like a good strategy for now, and we can work on a set of 'generic helpers' which have an associated bus and struct
kunit_devicein the meantime. If we can continue to useroot_device_registeruntil those are ready, that'd be very convenient.Would it be a tiny bit more acceptable if we did add a very simple:
Quoted 9 lines
#define
kunit_root_device_register(name)root_device_register(name)#definekunit_root_device_unregister(dev)root_device_unregister(dev)to
include/kunit/device.h(or somesuch)This should help us later to at least spot the places where root_device_[un]register() is abused and (potentially mass-)covert them to use the proper helpers when they're available.
Great idea.
The code I've been playing with has the following in include/kunit/device.h:
/* 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);
If we used the same names, and just forwarded them to root_device_register() and root_device_unregister() for now (discarding the struct kunit pointer), then I expect we could just swap out the implementation to gain the extra functionality.
It's a little less explicit, though, so I could see the value in using macros with "root_device" in the name to make the current implementation clearer, and the eventual change more obvious.
Cheers,
-- David
Matti Vaittinen
maintainerRe: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
Quoted 32 lines · David Gow
Quoted 11 lines · Matti Vaittinen
Quoted 6 lines · David Gow
On Fri, 24 Mar 2023 at 14:11, Matti Vaittinen <[email protected]> wrote:
I think that sounds like a good strategy for now, and we can work on a set of 'generic helpers' which have an associated bus and struct
kunit_devicein the meantime. If we can continue to useroot_device_registeruntil those are ready, that'd be very convenient.Would it be a tiny bit more acceptable if we did add a very simple:
Quoted 9 lines
#define
kunit_root_device_register(name)root_device_register(name)#definekunit_root_device_unregister(dev)root_device_unregister(dev)to
include/kunit/device.h(or somesuch)This should help us later to at least spot the places where root_device_[un]register() is abused and (potentially mass-)covert them to use the proper helpers when they're available.
Great idea.
The code I've been playing with has the following in
include/kunit/device.h:/* Register a new device against a KUnit test. */
struct device *kunit_device_register(struct kunit *test, const char *name); /* Unregister a device created bykunit_device_register()early (i.e., before test cleanup). */
voidkunit_device_unregister(struct kunit *test, struct device *dev);
Quoted 8 lines
If we used the same names, and just forwarded them to
root_device_register()androot_device_unregister()for now (discarding the struct kunit pointer), then I expect we could just swap out the implementation to gain the extra functionality.It's a little less explicit, though, so I could see the value in using macros with "
root_device" in the name to make the current implementation clearer, and the eventual change more obvious.
I think it makes sense to avoid the mass-conversions if the signatures for kunit_device_register() and kunit_device_unregister() are expected to be known by now. If there is no objections I'll add those wrappers + the include/kunit/device.h to v6 of this series.
I think I'll try to hold back sending the v6 until next Monday - unless I get really bored during the weekend ;)
Yours,
-- Matti
Signature · 5 lines
Matti Vaittinen Linux kernel developer at ROHM Semiconductors Oulu Finland ~~ When things go utterly wrong vim users can always type :help! ~~
Matti Vaittinen
maintainerRe: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
Quoted 33 lines · Matti Vaittinen
Quoted 32 lines · David Gow
Quoted 11 lines · Matti Vaittinen
Quoted 6 lines · David Gow
On Fri, 24 Mar 2023 at 14:11, Matti Vaittinen <[email protected]> wrote:
I think that sounds like a good strategy for now, and we can work on a set of 'generic helpers' which have an associated bus and struct
kunit_devicein the meantime. If we can continue to useroot_device_registeruntil those are ready, that'd be very convenient.Would it be a tiny bit more acceptable if we did add a very simple:
Quoted 9 lines
#define
kunit_root_device_register(name)root_device_register(name)#definekunit_root_device_unregister(dev)root_device_unregister(dev)to
include/kunit/device.h(or somesuch)This should help us later to at least spot the places where root_device_[un]register() is abused and (potentially mass-)covert them to use the proper helpers when they're available.
Great idea.
The code I've been playing with has the following in
include/kunit/device.h:/* Register a new device against a KUnit test. */
struct device *kunit_device_register(struct kunit *test, const char *name); /* Unregister a device created bykunit_device_register()early (i.e., before test cleanup). */
voidkunit_device_unregister(struct kunit *test, struct device *dev);
Quoted 4 lines
Quoted 4 lines
If we used the same names, and just forwarded them to
root_device_register()androot_device_unregister()for now (discarding the struct kunit pointer), then I expect we could just swap out the implementation to gain the extra functionality.
There's one thing though. If the goal is to do a direct replacement and if automatic device deletion upon test completion / test abort is planned - then it should be there also for these initial wrappers.
If these wrappers don't yet include the automatic device clean-up - then it probably makes more sense to just do the kunit_root_device_* defines because the tests are likely to need removing the explicit device clean-ups when proper APIs are finished.
Yours,
-- Matti
Signature · 5 lines
Matti Vaittinen Linux kernel developer at ROHM Semiconductors Oulu Finland ~~ When things go utterly wrong vim users can always type :help! ~~
Re: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
Quoted 39 lines · Matti Vaittinen
Quoted 37 lines · Matti Vaittinen
Quoted 36 lines · David Gow
Quoted 12 lines · Matti Vaittinen
Quoted 7 lines · David Gow
On Fri, 24 Mar 2023 at 14:11, Matti Vaittinen
<[email protected]> wrote:I think that sounds like a good strategy for now, and we can work on a set of 'generic helpers' which have an associated bus and struct
kunit_devicein the meantime. If we can continue to useroot_device_registeruntil those are ready, that'd be very convenient.Would it be a tiny bit more acceptable if we did add a very simple:
Quoted 9 lines
#define
kunit_root_device_register(name)root_device_register(name)#definekunit_root_device_unregister(dev)root_device_unregister(dev)to
include/kunit/device.h(or somesuch)This should help us later to at least spot the places where root_device_[un]register() is abused and (potentially mass-)covert them to use the proper helpers when they're available.
Great idea.
The code I've been playing with has the following in
include/kunit/device.h:/* Register a new device against a KUnit test. */
struct device *kunit_device_register(struct kunit *test, const char *name);
/* Unregister a device created bykunit_device_register()early (i.e., before test cleanup). */
voidkunit_device_unregister(struct kunit *test, struct device *dev);
Quoted 9 lines
Quoted 4 lines
Quoted 4 lines
If we used the same names, and just forwarded them to
root_device_register()androot_device_unregister()for now (discarding the struct kunit pointer), then I expect we could just swap out the implementation to gain the extra functionality.There's one thing though. If the goal is to do a direct replacement and if automatic device deletion upon test completion / test abort is planned - then it should be there also for these initial wrappers.
Yeah, that's an excellent point. It's a pretty subtle change in behaviour to suddenly introduce that, so changing it behind the scenes is probably unwise.
Quoted 5 lines
If these wrappers don't yet include the automatic device clean-up - then it probably makes more sense to just do the kunit_root_device_* defines because the tests are likely to need removing the explicit device clean-ups when proper APIs are finished.
I sent out my prototype implementation of this here, which does do the automatic cleanup:
https://lore.kernel.org/linux-kselftest/[email protected]/T/#mf797239a8bce11630875fdf60aab9ed627add1f0
It's probably overkill to squeeze into your patch series, though, given it also adds and uses a whole new kunit_defer() API.
Cheers,
-- David
Matti Vaittinen
maintainerRe: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
Quoted 60 lines · David Gow
Quoted 39 lines · Matti Vaittinen
Quoted 37 lines · Matti Vaittinen
Quoted 36 lines · David Gow
Quoted 12 lines · Matti Vaittinen
Quoted 7 lines · David Gow
On Fri, 24 Mar 2023 at 14:11, Matti Vaittinen
<[email protected]> wrote:I think that sounds like a good strategy for now, and we can work on a set of 'generic helpers' which have an associated bus and struct
kunit_devicein the meantime. If we can continue to useroot_device_registeruntil those are ready, that'd be very convenient.Would it be a tiny bit more acceptable if we did add a very simple:
Quoted 9 lines
#define
kunit_root_device_register(name)root_device_register(name)#definekunit_root_device_unregister(dev)root_device_unregister(dev)to
include/kunit/device.h(or somesuch)This should help us later to at least spot the places where root_device_[un]register() is abused and (potentially mass-)covert them to use the proper helpers when they're available.
Great idea.
The code I've been playing with has the following in
include/kunit/device.h:/* Register a new device against a KUnit test. */
struct device *kunit_device_register(struct kunit *test, const char *name);
/* Unregister a device created bykunit_device_register()early (i.e., before test cleanup). */
voidkunit_device_unregister(struct kunit *test, struct device *dev);Quoted 9 lines
Quoted 4 lines
Quoted 4 lines
If we used the same names, and just forwarded them to
root_device_register()androot_device_unregister()for now (discarding the struct kunit pointer), then I expect we could just swap out the implementation to gain the extra functionality.There's one thing though. If the goal is to do a direct replacement and if automatic device deletion upon test completion / test abort is planned - then it should be there also for these initial wrappers.
Yeah, that's an excellent point. It's a pretty subtle change in behaviour to suddenly introduce that, so changing it behind the scenes is probably unwise.
Quoted 5 lines
If these wrappers don't yet include the automatic device clean-up - then it probably makes more sense to just do the kunit_root_device_* defines because the tests are likely to need removing the explicit device clean-ups when proper APIs are finished.
Quoted 6 lines
I sent out my prototype implementation of this here, which does do the automatic cleanup:
https://lore.kernel.org/linux-kselftest/[email protected]/T/#mf797239a8bce11630875fdf60aab9ed627add1f0It's probably overkill to squeeze into your patch series, though, given it also adds and uses a whole new
kunit_defer()API.
Thanks for letting me know. I did also prepare this commit yesterday:
https://github.com/M-Vaittinen/linux/commit/b784a90f8cc64ff83e802ec818e662fae1d0c264
It does use the existing kunit resources for clean-up. I am not sure if it is worth a shot or should I just drop it and use the root-device API for now. Any educated opinions on that? :)
Yours,
-- Matti
Signature · 5 lines
Matti Vaittinen Linux kernel developer at ROHM Semiconductors Oulu Finland ~~ When things go utterly wrong vim users can always type :help! ~~
Re: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
In reply to David GowQuoted 66 lines · David Gow
Quoted 22 lines · Matti Vaittinen
Quoted 20 lines · Maxime Ripard
Quoted 10 lines · Matti Vaittinen
Quoted 4 lines · Maxime Ripard
On Thu, Mar 23, 2023 at 02:16:52PM +0200, Matti Vaittinen wrote:
This is the description of what was happening:
https://lore.kernel.org/dri-devel/20221117165311.vovrc7usy4efiytl@houat/Thanks Maxime. Do I read this correcty. The
devm_unwinding not being done whenroot_device_register()is used is not becauseroot_device_unregister()would not trigger the unwinding - but rather because DRM code on top of this device keeps the refcount increased?There's a difference of behaviour between a
root_deviceand any device with a bus: theroot_devicewill only release the devm resources when it's freed (indevice_release), but a bus device will also do it indevice_del(throughbus_remove_device()->device_release_driver()->device_release_driver_internal()->__device_release_driver()->device_unbind_cleanup(), which are skipped (in multiple places) if there's no bus and no driver attached to the device).Quoted 8 lines
Quoted 5 lines
It does affect DRM, but I'm pretty sure it will affect any framework that deals with device hotplugging by deferring the framework structure until the last (userspace) user closes its file descriptor. So I'd assume that v4l2 and cec at least are also affected, and most likely others.
Thanks for the explanation and patience :)
Thanks from me as well -- this has certainly helped me understand some of the details of the driver model that had slipped past me.
Quoted 14 lines
Quoted 5 lines
Quoted 2 lines
If this is the case, then it sounds like a DRM specific issue to me.
I mean, I guess. One could also argue that it's because IIO doesn't properly deal with hotplugging.
I must say I haven't been testing the IIO registration API. I've only tested the helper API which is not backed up by any "IIO device". (This is fine for the helper because it must by design be cleaned-up only after the IIO-deregistration).
After your explanation here, I am not convinced IIO wouldn't see the same issue if I was testing the
devm_iio_device_alloc()& co.Quoted 8 lines
Quoted 2 lines
I'm not sure how that helps. Those are
common helpers which should accommodate every framework,Ok. Fair enough. Besides, if the root-device was sufficient - then I would actually not see the need for a helper. People could in that case directly use the
root_device_register(). So, if helpers are provided they should be backed up by a device with a bus then.I think there is _some_ value in helpers even without a bus, but it's much more limited:
- It's less confusing if KUnit test devices are using kunit labelled structs and functions.
- Helpers could use KUnit's resource management API to ensure any device created is properly unregistered and removed when the test exits (particularly if it exits early due to, e.g., an assertion).
Quoted 4 lines
I've played around implementing those with a proper struct
kunit_deviceand the automatic cleanup on test failure, and thus far it -- likeroot_device_register-- works for all of the tests except the drm-test-managed one.
Yeah, like I said you need a device that has been bound to a driver for it to work at the moment.
I guess for driver mocks we could move to a setup where we get kunit-specific drivers like what Stephen has been implementing for the clocks but I guess we would need to register the kunit tests in the driver probe which doesn't look like it's possible at the moment?
Maxime
Re: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
In reply to Matti VaittinenQuoted 35 lines · Matti Vaittinen
Quoted 20 lines · Maxime Ripard
Quoted 10 lines · Matti Vaittinen
Quoted 4 lines · Maxime Ripard
On Thu, Mar 23, 2023 at 02:16:52PM +0200, Matti Vaittinen wrote:
This is the description of what was happening:
https://lore.kernel.org/dri-devel/20221117165311.vovrc7usy4efiytl@houat/Thanks Maxime. Do I read this correcty. The
devm_unwinding not being done whenroot_device_register()is used is not becauseroot_device_unregister()would not trigger the unwinding - but rather because DRM code on top of this device keeps the refcount increased?There's a difference of behaviour between a
root_deviceand any device with a bus: theroot_devicewill only release the devm resources when it's freed (indevice_release), but a bus device will also do it indevice_del(throughbus_remove_device()->device_release_driver()->device_release_driver_internal()->__device_release_driver()->device_unbind_cleanup(), which are skipped (in multiple places) if there's no bus and no driver attached to the device).Quoted 5 lines
It does affect DRM, but I'm pretty sure it will affect any framework that deals with device hotplugging by deferring the framework structure until the last (userspace) user closes its file descriptor. So I'd assume that v4l2 and cec at least are also affected, and most likely others.
Thanks for the explanation and patience :)
Quoted 5 lines
Quoted 2 lines
If this is the case, then it sounds like a DRM specific issue to me.
I mean, I guess. One could also argue that it's because IIO doesn't properly deal with hotplugging.
Quoted 7 lines
I must say I haven't been testing the IIO registration API. I've only tested the helper API which is not backed up by any "IIO device". (This is fine for the helper because it must by design be cleaned-up only after the IIO-deregistration).
After your explanation here, I am not convinced IIO wouldn't see the same issue if I was testing the
devm_iio_device_alloc()& co.
It depends really. The issue DRM is trying to solve is that, when a device is gone, some application might still have an open FD and could still poke into the kernel, while all the resources would have been free'd if it was using devm.
So everything is kept around until the last fd is closed, so you still have a reference to the device (even though it's been removed from its bus) until that time.
It could be possible that IIO just doesn't handle that case at all. I guess most of the devices aren't hotpluggable, and there's not much to interact with from a userspace PoV iirc, so it might be why.
Quoted 32 lines
Quoted 2 lines
I'm not sure how that helps. Those are
common helpers which should accommodate every framework,Ok. Fair enough. Besides, if the root-device was sufficient - then I would actually not see the need for a helper. People could in that case directly use the
root_device_register(). So, if helpers are provided they should be backed up by a device with a bus then.Quoted 2 lines
and your second
patch breaks the kunit tests for DRM anyway.Oh, I must have made an error there. It was supposed to be just a refactoring with no functional changes. Sorry about that. Anyways, that patch can be forgotten as Greg opposes using the platform devices in generic helpers.
Quoted 8 lines
Quoted 7 lines
Whether it is a feature or bug is beyond my knowledge. Still, I would not say using the root_device_[un]register() in generic code is not feasible - unless all other subsytems have similar refcount handling.
Sure thing using
root_device_register()root_device_unregister()in DRM does not work as such. This, however, does not mean the generic kunit helpers should useplatform_devicesto force unwinding?Quoted 7 lines
platform_deviceswere a quick way to get a device that would have a bus and a driver bound to fall into the right patch above. We probably shouldn't useplatform_devicesand akunit_devicesounds like the best idea, but the test linked in the original mail I pointed you to should work with whatever we come up with. It works with multiple (platform, PCI, USB, etc) buses, so the mock we create should behave like their real world equivalents.
Quoted 5 lines
Thanks for the patience and the explanation. Now I understand a generic test device needs to sit on a bus.
As I said, in my very specific IIO related test the test device does not need a bus. Hence I'll drop the 'generic helpers' from this series.
So, I went around and created a bunch of kunit tests that shows the problem without DRM being involved at all.
It does three things:
- It registers a device, attaches a devm action, unregisters the device and then checks that the action has ran.
- It registers a device, gets a reference to it, attaches a devm action, puts back the reference, unregisters the device and then checks that the action has ran.
- It registers a device, gets a reference to it, attaches a devm action that will put back the reference, unregisters the device and then checks that the action has ran.
And in three cases: first with a root_device, then platform_device, then a platform_device that has been bound to a driver.
Once you've applied that patch, you can run it using:
./tools/testing/kunit/kunit.py run --kunitconfig=drivers/base/test/ devm-inconsistencies
You'll see that only the last case passes all the tests, even though the code itself is exactly the same.
Maxime
-- >8 --
drivers/base/test/.kunitconfig new file +2 -0
@@ -0,0 +1,2 @@ +CONFIG_KUNIT=y +CONFIG_DM_KUNIT_TEST=y
drivers/base/test/Kconfig +4 -0
@@ -9,6 +9,10 @@ config TEST_ASYNC_DRIVER_PROBE If unsure say N. +config DM_KUNIT_TEST + tristate "KUnit Tests for the device model" if !KUNIT_ALL_TESTS + depends on KUNIT + config DRIVER_PE_KUNIT_TEST bool "KUnit Tests for property entry API" if !KUNIT_ALL_TESTS depends on KUNIT=y
drivers/base/test/Makefile +2 -0
@@ -1,5 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_TEST_ASYNC_DRIVER_PROBE) += test_async_driver_probe.o +obj-$(CONFIG_DM_KUNIT_TEST) += test-devm-cleanup.o + obj-$(CONFIG_DRIVER_PE_KUNIT_TEST) += property-entry-test.o CFLAGS_property-entry-test.o += $(DISABLE_STRUCTLEAK_PLUGIN)
drivers/base/test/test-devm-cleanup.c new file +353 -0
353 lines not on this page · raw message
-- >8 --
Re: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
Quoted 115 lines · Maxime Ripard
Quoted 35 lines · Matti Vaittinen
Quoted 20 lines · Maxime Ripard
Quoted 10 lines · Matti Vaittinen
Quoted 4 lines · Maxime Ripard
On Thu, Mar 23, 2023 at 02:16:52PM +0200, Matti Vaittinen wrote:
This is the description of what was happening:
https://lore.kernel.org/dri-devel/20221117165311.vovrc7usy4efiytl@houat/Thanks Maxime. Do I read this correcty. The
devm_unwinding not being done whenroot_device_register()is used is not becauseroot_device_unregister()would not trigger the unwinding - but rather because DRM code on top of this device keeps the refcount increased?There's a difference of behaviour between a
root_deviceand any device with a bus: theroot_devicewill only release the devm resources when it's freed (indevice_release), but a bus device will also do it indevice_del(throughbus_remove_device()->device_release_driver()->device_release_driver_internal()->__device_release_driver()->device_unbind_cleanup(), which are skipped (in multiple places) if there's no bus and no driver attached to the device).Quoted 5 lines
It does affect DRM, but I'm pretty sure it will affect any framework that deals with device hotplugging by deferring the framework structure until the last (userspace) user closes its file descriptor. So I'd assume that v4l2 and cec at least are also affected, and most likely others.
Thanks for the explanation and patience :)
Quoted 5 lines
Quoted 2 lines
If this is the case, then it sounds like a DRM specific issue to me.
I mean, I guess. One could also argue that it's because IIO doesn't properly deal with hotplugging.
Quoted 7 lines
I must say I haven't been testing the IIO registration API. I've only tested the helper API which is not backed up by any "IIO device". (This is fine for the helper because it must by design be cleaned-up only after the IIO-deregistration).
After your explanation here, I am not convinced IIO wouldn't see the same issue if I was testing the
devm_iio_device_alloc()& co.It depends really. The issue DRM is trying to solve is that, when a device is gone, some application might still have an open FD and could still poke into the kernel, while all the resources would have been free'd if it was using devm.
So everything is kept around until the last fd is closed, so you still have a reference to the device (even though it's been removed from its bus) until that time.
It could be possible that IIO just doesn't handle that case at all. I guess most of the devices aren't hotpluggable, and there's not much to interact with from a userspace PoV iirc, so it might be why.
Quoted 32 lines
Quoted 2 lines
I'm not sure how that helps. Those are
common helpers which should accommodate every framework,Ok. Fair enough. Besides, if the root-device was sufficient - then I would actually not see the need for a helper. People could in that case directly use the
root_device_register(). So, if helpers are provided they should be backed up by a device with a bus then.Quoted 2 lines
and your second
patch breaks the kunit tests for DRM anyway.Oh, I must have made an error there. It was supposed to be just a refactoring with no functional changes. Sorry about that. Anyways, that patch can be forgotten as Greg opposes using the platform devices in generic helpers.
Quoted 8 lines
Quoted 7 lines
Whether it is a feature or bug is beyond my knowledge. Still, I would not say using the root_device_[un]register() in generic code is not feasible - unless all other subsytems have similar refcount handling.
Sure thing using
root_device_register()root_device_unregister()in DRM does not work as such. This, however, does not mean the generic kunit helpers should useplatform_devicesto force unwinding?Quoted 7 lines
platform_deviceswere a quick way to get a device that would have a bus and a driver bound to fall into the right patch above. We probably shouldn't useplatform_devicesand akunit_devicesounds like the best idea, but the test linked in the original mail I pointed you to should work with whatever we come up with. It works with multiple (platform, PCI, USB, etc) buses, so the mock we create should behave like their real world equivalents.Quoted 5 lines
Thanks for the patience and the explanation. Now I understand a generic test device needs to sit on a bus.
As I said, in my very specific IIO related test the test device does not need a bus. Hence I'll drop the 'generic helpers' from this series.
So, I went around and created a bunch of kunit tests that shows the problem without DRM being involved at all.
It does three things:
- It registers a device, attaches a devm action, unregisters the device and then checks that the action has ran.
- It registers a device, gets a reference to it, attaches a devm action, puts back the reference, unregisters the device and then checks that the action has ran.
- It registers a device, gets a reference to it, attaches a devm action that will put back the reference, unregisters the device and then checks that the action has ran.
And in three cases: first with a
root_device, thenplatform_device, then aplatform_devicethat has been bound to a driver.
Quoted 7 lines
Once you've applied that patch, you can run it using:
./tools/testing/kunit/kunit.pyrun --kunitconfig=drivers/base/test/ devm-inconsistenciesYou'll see that only the last case passes all the tests, even though the code itself is exactly the same.
This illustrates the problem very nicely, thanks.
I played around a bit with this, and I'm definitely leaning towards this being a bug, rather than intentional behaviour. There's actually an explicit call to devres_release_all() in device_release() which seems to suggest that this should work:
/*
* Some platform devices are driven without driver attached
* and managed resources may have been acquired. Make sure
* all resources are released.
*
* Drivers still can add resources into device after device
* is deleted but alive, so release devres here to avoid
* possible memory leak.
*/
My "solution" is just to call devres_release_all() in device_del() as well, which fixes your tests (and the drm-test-managed one when ported to use root_device_register() or my kunit_device_register() API[1]).
--8<--
drivers/base/core.c +11 -0
@@ -3778,6 +3778,17 @@ void device_del(struct device *dev)device_platform_notify_remove (dev);device_links_purge (dev); +/* +* If a device does not have a driver attached, we need to clean up any +* managed resources. We do this in device_release(), but it's never +* called (and we leak the device) if a managed resource holds a +* reference to the device. So release all managed resources here, +* like we do in driver_detach(). We still need to do so again in +* device_release() in case someone adds a new resource after this +* point, though. +*/ +devres_release_all (dev); +bus_notify (dev,BUS_NOTIFY_REMOVED_DEVICE );kobject_uevent (&dev->kobj,KOBJ_REMOVE ); glue_dir =get_glue_dir (dev);
-->8--
It doesn't _seem_ to break anything else, and I've managed to convince myself that it's probably the correct fix. (Albeit, as someone with a limited knowledge of this part of the code, who also hasn't had quite enough sleep, so take that with some salt.)
Still, I'd agree with Greg that it'd be great to have versions of your tests upstream before making any such radical changes.
Cheers,
-- David
Re: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
Hi David,
Quoted 170 lines · David Gow
Quoted 115 lines · Maxime Ripard
Quoted 35 lines · Matti Vaittinen
Quoted 20 lines · Maxime Ripard
Quoted 10 lines · Matti Vaittinen
Quoted 4 lines · Maxime Ripard
On Thu, Mar 23, 2023 at 02:16:52PM +0200, Matti Vaittinen wrote:
This is the description of what was happening:
https://lore.kernel.org/dri-devel/20221117165311.vovrc7usy4efiytl@houat/Thanks Maxime. Do I read this correcty. The
devm_unwinding not being done whenroot_device_register()is used is not becauseroot_device_unregister()would not trigger the unwinding - but rather because DRM code on top of this device keeps the refcount increased?There's a difference of behaviour between a
root_deviceand any device with a bus: theroot_devicewill only release the devm resources when it's freed (indevice_release), but a bus device will also do it indevice_del(throughbus_remove_device()->device_release_driver()->device_release_driver_internal()->__device_release_driver()->device_unbind_cleanup(), which are skipped (in multiple places) if there's no bus and no driver attached to the device).Quoted 5 lines
It does affect DRM, but I'm pretty sure it will affect any framework that deals with device hotplugging by deferring the framework structure until the last (userspace) user closes its file descriptor. So I'd assume that v4l2 and cec at least are also affected, and most likely others.
Thanks for the explanation and patience :)
Quoted 5 lines
Quoted 2 lines
If this is the case, then it sounds like a DRM specific issue to me.
I mean, I guess. One could also argue that it's because IIO doesn't properly deal with hotplugging.
Quoted 7 lines
I must say I haven't been testing the IIO registration API. I've only tested the helper API which is not backed up by any "IIO device". (This is fine for the helper because it must by design be cleaned-up only after the IIO-deregistration).
After your explanation here, I am not convinced IIO wouldn't see the same issue if I was testing the
devm_iio_device_alloc()& co.It depends really. The issue DRM is trying to solve is that, when a device is gone, some application might still have an open FD and could still poke into the kernel, while all the resources would have been free'd if it was using devm.
So everything is kept around until the last fd is closed, so you still have a reference to the device (even though it's been removed from its bus) until that time.
It could be possible that IIO just doesn't handle that case at all. I guess most of the devices aren't hotpluggable, and there's not much to interact with from a userspace PoV iirc, so it might be why.
Quoted 32 lines
Quoted 2 lines
I'm not sure how that helps. Those are
common helpers which should accommodate every framework,Ok. Fair enough. Besides, if the root-device was sufficient - then I would actually not see the need for a helper. People could in that case directly use the
root_device_register(). So, if helpers are provided they should be backed up by a device with a bus then.Quoted 2 lines
and your second
patch breaks the kunit tests for DRM anyway.Oh, I must have made an error there. It was supposed to be just a refactoring with no functional changes. Sorry about that. Anyways, that patch can be forgotten as Greg opposes using the platform devices in generic helpers.
Quoted 8 lines
Quoted 7 lines
Whether it is a feature or bug is beyond my knowledge. Still, I would not say using the root_device_[un]register() in generic code is not feasible - unless all other subsytems have similar refcount handling.
Sure thing using
root_device_register()root_device_unregister()in DRM does not work as such. This, however, does not mean the generic kunit helpers should useplatform_devicesto force unwinding?Quoted 7 lines
platform_deviceswere a quick way to get a device that would have a bus and a driver bound to fall into the right patch above. We probably shouldn't useplatform_devicesand akunit_devicesounds like the best idea, but the test linked in the original mail I pointed you to should work with whatever we come up with. It works with multiple (platform, PCI, USB, etc) buses, so the mock we create should behave like their real world equivalents.Quoted 5 lines
Thanks for the patience and the explanation. Now I understand a generic test device needs to sit on a bus.
As I said, in my very specific IIO related test the test device does not need a bus. Hence I'll drop the 'generic helpers' from this series.
So, I went around and created a bunch of kunit tests that shows the problem without DRM being involved at all.
It does three things:
- It registers a device, attaches a devm action, unregisters the device and then checks that the action has ran.
- It registers a device, gets a reference to it, attaches a devm action, puts back the reference, unregisters the device and then checks that the action has ran.
- It registers a device, gets a reference to it, attaches a devm action that will put back the reference, unregisters the device and then checks that the action has ran.
And in three cases: first with a
root_device, thenplatform_device, then aplatform_devicethat has been bound to a driver.Quoted 7 lines
Once you've applied that patch, you can run it using:
./tools/testing/kunit/kunit.pyrun --kunitconfig=drivers/base/test/ devm-inconsistenciesYou'll see that only the last case passes all the tests, even though the code itself is exactly the same.
This illustrates the problem very nicely, thanks.
I played around a bit with this, and I'm definitely leaning towards this being a bug, rather than intentional behaviour. There's actually an explicit call to
devres_release_all()indevice_release()which seems to suggest that this should work:
/*
* Some platform devices are driven without driver attached
* and managed resources may have been acquired. Make sure
* all resources are released.
*
* Drivers still can add resources into device after device
* is deleted but alive, so release devres here to avoid
* possible memory leak.
*/My "solution" is just to call
devres_release_all()indevice_del()as well, which fixes your tests (and the drm-test-managed one when ported to useroot_device_register()or mykunit_device_register()API[1]).--8<--
drivers/base/core.c +11
-1@@ -3778,6 +3778,17 @@ void device_del(struct device *dev)device_platform_notify_remove (dev);device_links_purge (dev); +/* +* If a device does not have a driver attached, we need to clean up any +* managed resources. We do this in device_release(), but it's never +* called (and we leak the device) if a managed resource holds a +* reference to the device. So release all managed resources here, +* like we do in driver_detach(). We still need to do so again in +* device_release() in case someone adds a new resource after this +* point, though. +*/ +devres_release_all (dev); +bus_notify (dev,BUS_NOTIFY_REMOVED_DEVICE );kobject_uevent (&dev->kobj,KOBJ_REMOVE ); glue_dir =get_glue_dir (dev); -->8--
Quoted 2 lines
It doesn't _seem_ to break anything else, and I've managed to convince myself that it's probably the correct fix.
Yeah, as an outsider, I came to the same conclusion last time...
Quoted 2 lines
(Albeit, as someone with a limited knowledge of this part of the code, who also hasn't had quite enough sleep, so take that with some salt.)
... but as someone that also have a limited knowledge of that part of the code, I certainly wasn't sure it was the proper thing to do :)
Quoted 2 lines
Still, I'd agree with Greg that it'd be great to have versions of your tests upstream before making any such radical changes.
I just submitted them.
Thanks!
Maxime
Jonathan Cameron
maintainerRe: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
In reply to Maxime RipardQuoted 49 lines · On Fri, 24 Mar 2023 13:31:57 +0100 Maxime Ripard <[email protected]> wrote:
Quoted 35 lines · Matti Vaittinen
Quoted 20 lines · Maxime Ripard
Quoted 10 lines · Matti Vaittinen
Quoted 4 lines · Maxime Ripard
On Thu, Mar 23, 2023 at 02:16:52PM +0200, Matti Vaittinen wrote:
This is the description of what was happening:
https://lore.kernel.org/dri-devel/20221117165311.vovrc7usy4efiytl@houat/Thanks Maxime. Do I read this correcty. The
devm_unwinding not being done whenroot_device_register()is used is not becauseroot_device_unregister()would not trigger the unwinding - but rather because DRM code on top of this device keeps the refcount increased?There's a difference of behaviour between a
root_deviceand any device with a bus: theroot_devicewill only release the devm resources when it's freed (indevice_release), but a bus device will also do it indevice_del(throughbus_remove_device()->device_release_driver()->device_release_driver_internal()->__device_release_driver()->device_unbind_cleanup(), which are skipped (in multiple places) if there's no bus and no driver attached to the device).Quoted 5 lines
It does affect DRM, but I'm pretty sure it will affect any framework that deals with device hotplugging by deferring the framework structure until the last (userspace) user closes its file descriptor. So I'd assume that v4l2 and cec at least are also affected, and most likely others.
Thanks for the explanation and patience :)
Quoted 5 lines
Quoted 2 lines
If this is the case, then it sounds like a DRM specific issue to me.
I mean, I guess. One could also argue that it's because IIO doesn't properly deal with hotplugging.
Quoted 7 lines
I must say I haven't been testing the IIO registration API. I've only tested the helper API which is not backed up by any "IIO device". (This is fine for the helper because it must by design be cleaned-up only after the IIO-deregistration).
After your explanation here, I am not convinced IIO wouldn't see the same issue if I was testing the
devm_iio_device_alloc()& co.It depends really. The issue DRM is trying to solve is that, when a device is gone, some application might still have an open FD and could still poke into the kernel, while all the resources would have been free'd if it was using devm.
Quoted 7 lines
So everything is kept around until the last fd is closed, so you still have a reference to the device (even though it's been removed from its bus) until that time.
It could be possible that IIO just doesn't handle that case at all. I guess most of the devices aren't hotpluggable, and there's not much to interact with from a userspace PoV iirc, so it might be why.
Lars-Peter Clausen (IIRC) fixed up the IIO handling of the similar cases a long time ago now. It's simpler that for some other subsystems as we don't have as many interdependencies as occur in DRM etc.
I 'think' we are fine in general with the IIO approach to this (I think we did have one report of a theoretical race condition in the remove path that was never fully addressed).
For IIO we also have fds that can be open but all accesses to them are proxied through the IIO core and one of the things iio_device_unregister() or the devm equivalent does is to set indio_dev->info = NULL (+ wake up anyone waiting on data etc). Alongside removing the callbacks, that is also used as a flag to indicate the device has gone.
Note that we keep a reference to the struct indio_dev->dev (rather that the underlying device) so that is not freed until the last fd is closed. Thus, although devm unwinding has occurred that doesn't mean all the data that was allocated with devm_xx calls is cleared up immediately.
Re: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
Quoted 67 lines · Jonathan Cameron
Quoted 43 lines · On Fri, 24 Mar 2023 13:31:57 +0100 Maxime Ripard <[email protected]> wrote:
Quoted 30 lines · Matti Vaittinen
Quoted 18 lines · Maxime Ripard
Quoted 9 lines · Matti Vaittinen
Quoted 4 lines · Maxime Ripard
On Thu, Mar 23, 2023 at 02:16:52PM +0200, Matti Vaittinen wrote:
This is the description of what was happening:
https://lore.kernel.org/dri-devel/20221117165311.vovrc7usy4efiytl@houat/Thanks Maxime. Do I read this correcty. The
devm_unwinding not being done whenroot_device_register()is used is not becauseroot_device_unregister()would not trigger the unwinding - but rather because DRM code on top of this device keeps the refcount increased?There's a difference of behaviour between a
root_deviceand any device with a bus: theroot_devicewill only release the devm resources when it's freed (indevice_release), but a bus device will also do it indevice_del(throughbus_remove_device()->device_release_driver()->device_release_driver_internal()->__device_release_driver()->device_unbind_cleanup(), which are skipped (in multiple places) if there's no bus and no driver attached to the device).Quoted 5 lines
It does affect DRM, but I'm pretty sure it will affect any framework that deals with device hotplugging by deferring the framework structure until the last (userspace) user closes its file descriptor. So I'd assume that v4l2 and cec at least are also affected, and most likely others.
Thanks for the explanation and patience :)
Quoted 4 lines
Quoted 2 lines
If this is the case, then it sounds like a DRM specific issue to me.
I mean, I guess. One could also argue that it's because IIO doesn't properly deal with hotplugging.
Quoted 7 lines
I must say I haven't been testing the IIO registration API. I've only tested the helper API which is not backed up by any "IIO device". (This is fine for the helper because it must by design be cleaned-up only after the IIO-deregistration).
After your explanation here, I am not convinced IIO wouldn't see the same issue if I was testing the
devm_iio_device_alloc()& co.It depends really. The issue DRM is trying to solve is that, when a device is gone, some application might still have an open FD and could still poke into the kernel, while all the resources would have been free'd if it was using devm.
Quoted 7 lines
So everything is kept around until the last fd is closed, so you still have a reference to the device (even though it's been removed from its bus) until that time.
It could be possible that IIO just doesn't handle that case at all. I guess most of the devices aren't hotpluggable, and there's not much to interact with from a userspace PoV iirc, so it might be why.
Lars-Peter Clausen (IIRC) fixed up the IIO handling of the similar cases a long time ago now. It's simpler that for some other subsystems as we don't have as many interdependencies as occur in DRM etc.
I 'think' we are fine in general with the IIO approach to this (I think we did have one report of a theoretical race condition in the remove path that was never fully addressed).
For IIO we also have fds that can be open but all accesses to them are proxied through the IIO core and one of the things
iio_device_unregister()or the devm equivalent does is to setindio_dev->info= NULL (+ wake up anyone waiting on data etc). Alongside removing the callbacks, that is also used as a flag to indicate the device has gone.
Quoted 4 lines
Note that we keep a reference to the struct
indio_dev->dev(rather that the underlying device) so that is not freed until the last fd is closed. Thus, although devm unwinding has occurred that doesn't mean all the data that was allocated withdevm_xxcalls is cleared up immediately.
IIO is fully hot-plug and hot-unplug capable. And it will have the same issue. When using managed device registration that establishes a parent child relationship between the devices and in combination with a device where the managed unwinding does not happen on unbind, but rather on in the release callback you create a cyclic reference dependency. The child device holds a reference to the parent, but the reference is only released in the parents release callback. And since that release callback is not called until the last reference is dropped you end up with a resource leak.
There are even some other places where IIO drivers run into this. E.g. any driver that does devm_iio_trigger_register(&indio_dev->dev, ...) creates a resource leak on the trigger and the IIO device. The indio_dev is not a bus device, hence no unbind and the trigger holds a reference so the release callback will never be called either.
Jonathan Cameron
maintainerRe: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
Quoted 83 lines · On Sun, 26 Mar 2023 10:16:54 -0700 Lars-Peter Clausen <[email protected]> wrote:
Quoted 67 lines · Jonathan Cameron
Quoted 43 lines · On Fri, 24 Mar 2023 13:31:57 +0100 Maxime Ripard <[email protected]> wrote:
Quoted 30 lines · Matti Vaittinen
Quoted 18 lines · Maxime Ripard
Quoted 9 lines · Matti Vaittinen
Quoted 4 lines · Maxime Ripard
On Thu, Mar 23, 2023 at 02:16:52PM +0200, Matti Vaittinen wrote:
This is the description of what was happening:
https://lore.kernel.org/dri-devel/20221117165311.vovrc7usy4efiytl@houat/Thanks Maxime. Do I read this correcty. The
devm_unwinding not being done whenroot_device_register()is used is not becauseroot_device_unregister()would not trigger the unwinding - but rather because DRM code on top of this device keeps the refcount increased?There's a difference of behaviour between a
root_deviceand any device with a bus: theroot_devicewill only release the devm resources when it's freed (indevice_release), but a bus device will also do it indevice_del(throughbus_remove_device()->device_release_driver()->device_release_driver_internal()->__device_release_driver()->device_unbind_cleanup(), which are skipped (in multiple places) if there's no bus and no driver attached to the device).Quoted 5 lines
It does affect DRM, but I'm pretty sure it will affect any framework that deals with device hotplugging by deferring the framework structure until the last (userspace) user closes its file descriptor. So I'd assume that v4l2 and cec at least are also affected, and most likely others.
Thanks for the explanation and patience :)
Quoted 4 lines
Quoted 2 lines
If this is the case, then it sounds like a DRM specific issue to me.
I mean, I guess. One could also argue that it's because IIO doesn't properly deal with hotplugging.
Quoted 7 lines
I must say I haven't been testing the IIO registration API. I've only tested the helper API which is not backed up by any "IIO device". (This is fine for the helper because it must by design be cleaned-up only after the IIO-deregistration).
After your explanation here, I am not convinced IIO wouldn't see the same issue if I was testing the
devm_iio_device_alloc()& co.It depends really. The issue DRM is trying to solve is that, when a device is gone, some application might still have an open FD and could still poke into the kernel, while all the resources would have been free'd if it was using devm.
Quoted 7 lines
So everything is kept around until the last fd is closed, so you still have a reference to the device (even though it's been removed from its bus) until that time.
It could be possible that IIO just doesn't handle that case at all. I guess most of the devices aren't hotpluggable, and there's not much to interact with from a userspace PoV iirc, so it might be why.
Lars-Peter Clausen (IIRC) fixed up the IIO handling of the similar cases a long time ago now. It's simpler that for some other subsystems as we don't have as many interdependencies as occur in DRM etc.
I 'think' we are fine in general with the IIO approach to this (I think we did have one report of a theoretical race condition in the remove path that was never fully addressed).
For IIO we also have fds that can be open but all accesses to them are proxied through the IIO core and one of the things
iio_device_unregister()or the devm equivalent does is to setindio_dev->info= NULL (+ wake up anyone waiting on data etc). Alongside removing the callbacks, that is also used as a flag to indicate the device has gone.Quoted 4 lines
Note that we keep a reference to the struct
indio_dev->dev(rather that the underlying device) so that is not freed until the last fd is closed. Thus, although devm unwinding has occurred that doesn't mean all the data that was allocated withdevm_xxcalls is cleared up immediately.IIO is fully hot-plug and hot-unplug capable. And it will have the same issue. When using managed device registration that establishes a parent child relationship between the devices and in combination with a device where the managed unwinding does not happen on unbind, but rather on in the release callback you create a cyclic reference dependency. The child device holds a reference to the parent, but the reference is only released in the parents release callback. And since that release callback is not called until the last reference is dropped you end up with a resource leak.
Quoted 2 lines
There are even some other places where IIO drivers run into this. E.g. any driver that does
devm_iio_trigger_register(&indio_dev->dev, ...)
A driver should should not do that.
Should be devm_iio_trigger_registers(parent device, ...)
There is a corner where you need to detach the trigger from userspace before release which is odd if it was attached by default. There are some left over corners there that I think still cause trouble.
Quoted 4 lines
creates a resource leak on the trigger and the IIO device. The
indio_devis not a bus device, hence no unbind and the trigger holds a reference so the release callback will never be called either.
Re: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
In reply to Jonathan CameronQuoted 68 lines · Jonathan Cameron
Quoted 49 lines · On Fri, 24 Mar 2023 13:31:57 +0100 Maxime Ripard <[email protected]> wrote:
Quoted 35 lines · Matti Vaittinen
Quoted 20 lines · Maxime Ripard
Quoted 10 lines · Matti Vaittinen
Quoted 4 lines · Maxime Ripard
On Thu, Mar 23, 2023 at 02:16:52PM +0200, Matti Vaittinen wrote:
This is the description of what was happening:
https://lore.kernel.org/dri-devel/20221117165311.vovrc7usy4efiytl@houat/Thanks Maxime. Do I read this correcty. The
devm_unwinding not being done whenroot_device_register()is used is not becauseroot_device_unregister()would not trigger the unwinding - but rather because DRM code on top of this device keeps the refcount increased?There's a difference of behaviour between a
root_deviceand any device with a bus: theroot_devicewill only release the devm resources when it's freed (indevice_release), but a bus device will also do it indevice_del(throughbus_remove_device()->device_release_driver()->device_release_driver_internal()->__device_release_driver()->device_unbind_cleanup(), which are skipped (in multiple places) if there's no bus and no driver attached to the device).Quoted 5 lines
It does affect DRM, but I'm pretty sure it will affect any framework that deals with device hotplugging by deferring the framework structure until the last (userspace) user closes its file descriptor. So I'd assume that v4l2 and cec at least are also affected, and most likely others.
Thanks for the explanation and patience :)
Quoted 5 lines
Quoted 2 lines
If this is the case, then it sounds like a DRM specific issue to me.
I mean, I guess. One could also argue that it's because IIO doesn't properly deal with hotplugging.
Quoted 7 lines
I must say I haven't been testing the IIO registration API. I've only tested the helper API which is not backed up by any "IIO device". (This is fine for the helper because it must by design be cleaned-up only after the IIO-deregistration).
After your explanation here, I am not convinced IIO wouldn't see the same issue if I was testing the
devm_iio_device_alloc()& co.It depends really. The issue DRM is trying to solve is that, when a device is gone, some application might still have an open FD and could still poke into the kernel, while all the resources would have been free'd if it was using devm.
Quoted 7 lines
So everything is kept around until the last fd is closed, so you still have a reference to the device (even though it's been removed from its bus) until that time.
It could be possible that IIO just doesn't handle that case at all. I guess most of the devices aren't hotpluggable, and there's not much to interact with from a userspace PoV iirc, so it might be why.
Lars-Peter Clausen (IIRC) fixed up the IIO handling of the similar cases a long time ago now. It's simpler that for some other subsystems as we don't have as many interdependencies as occur in DRM etc.
I 'think' we are fine in general with the IIO approach to this (I think we did have one report of a theoretical race condition in the remove path that was never fully addressed).
Quoted 5 lines
For IIO we also have fds that can be open but all accesses to them are proxied through the IIO core and one of the things
iio_device_unregister()or the devm equivalent does is to setindio_dev->info= NULL (+ wake up anyone waiting on data etc). Alongside removing the callbacks, that is also used as a flag to indicate the device has gone.
Sorry if it came as trying to put IIO under a bad light, it certainly wasn't my intention. I was trying to come up with possible explanations as to why IIO's design was simpler than DRM is :)
Quoted 4 lines
Note that we keep a reference to the struct
indio_dev->dev(rather that the underlying device) so that is not freed until the last fd is closed. Thus, although devm unwinding has occurred that doesn't mean all the data that was allocated withdevm_xxcalls is cleared up immediately.
I'm not sure I get that part though. devm unwinding can happen even if the refcount is > 1
Maxime
Jonathan Cameron
maintainerRe: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
Quoted 75 lines · On Wed, 29 Mar 2023 21:46:09 +0200 Maxime Ripard <[email protected]> wrote:
Quoted 68 lines · Jonathan Cameron
Quoted 49 lines · On Fri, 24 Mar 2023 13:31:57 +0100 Maxime Ripard <[email protected]> wrote:
Quoted 35 lines · Matti Vaittinen
Quoted 20 lines · Maxime Ripard
Quoted 10 lines · Matti Vaittinen
Quoted 4 lines · Maxime Ripard
On Thu, Mar 23, 2023 at 02:16:52PM +0200, Matti Vaittinen wrote:
This is the description of what was happening:
https://lore.kernel.org/dri-devel/20221117165311.vovrc7usy4efiytl@houat/Thanks Maxime. Do I read this correcty. The
devm_unwinding not being done whenroot_device_register()is used is not becauseroot_device_unregister()would not trigger the unwinding - but rather because DRM code on top of this device keeps the refcount increased?There's a difference of behaviour between a
root_deviceand any device with a bus: theroot_devicewill only release the devm resources when it's freed (indevice_release), but a bus device will also do it indevice_del(throughbus_remove_device()->device_release_driver()->device_release_driver_internal()->__device_release_driver()->device_unbind_cleanup(), which are skipped (in multiple places) if there's no bus and no driver attached to the device).Quoted 5 lines
It does affect DRM, but I'm pretty sure it will affect any framework that deals with device hotplugging by deferring the framework structure until the last (userspace) user closes its file descriptor. So I'd assume that v4l2 and cec at least are also affected, and most likely others.
Thanks for the explanation and patience :)
Quoted 5 lines
Quoted 2 lines
If this is the case, then it sounds like a DRM specific issue to me.
I mean, I guess. One could also argue that it's because IIO doesn't properly deal with hotplugging.
Quoted 7 lines
I must say I haven't been testing the IIO registration API. I've only tested the helper API which is not backed up by any "IIO device". (This is fine for the helper because it must by design be cleaned-up only after the IIO-deregistration).
After your explanation here, I am not convinced IIO wouldn't see the same issue if I was testing the
devm_iio_device_alloc()& co.It depends really. The issue DRM is trying to solve is that, when a device is gone, some application might still have an open FD and could still poke into the kernel, while all the resources would have been free'd if it was using devm.
Quoted 7 lines
So everything is kept around until the last fd is closed, so you still have a reference to the device (even though it's been removed from its bus) until that time.
It could be possible that IIO just doesn't handle that case at all. I guess most of the devices aren't hotpluggable, and there's not much to interact with from a userspace PoV iirc, so it might be why.
Lars-Peter Clausen (IIRC) fixed up the IIO handling of the similar cases a long time ago now. It's simpler that for some other subsystems as we don't have as many interdependencies as occur in DRM etc.
I 'think' we are fine in general with the IIO approach to this (I think we did have one report of a theoretical race condition in the remove path that was never fully addressed).
Quoted 5 lines
For IIO we also have fds that can be open but all accesses to them are proxied through the IIO core and one of the things
iio_device_unregister()or the devm equivalent does is to setindio_dev->info= NULL (+ wake up anyone waiting on data etc). Alongside removing the callbacks, that is also used as a flag to indicate the device has gone.
Quoted 3 lines
Sorry if it came as trying to put IIO under a bad light, it certainly wasn't my intention. I was trying to come up with possible explanations as to why IIO's design was simpler than DRM is :)
No problem :) I'm sure there are gremlins hiding there.
Part of the problem is that nothing prevents drivers doing 'wrong things' other than us noticing when it happens.
Quoted 7 lines
Quoted 5 lines
Note that we keep a reference to the struct
indio_dev->dev(rather that the underlying device) so that is not freed until the last fd is closed. Thus, although devm unwinding has occurred that doesn't mean all the data that was allocated withdevm_xxcalls is cleared up immediately.I'm not sure I get that part though. devm unwinding can happen even if the refcount is > 1
No IIO driver should be using devm on the indio_dev->dev, they should be doing it on the parent device. When the devm_iio_device_free() gets called, that doesn't actually free the device. Just decrements a reference count (earlier on we already ensured that it is just acting as a stub that provides no access to the underlying device for open FDs.).
There are probably more problems hiding though!
Jonathan
Quoted 2 lines
Maxime
Re: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
In reply to Greg Kroah-HartmanQuoted 29 lines · Greg Kroah-Hartman
Quoted 28 lines · Maxime Ripard
Quoted 26 lines · Greg Kroah-Hartman
Quoted 17 lines
Quoted 9 lines
Quoted 8 lines
+/**
+ *test_kunit_helper_alloc_device- Allocate a mock device for a KUnit test
+ * @test: The test context object
+ *
+ * This allocates a fake struct &device to create a mock for a KUnit
+ * test. The device will also be bound to a fake driver. It will thus be
+ * able to leverage the usual infrastructure and most notably the
+ * device-managed resources just like a "real" device.Quoted 7 lines
What specific "usual infrastructure" are you wanting to access here?
And again, if you want a fake device, make a virtual one, by just calling
device_create().Or are you wanting to do "more" with that device pointer than
device_create()can give you?Quoted 6 lines
Personally, I was (am) only interested in
devm_unwinding. I guess thedevice_create(),device_add(),device_remove()... (didn't study this sequence in details so sorry if there is errors) could've been sufficient for me. I haven't looked how much of the code that there is for 'platform devices' should be duplicated to support that sequence for testability purposes.Any device can access
devm_code, there's no need for it to be a platform device at all.
Quoted 6 lines
Quoted 2 lines
Sure but the resources are only released if the device is part of a bus, so it can't be a
root_device(or bare device) eitherThe resources are not cleaned up when the device is freed no matter if it's on a bus or not? If so, then that's a bug that needs to be fixed, and tested :)
Please have a look at:
https://lore.kernel.org/linux-kselftest/20230324123157.bbwvfq4gsxnlnfwb@houat/
I couldn't get an answer on whether it was considered a bug or not last time, but as you can see there's a clear difference between a root device and a platform device that has probed when it comes to resource cleanup.
Maxime
Greg Kroah-Hartman
maintainerRe: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
Quoted 37 lines · Maxime Ripard
Quoted 29 lines · Greg Kroah-Hartman
Quoted 28 lines · Maxime Ripard
Quoted 26 lines · Greg Kroah-Hartman
Quoted 17 lines
Quoted 9 lines
Quoted 8 lines
+/**
+ *test_kunit_helper_alloc_device- Allocate a mock device for a KUnit test
+ * @test: The test context object
+ *
+ * This allocates a fake struct &device to create a mock for a KUnit
+ * test. The device will also be bound to a fake driver. It will thus be
+ * able to leverage the usual infrastructure and most notably the
+ * device-managed resources just like a "real" device.Quoted 7 lines
What specific "usual infrastructure" are you wanting to access here?
And again, if you want a fake device, make a virtual one, by just calling
device_create().Or are you wanting to do "more" with that device pointer than
device_create()can give you?Quoted 6 lines
Personally, I was (am) only interested in
devm_unwinding. I guess thedevice_create(),device_add(),device_remove()... (didn't study this sequence in details so sorry if there is errors) could've been sufficient for me. I haven't looked how much of the code that there is for 'platform devices' should be duplicated to support that sequence for testability purposes.Any device can access
devm_code, there's no need for it to be a platform device at all.Quoted 6 lines
Quoted 2 lines
Sure but the resources are only released if the device is part of a bus, so it can't be a
root_device(or bare device) eitherThe resources are not cleaned up when the device is freed no matter if it's on a bus or not? If so, then that's a bug that needs to be fixed, and tested :)
Quoted 7 lines
Please have a look at:
https://lore.kernel.org/linux-kselftest/20230324123157.bbwvfq4gsxnlnfwb@houat/I couldn't get an answer on whether it was considered a bug or not last time, but as you can see there's a clear difference between a root device and a platform device that has probed when it comes to resource cleanup.
Great, testing shows there are bugs! :)
That's a great start of a test, how about submitting that in a way that I can test it and we can go from there?
thanks,
greg k-h
Re: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
Quoted 41 lines · Greg Kroah-Hartman
Quoted 40 lines · Maxime Ripard
Quoted 29 lines · Greg Kroah-Hartman
Quoted 28 lines · Maxime Ripard
Quoted 26 lines · Greg Kroah-Hartman
Quoted 17 lines
Quoted 9 lines
Quoted 8 lines
+/**
+ *test_kunit_helper_alloc_device- Allocate a mock device for a KUnit test
+ * @test: The test context object
+ *
+ * This allocates a fake struct &device to create a mock for a KUnit
+ * test. The device will also be bound to a fake driver. It will thus be
+ * able to leverage the usual infrastructure and most notably the
+ * device-managed resources just like a "real" device.Quoted 7 lines
What specific "usual infrastructure" are you wanting to access here?
And again, if you want a fake device, make a virtual one, by just calling
device_create().Or are you wanting to do "more" with that device pointer than
device_create()can give you?Quoted 6 lines
Personally, I was (am) only interested in
devm_unwinding. I guess thedevice_create(),device_add(),device_remove()... (didn't study this sequence in details so sorry if there is errors) could've been sufficient for me. I haven't looked how much of the code that there is for 'platform devices' should be duplicated to support that sequence for testability purposes.Any device can access
devm_code, there's no need for it to be a platform device at all.Quoted 6 lines
Quoted 2 lines
Sure but the resources are only released if the device is part of a bus, so it can't be a
root_device(or bare device) eitherThe resources are not cleaned up when the device is freed no matter if it's on a bus or not? If so, then that's a bug that needs to be fixed, and tested :)
Please have a look at:
https://lore.kernel.org/linux-kselftest/20230324123157.bbwvfq4gsxnlnfwb@houat/
Quoted 6 lines
Quoted 4 lines
I couldn't get an answer on whether it was considered a bug or not last time, but as you can see there's a clear difference between a root device and a platform device that has probed when it comes to resource cleanup.
Great, testing shows there are bugs! :)
I mean, it wasn't clear to me that it was indeed a bug or the intent behind devm was that it would only work when probed. Both seemed reasonable.
Quoted 2 lines
That's a great start of a test, how about submitting that in a way that I can test it and we can go from there?
Ack.
I guess I'd need to arrange them somewhat differently for it to be useful and merge-able.
How would you prefer them to be submitted, in two different files testing both the root devices and platform devices?
Maxime
Greg Kroah-Hartman
maintainerRe: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
Quoted 56 lines · Maxime Ripard
Quoted 41 lines · Greg Kroah-Hartman
Quoted 40 lines · Maxime Ripard
Quoted 29 lines · Greg Kroah-Hartman
Quoted 28 lines · Maxime Ripard
Quoted 26 lines · Greg Kroah-Hartman
Quoted 17 lines
Quoted 9 lines
Quoted 8 lines
+/**
+ *test_kunit_helper_alloc_device- Allocate a mock device for a KUnit test
+ * @test: The test context object
+ *
+ * This allocates a fake struct &device to create a mock for a KUnit
+ * test. The device will also be bound to a fake driver. It will thus be
+ * able to leverage the usual infrastructure and most notably the
+ * device-managed resources just like a "real" device.Quoted 7 lines
What specific "usual infrastructure" are you wanting to access here?
And again, if you want a fake device, make a virtual one, by just calling
device_create().Or are you wanting to do "more" with that device pointer than
device_create()can give you?Quoted 6 lines
Personally, I was (am) only interested in
devm_unwinding. I guess thedevice_create(),device_add(),device_remove()... (didn't study this sequence in details so sorry if there is errors) could've been sufficient for me. I haven't looked how much of the code that there is for 'platform devices' should be duplicated to support that sequence for testability purposes.Any device can access
devm_code, there's no need for it to be a platform device at all.Quoted 6 lines
Quoted 2 lines
Sure but the resources are only released if the device is part of a bus, so it can't be a
root_device(or bare device) eitherThe resources are not cleaned up when the device is freed no matter if it's on a bus or not? If so, then that's a bug that needs to be fixed, and tested :)
Please have a look at:
https://lore.kernel.org/linux-kselftest/20230324123157.bbwvfq4gsxnlnfwb@houat/Quoted 6 lines
Quoted 4 lines
I couldn't get an answer on whether it was considered a bug or not last time, but as you can see there's a clear difference between a root device and a platform device that has probed when it comes to resource cleanup.
Great, testing shows there are bugs! :)
I mean, it wasn't clear to me that it was indeed a bug or the intent behind devm was that it would only work when probed. Both seemed reasonable.
Quoted 2 lines
That's a great start of a test, how about submitting that in a way that I can test it and we can go from there?
Quoted 7 lines
Ack.
I guess I'd need to arrange them somewhat differently for it to be useful and merge-able.
How would you prefer them to be submitted, in two different files testing both the root devices and platform devices?
root devices are rare, but yes, one for each would be good, thanks!
greg k-h
Greg Kroah-Hartman
maintainerRe: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
In reply to Matti VaittinenQuoted 25 lines · Matti Vaittinen
The creation of a dummy device in order to test managed interfaces is a generally useful test feature. The drm test helpers
drm_kunit_helper_alloc_device()anddrm_kunit_helper_free_device()are doing exactly this. It makes no sense that each and every component which intends to be testing managed interfaces will create similar helpers so stole these for more generic use.Signed-off-by Matti Vaittinen <[email protected]>---
Changes:
v4 => v5:
- Add accidentally dropped header and email recipients
- do not rename + move helpers from DRM but add temporary dublicates to simplify merging. (This patch does not touch DRM and can be merged separately. DRM patch and IIO test patch still depend on this one).Please note that there's something similar ongoing in the CCF:
https://lore.kernel.org/all/[email protected]/I do like the simplicity of these DRM-originated helpers so I think they're worth. I do equally like the Stephen's idea of having the "dummy platform device" related helpers under
drivers/baseand the header being ininclude/kunit/platform_device.hwhich is similar to real platform device underinclude/linux/platform_device.h
Quoted 4 lines
--- drivers/base/test/Kconfig | 5 ++ drivers/base/test/Makefile | 2 + drivers/base/test/test_kunit_device.c | 83 +++++++++++++++++++++++++++
By putting files in this directory, you are asking me to maintain this code, and right now, I can't agree with that, sorry. See my review comments on it for why.
thanks,
greg k-h
Re: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
In reply to Matti VaittinenQuoted 21 lines · Matti Vaittinen
The creation of a dummy device in order to test managed interfaces is a generally useful test feature. The drm test helpers
drm_kunit_helper_alloc_device()anddrm_kunit_helper_free_device()are doing exactly this. It makes no sense that each and every component which intends to be testing managed interfaces will create similar helpers so stole these for more generic use.Signed-off-by Matti Vaittinen <[email protected]>---
Changes:
v4 => v5:
- Add accidentally dropped header and email recipients
- do not rename + move helpers from DRM but add temporary dublicates to simplify merging. (This patch does not touch DRM and can be merged separately. DRM patch and IIO test patch still depend on this one).Please note that there's something similar ongoing in the CCF:
https://lore.kernel.org/all/[email protected]/
Quoted 6 lines
I do like the simplicity of these DRM-originated helpers so I think they're worth. I do equally like the Stephen's idea of having the "dummy platform device" related helpers under
drivers/baseand the header being ininclude/kunit/platform_device.hwhich is similar to real platform device underinclude/linux/platform_device.h
---
Thanks for sending this my way.
It's clear we need some way of creating "fake" devices for KUnit tests. Given that there are now (at least) three different drivers looking to use this, we'll ultimately need something which works for everyone.
I think the questions we therefore need to answer are:
- Do we specifically need a platform_device (or, any other specific device struct), or would any old struct device work? I can see why we would need a platform device for cases where we're testing things like device-tree properties (or, in the future, having e.g. USB-specific helpers which create usb_device). Most tests just use root_device_register() thus far, though.
- What helpers do we need to make creating, using, and cleaning up these devices as simple as possible.
I think that in this particular case, we don't actually need a struct platform_device. Replacing these helpers with simple calls to root_device_register() and root_device_unregister() seems to work fine with this patch series for me. (It does break the drm_test_managed_run_action test, though.) So I don't think having these helpers actually help this series at the moment.
That being said, if they used the KUnit resource system to automatically clean up the device when the test is finished (or otherwise exits), that would seem like a real advantage. The clk and drm examples both do this, and I'm hoping to add an API to make it even simpler going forward. (With the work-in-progress API described here[1], the whole thing should boil down to "struct device *dev = root_device_register(name); kunit_defer(root_device_unregister, dev);".)
So, I guess we have three cases we need to look at:
- A test just needs any old struct device. Tests thus far have hardcoded, or had their own wrappers around root_device_register() for this.
- A test needs a device attached to a bus (but doesn't care which bus). Thus far, people have used struct platform_device for this (see the DRM helpers, which use a platform device for managed resource tests[2]). Maybe the right solution here is something like a struct kunit_device?
- A test needs a device attached to a specific bus. We'll probably need some more detailed faking of that bus. This covers cases like having fake USB devices, devicetree integration, etc.
I'd suggest that, for the majority of cases which only care about the first case, let's just use root_device_register() directly, or have a thin wrapper like the old root_device-based version of the DRM helpers[3]. This will probable serve us well enough while we work out how to handle the other two cases properly (which is already being looked at for the CLK/DeviceTree patches and the DRM stuff).
If the resulting helpers are generally useful enough, they can probably sit in either drivers/base or lib/kunit. I'd rather not have code that's really specific to certain busses sitting in lib/kunit rather than alongside the device/bus code in drivers/base or some other subsystem/driver path, but I can tolerate it for the very generic struct device.
Regardless, I've left a few notes on the patch itself below.
Cheers,
-- David
[1]: https://kunit-review.googlesource.com/c/linux/+/5434/3/include/kunit/resource.h
[2]: https://lore.kernel.org/all/[email protected]/
[3]: https://elixir.bootlin.com/linux/v6.2/source/drivers/gpu/drm/tests/drm_kunit_helpers.c#L39
Quoted 43 lines
drivers/base/test/Kconfig | 5 ++ drivers/base/test/Makefile | 2 + drivers/base/test/test_kunit_device.c | 83 +++++++++++++++++++++++++++ include/kunit/platform_device.h | 13 +++++ 4 files changed, 103 insertions(+) create mode 100644 drivers/base/test/test_kunit_device.c create mode 100644 include/kunit/platform_device.hdrivers/base/test/Kconfig +5
-0@@ -1,4 +1,9 @@ # SPDX-License-Identifier: GPL-2.0 + +config TEST_KUNIT_DEVICE_HELPERS + depends on KUNIT + tristate + config TEST_ASYNC_DRIVER_PROBE tristate "Build kernel module to test asynchronous driver probing" depends on mdrivers/base/test/Makefile +2
-0@@ -1,5 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_TEST_ASYNC_DRIVER_PROBE) += test_async_driver_probe.o +obj-$(CONFIG_TEST_KUNIT_DEVICE_HELPERS) += test_kunit_device.o + obj-$(CONFIG_DRIVER_PE_KUNIT_TEST) += property-entry-test.o CFLAGS_property-entry-test.o += $(DISABLE_STRUCTLEAK_PLUGIN)drivers/base/test/test_kunit_device.c new file +3
-0@@ -0,0 +1,83 @@ +// SPDX-License-Identifier: GPL-2.0 +/* +* These helpers have been extracted from drm test code at
drivers/base/test/test_kunit_device.c line 13
Quoted 10 lines
drivers/base/test/test_kunit_device.c new file +10
-0+* drm_kunit_helpers.c which was authored by +* Maxime Ripard <[email protected]> +*/ + +#include <linux/device.h> +#include <linux/platform_device.h> + +#include <kunit/platform_device.h> + +#define KUNIT_DEVICE_NAME "test-kunit-mock-device"
Personally, I'd really rather this be a name passed in by the test. What if a test needs to create multiple distinct devices?
Quoted 49 lines
drivers/base/test/test_kunit_device.c new file +49
-0+ +static int fake_probe (struct platform_device *pdev) +{ +return 0 ; +} + +static int fake_remove (struct platform_device *pdev) +{ +return 0 ; +} + +static struct platform_driver fake_platform_driver = { + .probe = fake_probe, + .remove = fake_remove, + .driver = { + .name =KUNIT_DEVICE_NAME , + }, +}; + +/** +* test_kunit_helper_alloc_device - Allocate a mock device for a KUnit test +* @test: The test context object +* +* This allocates a fake struct &device to create a mock for a KUnit +* test. The device will also be bound to a fake driver. It will thus be +* able to leverage the usual infrastructure and most notably the +* device-managed resources just like a "real" device. +* +* Callers need to make sure test_kunit_helper_free_device() on the +* device when done. +* +* Returns: +* A pointer to the new device, or an ERR_PTR() otherwise. +*/ +struct device *test_kunit_helper_alloc_device (struct kunit *test) +{ +struct platform_device *pdev; +int ret; + + ret =platform_driver_register (&fake_platform_driver); +KUNIT_ASSERT_EQ (test, ret,0 ); + + pdev =platform_device_alloc (KUNIT_DEVICE_NAME ,PLATFORM_DEVID_NONE ); +KUNIT_ASSERT_NOT_ERR_OR_NULL (test, pdev); + + ret =platform_device_add (pdev); +KUNIT_ASSERT_EQ (test, ret,0 ); + +return &pdev->dev;
drivers/base/test/test_kunit_device.c line 72
Quoted 10 lines
drivers/base/test/test_kunit_device.c new file +10
-0+} +EXPORT_SYMBOL_GPL (test_kunit_helper_alloc_device); + +/** +* test_kunit_helper_free_device - Frees a mock device +* @test: The test context object +* @dev: The device to free +* +* Frees a device allocated with test_kunit_helper_alloc_device(). +*/
This really should be automatically called when the test exits, probably using kunit reources. Ideally, there'd also be a function to free it earlier, which can be done by calling kunit_remove_resource() to lower the refcount.
Quoted 18 lines
drivers/base/test/test_kunit_device.c new file +11
-0+void test_kunit_helper_free_device (struct kunit *test,struct device *dev) +{ +struct platform_device *pdev =to_platform_device (dev); + +platform_device_unregister (pdev); +platform_driver_unregister (&fake_platform_driver); +} +EXPORT_SYMBOL_GPL (test_kunit_helper_free_device); + +MODULE_AUTHOR ("Matti Vaittinen <[email protected]>" ); +MODULE_LICENSE ("GPL" );include/kunit/platform_device.h new file +1
-0@@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */
include/kunit/platform_device.h line 11
Quoted 10 lines
include/kunit/platform_device.h new file +10
-0+ +#ifndef __KUNIT_PLATFORM_DEVICE__ +#define __KUNIT_PLATFORM_DEVICE__ + +#include <kunit/test.h> + +struct device ; + +struct device *test_kunit_helper_alloc_device (struct kunit *test); +void test_kunit_helper_free_device (struct kunit *test,struct device *dev);
If these helpers are supposed to guarantee that the resulting device is a platform device, let's reflect that in their names. Otherwise, let's not put this in a platform_device.h header, but maybe something more general, like kunit/device.h.
Quoted 17 lines
include/kunit/platform_device.h new file +2
-1+ +#endif --2.39.2
--
Matti Vaittinen, Linux device drivers
ROHM Semiconductors, Finland SWDC
Kiviharjunlenkki 1E
90220 OULU
FINLAND~~~ "I don't think so," said Rene Descartes. Just then he vanished ~~~ Simon says - in Latin please.
~~~ "non cogito me" dixit Rene Descarte, deinde evanescavit ~~~ Thanks to Simon Glass for the translation =]
Matti Vaittinen
maintainerRe: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
Hi David, all,
Quoted 36 lines · David Gow
Quoted 21 lines · Matti Vaittinen
The creation of a dummy device in order to test managed interfaces is a generally useful test feature. The drm test helpers
drm_kunit_helper_alloc_device()anddrm_kunit_helper_free_device()are doing exactly this. It makes no sense that each and every component which intends to be testing managed interfaces will create similar helpers so stole these for more generic use.Signed-off-by Matti Vaittinen <[email protected]>---
Changes:
v4 => v5:
- Add accidentally dropped header and email recipients
- do not rename + move helpers from DRM but add temporary dublicates to simplify merging. (This patch does not touch DRM and can be merged separately. DRM patch and IIO test patch still depend on this one).Please note that there's something similar ongoing in the CCF:
https://lore.kernel.org/all/[email protected]/Quoted 6 lines
I do like the simplicity of these DRM-originated helpers so I think they're worth. I do equally like the Stephen's idea of having the "dummy platform device" related helpers under
drivers/baseand the header being ininclude/kunit/platform_device.hwhich is similar to real platform device underinclude/linux/platform_device.h
---Thanks for sending this my way.
It's clear we need some way of creating "fake" devices for KUnit tests. Given that there are now (at least) three different drivers looking to use this, we'll ultimately need something which works for everyone.
Quoted 7 lines
I think the questions we therefore need to answer are:
- Do we specifically need aplatform_device(or, any other specific device struct), or would any old struct device work? I can see why we would need a platform device for cases where we're testing things like device-tree properties (or, in the future, having e.g. USB-specific helpers which createusb_device). Most tests just useroot_device_register()thus far, though.
Funny timing. I just found the root_device_register() while wondering the parent for auxiliary_devices.
I think the root_device_[un]register() meets my current needs.
Quoted 9 lines
- What helpers do we need to make creating, using, and cleaning up these devices as simple as possible.
I think that in this particular case, we don't actually need a struct
platform_device. Replacing these helpers with simple calls toroot_device_register()androot_device_unregister()seems to work fine with this patch series for me. (It does break thedrm_test_managed_run_actiontest, though.) So I don't think having these helpers actually help this series at the moment.
I am afraid that further work with these helpers is out of the scope for me (at least for now). I'll drop the DRM and the helper patches from this series && go with the root_device_register(), root_device_unregister() in the IIO tests added in this series.
Quoted 3 lines
That being said, if they used the KUnit resource system to automatically clean up the device when the test is finished (or otherwise exits),
My 10 cents to this is that yes, automatic unwinding at test exit would be simple - and also correct for most of the time. However, I think there might also be tests that would like to verify the unwinding process has really managed to do what it was intended to do. That, I think would require being able to manually drop the device in the middle of the test.
Quoted 4 lines
So, I guess we have three cases we need to look at:
- A test just needs any old struct device. Tests thus far have hardcoded, or had their own wrappers aroundroot_device_register()for this.
As said above, my case fits this category.
Quoted 5 lines
- A test needs a device attached to a bus (but doesn't care which bus). Thus far, people have used struct
platform_devicefor this (see the DRM helpers, which use a platform device for managed resource tests[2]). Maybe the right solution here is something like a structkunit_device?
This sounds like, how to put it, "architecturally correct". But...
Quoted 3 lines
- A test needs a device attached to a specific bus. We'll probably need some more detailed faking of that bus. This covers cases like having fake USB devices, devicetree integration, etc.
...if we in any case need this, wouldn't the kunit_device just be unnecessary bloat because if the test does not care which bus it is sitting in, then it could probably use a bus-specific device as well?
Quoted 2 lines
I'd suggest that, for the majority of cases which only care about the first case, let's just use
root_device_register()directly,
After finding the root_device_register() - I agree.
Quoted 6 lines
or have a
thin wrapper like the old root_device-based version of the DRM helpers[3]. This will probable serve us well enough while we work out how to handle the other two cases properly (which is already being looked at for the CLK/DeviceTree patches and the DRM stuff).
Quoted 8 lines
If the resulting helpers are generally useful enough, they can probably sit in either
drivers/baseor lib/kunit. I'd rather not have code that's really specific to certain busses sitting in lib/kunit rather than alongside the device/bus code indrivers/baseor some other subsystem/driver path, but I can tolerate it for the very generic struct device.Regardless, I've left a few notes on the patch itself below.
Thanks but I guess I'll just drop this one :)
Quoted 7 lines
Cheers,
-- David[1]: https://kunit-review.googlesource.com/c/linux/+/5434/3/include/kunit/resource.h
[2]: https://lore.kernel.org/all/[email protected]/
[3]: https://elixir.bootlin.com/linux/v6.2/source/drivers/gpu/drm/tests/drm_kunit_helpers.c#L39
Thanks for the thorough analysis and these links! This was enlightening :)
Yours,
-- Matti
Signature · 5 lines
Matti Vaittinen Linux kernel developer at ROHM Semiconductors Oulu Finland ~~ When things go utterly wrong vim users can always type :help! ~~
Greg Kroah-Hartman
maintainerRe: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
In reply to David GowQuoted 36 lines · David Gow
Quoted 21 lines · Matti Vaittinen
The creation of a dummy device in order to test managed interfaces is a generally useful test feature. The drm test helpers
drm_kunit_helper_alloc_device()anddrm_kunit_helper_free_device()are doing exactly this. It makes no sense that each and every component which intends to be testing managed interfaces will create similar helpers so stole these for more generic use.Signed-off-by Matti Vaittinen <[email protected]>---
Changes:
v4 => v5:
- Add accidentally dropped header and email recipients
- do not rename + move helpers from DRM but add temporary dublicates to simplify merging. (This patch does not touch DRM and can be merged separately. DRM patch and IIO test patch still depend on this one).Please note that there's something similar ongoing in the CCF:
https://lore.kernel.org/all/[email protected]/Quoted 6 lines
I do like the simplicity of these DRM-originated helpers so I think they're worth. I do equally like the Stephen's idea of having the "dummy platform device" related helpers under
drivers/baseand the header being ininclude/kunit/platform_device.hwhich is similar to real platform device underinclude/linux/platform_device.h
---Thanks for sending this my way.
It's clear we need some way of creating "fake" devices for KUnit tests. Given that there are now (at least) three different drivers looking to use this, we'll ultimately need something which works for everyone.
Quoted 7 lines
I think the questions we therefore need to answer are:
- Do we specifically need aplatform_device(or, any other specific device struct), or would any old struct device work? I can see why we would need a platform device for cases where we're testing things like device-tree properties (or, in the future, having e.g. USB-specific helpers which createusb_device). Most tests just useroot_device_register()thus far, though.
Any struct device would work, so please do NOT use a platform device.
Use aux devices, or better yet, just a normal virtual device by calling device_create().
Quoted 2 lines
- What helpers do we need to make creating, using, and cleaning up these devices as simple as possible.
Becides what the driver core already provides you? What exactly are you wanting to do here?
Quoted 6 lines
I think that in this particular case, we don't actually need a struct
platform_device. Replacing these helpers with simple calls toroot_device_register()androot_device_unregister()seems to work fine with this patch series for me. (It does break thedrm_test_managed_run_actiontest, though.) So I don't think having these helpers actually help this series at the moment.
Why abuse root_device_*() for something that really is not a root device in the system? Why not use a virtual device? Or better yet, a kunit bus with devices on it that are just for testing? That way you can properly test the bus and driver and device code fully, which is what you are implying is needed here.
Quoted 9 lines
That being said, if they used the KUnit resource system to automatically clean up the device when the test is finished (or otherwise exits), that would seem like a real advantage. The clk and drm examples both do this, and I'm hoping to add an API to make it even simpler going forward. (With the work-in-progress API described here[1], the whole thing should boil down to "struct device *dev =
root_device_register(name);kunit_defer(root_device_unregister, dev);".)
Quoted 4 lines
So, I guess we have three cases we need to look at:
- A test just needs any old struct device. Tests thus far have hardcoded, or had their own wrappers aroundroot_device_register()for this.
Again, make a kunit bus and devices, that might be "simplest" overall.
Quoted 5 lines
- A test needs a device attached to a bus (but doesn't care which bus). Thus far, people have used struct
platform_devicefor this (see the DRM helpers, which use a platform device for managed resource tests[2]). Maybe the right solution here is something like a structkunit_device?
Yes.
Quoted 3 lines
- A test needs a device attached to a specific bus. We'll probably need some more detailed faking of that bus. This covers cases like having fake USB devices, devicetree integration, etc.
Have your own bus. No need to mess with USB or any real bus UNLESS you want to actually test those busses, and if so, just create fake USB or clk or whatever devices so that you can test them.
Or just rely on the testing that some busses have for their devices (USB has this today and syzbot knows how to test it), as busses for hardware can be complex and usually require a "real" driver to be written for them to test things.
thanks,
gre gk-h
Re: [PATCH v5 1/8] drivers: kunit: Generic helpers for test device creation
In reply to David GowHi David,
Quoted 10 lines · David Gow
I think the questions we therefore need to answer are:
- Do we specifically need aplatform_device(or, any other specific device struct), or would any old struct device work? I can see why we would need a platform device for cases where we're testing things like device-tree properties (or, in the future, having e.g. USB-specific helpers which createusb_device). Most tests just useroot_device_register()thus far, though.
- What helpers do we need to make creating, using, and cleaning up these devices as simple as possible.
Quoted 6 lines
I think that in this particular case, we don't actually need a struct
platform_device. Replacing these helpers with simple calls toroot_device_register()androot_device_unregister()seems to work fine with this patch series for me. (It does break thedrm_test_managed_run_actiontest, though.) So I don't think having these helpers actually help this series at the moment.
I'm not sure that a root_device is a good option, see below.
Quoted 8 lines
That being said, if they used the KUnit resource system to automatically clean up the device when the test is finished (or otherwise exits), that would seem like a real advantage. The clk and drm examples both do this, and I'm hoping to add an API to make it even simpler going forward. (With the work-in-progress API described here[1], the whole thing should boil down to "struct device *dev =
root_device_register(name);kunit_defer(root_device_unregister, dev);".)
Oh, yes, please make it happen :)
The current API is a bit of a pain compared to other managed APIs like devm or drmm.
Quoted 4 lines
So, I guess we have three cases we need to look at:
- A test just needs any old struct device. Tests thus far have hardcoded, or had their own wrappers aroundroot_device_register()for this.
Quoted 8 lines
- A test needs a device attached to a bus (but doesn't care which bus). Thus far, people have used struct
platform_devicefor this (see the DRM helpers, which use a platform device for managed resource tests[2]). Maybe the right solution here is something like a structkunit_device?
- A test needs a device attached to a specific bus. We'll probably need some more detailed faking of that bus. This covers cases like having fake USB devices, devicetree integration, etc.
Yeah, from the current discussion on the IIO and clk patchsets, and what we've done in DRM, I guess there's two major use cases:
* You test an (isolated) function that takes a device as an argument. Here you probably don't really care about what the device is as long as you can provide one. This is what is being done for the DRM helpers at the moment, even though it's not really isolated. The device is essentially mocked. This could be your points 1 and 2.
* You want to probe the driver with a fake context. The device and drivers are very much real, but the device tree (or whatever) is mocked. This is what the clocks patches from Stephen are doing. This could be covered by your point 3.
Quoted 6 lines
I'd suggest that, for the majority of cases which only care about the first case, let's just use
root_device_register()directly, or have a thin wrapper like the old root_device-based version of the DRM helpers[3]. This will probable serve us well enough while we work out how to handle the other two cases properly (which is already being looked at for the CLK/DeviceTree patches and the DRM stuff).
I disagree, and I think your cases 1 and 2 should be merged. We were initially using a root_device in DRM. We had to switch to platform_device (but actually any device attached to a bus) because a root device isn't attached to a bus and thus the devm resources are never freed.
When a function takes a device as an argument, there's a good chance that it will use devm nowadays, so we ended up exhausting resources pools (like IDs iirc) when running a lot of tests in sequence.
So yeah, I think you can't just assume that a root device will do even for a true unit test that would test an isolated function. It either needs to be tied to a bus, or we need to force the devm resource release when the root device is removed somehow.
Maxime
Matti Vaittinen
maintainerPATCH v5 2/8 drm/tests: helpers: Use generic helpers
In reply to Matti VaittinenReplace DRM specific managed device creation test-helpers with generic ones.
---
v4 => v5:
- do not rename + move helpers from DRM but add temporary dublicates to simplify merging. This patch depends on interface added at patch 1/8.
--- drivers/gpu/drm/Kconfig | 2 + .../gpu/drm/tests/drm_client_modeset_test.c | 5 +- drivers/gpu/drm/tests/drm_kunit_helpers.c | 69 ------------------- drivers/gpu/drm/tests/drm_managed_test.c | 5 +- drivers/gpu/drm/tests/drm_modes_test.c | 5 +- drivers/gpu/drm/tests/drm_probe_helper_test.c | 5 +- drivers/gpu/drm/vc4/Kconfig | 1 + drivers/gpu/drm/vc4/tests/vc4_mock.c | 3 +- .../gpu/drm/vc4/tests/vc4_test_pv_muxing.c | 9 +-- include/drm/drm_kunit_helpers.h | 7 +- 10 files changed, 24 insertions(+), 87 deletions(-)
drivers/gpu/drm/Kconfig +2 -0
@@ -66,6 +66,7 @@ config DRM_USE_DYNAMIC_DEBUG config DRM_KUNIT_TEST_HELPERS tristate depends on DRM && KUNIT + select TEST_KUNIT_DEVICE_HELPERS help KUnit Helpers for KMS drivers.
@@ -80,6 +81,7 @@ config DRM_KUNIT_TEST select DRM_BUDDY select DRM_EXPORT_FOR_TESTS if m select DRM_KUNIT_TEST_HELPERS + select TEST_KUNIT_DEVICE_HELPERS default KUNIT_ALL_TESTS help This builds unit tests for DRM. This option is not useful for
drivers/gpu/drm/tests/drm_client_modeset_test.c +3 -2
@@ -3,6 +3,7 @@* Copyright (c) 2022 Maxime Ripard <[email protected]> */ +#include <kunit/platform_device.h> #include <kunit/test.h> #include <drm/drm_connector.h>
@@ -60,7 +61,7 @@ static int drm_client_modeset_test_init(struct kunit *test) test->priv = priv; - priv->dev =drm_kunit_helper_alloc_device (test); + priv->dev =test_kunit_helper_alloc_device (test);KUNIT_ASSERT_NOT_ERR_OR_NULL (test, priv->dev); priv->drm = __drm_kunit_helper_alloc_drm_device(test, priv->dev,
@@ -86,7 +87,7 @@ static void drm_client_modeset_test_exit(struct kunit *test) {struct drm_client_modeset_test_priv *priv = test->priv; -drm_kunit_helper_free_device (test, priv->dev); +test_kunit_helper_free_device (test, priv->dev); }static void drm_test_pick_cmdline_res_1920_1080_60 (struct kunit *test)
drivers/gpu/drm/tests/drm_kunit_helpers.c +0 -69
78 lines not on this page · raw message
drivers/gpu/drm/tests/drm_managed_test.c +3 -2
@@ -4,6 +4,7 @@#include <drm/drm_kunit_helpers.h> #include <drm/drm_managed.h> +#include <kunit/platform_device.h> #include <kunit/resource.h> #include <linux/device.h>
@@ -35,7 +36,7 @@ static void drm_test_managed_run_action(struct kunit *test)KUNIT_ASSERT_NOT_ERR_OR_NULL (test, priv);init_waitqueue_head (&priv->action_wq); - dev =drm_kunit_helper_alloc_device (test); + dev =test_kunit_helper_alloc_device (test);KUNIT_ASSERT_NOT_ERR_OR_NULL (test, dev); drm =__drm_kunit_helper_alloc_drm_device (test, dev,sizeof (*drm),0 ,DRIVER_MODESET );
@@ -48,7 +49,7 @@ static void drm_test_managed_run_action(struct kunit *test)KUNIT_ASSERT_EQ (test, ret,0 );drm_dev_unregister (drm); -drm_kunit_helper_free_device (test, dev); +test_kunit_helper_free_device (test, dev); ret =wait_event_interruptible_timeout (priv->action_wq, priv->action_done,msecs_to_jiffies (TEST_TIMEOUT_MS ));
drivers/gpu/drm/tests/drm_modes_test.c +3 -2
@@ -7,6 +7,7 @@#include <drm/drm_kunit_helpers.h> #include <drm/drm_modes.h> +#include <kunit/platform_device.h> #include <kunit/test.h> #include <linux/units.h>
@@ -23,7 +24,7 @@ static int drm_test_modes_init(struct kunit *test) priv =kunit_kzalloc (test,sizeof (*priv),GFP_KERNEL );KUNIT_ASSERT_NOT_NULL (test, priv); - priv->dev =drm_kunit_helper_alloc_device (test); + priv->dev =test_kunit_helper_alloc_device (test);KUNIT_ASSERT_NOT_ERR_OR_NULL (test, priv->dev); priv->drm = __drm_kunit_helper_alloc_drm_device(test, priv->dev,
@@ -40,7 +41,7 @@ static void drm_test_modes_exit(struct kunit *test) {struct drm_test_modes_priv *priv = test->priv; -drm_kunit_helper_free_device (test, priv->dev); +test_kunit_helper_free_device (test, priv->dev); }static void drm_test_modes_analog_tv_ntsc_480i (struct kunit *test)
drivers/gpu/drm/tests/drm_probe_helper_test.c +3 -2
@@ -13,6 +13,7 @@#include <drm/drm_modeset_helper_vtables.h> #include <drm/drm_probe_helper.h> +#include <kunit/platform_device.h> #include <kunit/test.h> struct drm_probe_helper_test_priv {
@@ -40,7 +41,7 @@ static int drm_probe_helper_test_init(struct kunit *test)KUNIT_ASSERT_NOT_NULL (test, priv); test->priv = priv; - priv->dev =drm_kunit_helper_alloc_device (test); + priv->dev =test_kunit_helper_alloc_device (test);KUNIT_ASSERT_NOT_ERR_OR_NULL (test, priv->dev); priv->drm = __drm_kunit_helper_alloc_drm_device(test, priv->dev,
@@ -64,7 +65,7 @@ static void drm_probe_helper_test_exit(struct kunit *test) {struct drm_probe_helper_test_priv *priv = test->priv; -drm_kunit_helper_free_device (test, priv->dev); +test_kunit_helper_free_device (test, priv->dev); }typedef struct drm_display_mode *(*expected_mode_func_t )(struct drm_device *);
drivers/gpu/drm/vc4/Kconfig +1 -0
@@ -39,6 +39,7 @@ config DRM_VC4_KUNIT_TEST tristate "KUnit tests for VC4" if !KUNIT_ALL_TESTS depends on DRM_VC4 && KUNIT select DRM_KUNIT_TEST_HELPERS + select TEST_KUNIT_DEVICE_HELPERS default KUNIT_ALL_TESTS help This builds unit tests for the VC4 DRM/KMS driver. This option is
drivers/gpu/drm/vc4/tests/vc4_mock.c +2 -1
@@ -3,6 +3,7 @@#include <drm/drm_drv.h> #include <drm/drm_kunit_helpers.h> +#include <kunit/platform_device.h> #include <kunit/test.h> #include "vc4_mock.h"
@@ -162,7 +163,7 @@ static struct vc4_dev *__mock_device(struct kunit *test, bool is_vc5)struct device *dev;int ret; - dev =drm_kunit_helper_alloc_device (test); + dev =test_kunit_helper_alloc_device (test);KUNIT_ASSERT_NOT_ERR_OR_NULL (test, dev); vc4 = drm_kunit_helper_alloc_drm_device_with_driver(test, dev,
drivers/gpu/drm/vc4/tests/vc4_test_pv_muxing.c +5 -4
@@ -12,6 +12,7 @@#include <drm/drm_modeset_helper_vtables.h> #include <drm/drm_plane.h> +#include <kunit/platform_device.h> #include <kunit/test.h> #include "../vc4_drv.h"
@@ -762,7 +763,7 @@ static void vc4_pv_muxing_test_exit(struct kunit *test)drm_modeset_drop_locks (&priv->ctx);drm_modeset_acquire_fini (&priv->ctx);drm_dev_unregister (drm); -drm_kunit_helper_free_device (test, vc4->dev); +test_kunit_helper_free_device (test, vc4->dev); }static struct kunit_case vc4_pv_muxing_tests[] = {
@@ -873,7 +874,7 @@ static void drm_test_vc5_pv_muxing_bugs_subsequent_crtc_enable(struct kunit *tesdrm_modeset_drop_locks (&ctx);drm_modeset_acquire_fini (&ctx);drm_dev_unregister (drm); -drm_kunit_helper_free_device (test, vc4->dev); +test_kunit_helper_free_device (test, vc4->dev); }static void drm_test_vc5_pv_muxing_bugs_stable_fifo (struct kunit *test)
@@ -963,7 +964,7 @@ static void drm_test_vc5_pv_muxing_bugs_stable_fifo(struct kunit *test)drm_modeset_drop_locks (&ctx);drm_modeset_acquire_fini (&ctx);drm_dev_unregister (drm); -drm_kunit_helper_free_device (test, vc4->dev); +test_kunit_helper_free_device (test, vc4->dev); } static void
@@ -1017,7 +1018,7 @@ drm_test_vc5_pv_muxing_bugs_subsequent_crtc_enable_too_many_crtc_state(struct kudrm_modeset_drop_locks (&ctx);drm_modeset_acquire_fini (&ctx);drm_dev_unregister (drm); -drm_kunit_helper_free_device (test, vc4->dev); +test_kunit_helper_free_device (test, vc4->dev); }static struct kunit_case vc5_pv_muxing_bugs_tests[] = {
include/drm/drm_kunit_helpers.h +2 -5
@@ -8,9 +8,6 @@struct drm_device ;struct kunit ; -struct device *drm_kunit_helper_alloc_device (struct kunit *test); -void drm_kunit_helper_free_device (struct kunit *test,struct device *dev); -struct drm_device * __drm_kunit_helper_alloc_drm_device_with_driver(struct kunit *test, struct device *dev,
@@ -27,7 +24,7 @@ __drm_kunit_helper_alloc_drm_device_with_driver(struct kunit *test,* * This function creates a struct &drm_device from @_dev and @_drv. * -* @_dev should be allocated using drm_kunit_helper_alloc_device(). +* @_dev should be allocated using test_kunit_helper_alloc_device(). * * The driver is tied to the @_test context and will get cleaned at the * end of the test. The drm_device is allocated through
@@ -72,7 +69,7 @@ __drm_kunit_helper_alloc_drm_device(struct kunit *test,* This function creates a struct &drm_driver and will create a struct * &drm_device from @_dev and that driver. * -* @_dev should be allocated using drm_kunit_helper_alloc_device(). +* @_dev should be allocated using test_kunit_helper_alloc_device(). * * The driver is tied to the @_test context and will get cleaned at the * end of the test. The drm_device is allocated through
Signature · 14 lines
2.39.2 -- Matti Vaittinen, Linux device drivers ROHM Semiconductors, Finland SWDC Kiviharjunlenkki 1E 90220 OULU FINLAND ~~~ "I don't think so," said Rene Descartes. Just then he vanished ~~~ Simon says - in Latin please. ~~~ "non cogito me" dixit Rene Descarte, deinde evanescavit ~~~ Thanks to Simon Glass for the translation =]
Matti Vaittinen
maintainerPATCH v5 3/8 dt-bindings: iio: light: Support ROHM BU27034
In reply to Matti VaittinenROHM BU27034 is an ambient light sesnor with 3 channels and 3 photo diodes capable of detecting a very wide range of illuminance. Typical application is adjusting LCD and backlight power of TVs and mobile phones.
Add dt-bindings.
---
v2 =>
- No changes
Changes since RFCv1 => v2
- Fix binding file name and id by using comma instead of a hyphen to separate the vendor and part names.
--- .../bindings/iio/light/rohm,bu27034.yaml | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/light/rohm,bu27034.yaml
Documentation/devicetree/bindings/iio/light/rohm,bu27034.yaml new file +46 -0
@@ -0,0 +1,46 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/light/rohm,bu27034.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ROHM BU27034 ambient light sensor + +maintainers: + - Matti Vaittinen <[email protected]> + +description: | + ROHM BU27034 is an ambient light sesnor with 3 channels and 3 photo diodes + capable of detecting a very wide range of illuminance. Typical application + is adjusting LCD and backlight power of TVs and mobile phones. + https://fscdn.rohm.com/en/products/databook/datasheet/ic/sensor/light/bu27034nuc-e.pdf + +properties: + compatible: + const: rohm,bu27034 + + reg: + maxItems: 1 + + vdd-supply: true + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + light-sensor@38 { + compatible = "rohm,bu27034"; + reg = <0x38>; + vdd-supply = <&vdd>; + }; + }; + +...
Signature · 14 lines
2.39.2 -- Matti Vaittinen, Linux device drivers ROHM Semiconductors, Finland SWDC Kiviharjunlenkki 1E 90220 OULU FINLAND ~~~ "I don't think so," said Rene Descartes. Just then he vanished ~~~ Simon says - in Latin please. ~~~ "non cogito me" dixit Rene Descarte, deinde evanescavit ~~~ Thanks to Simon Glass for the translation =]
Matti Vaittinen
maintainerPATCH v5 4/8 iio: light: Add gain-time-scale helpers
In reply to Matti VaittinenSome light sensors can adjust both the HW-gain and integration time. There are cases where adjusting the integration time has similar impact to the scale of the reported values as gain setting has.
IIO users do typically expect to handle scale by a single writable 'scale' entry. Driver should then adjust the gain/time accordingly.
It however is difficult for a driver to know whether it should change gain or integration time to meet the requested scale. Usually it is preferred to have longer integration time which usually improves accuracy, but there may be use-cases where long measurement times can be an issue. Thus it can be preferable to allow also changing the integration time - but mitigate the scale impact by also changing the gain underneath. Eg, if integration time change doubles the measured values, the driver can reduce the HW-gain to half.
The theory of the computations of gain-time-scale is simple. However, some people (undersigned) got that implemented wrong for more than once.
Add some gain-time-scale helpers in order to not dublicate errors in all drivers needing these computations.
---
Currently it is only BU27034 using these in this series. I am however working with drivers for RGB sensors BU27008 and BU27010 which have similar [gain - integration time - scale] - relation. I hope sending those follows soon after the BU27034 is done.
Changes:
v4 => v5:
- drop DEFAULT_SYMBOL_NAMESPACE again
- spellcheck
- always build availability tables
- combine table-build and gts-init. Drop no longer needed interfaces
- check for invalid values at init
- document limitations of gain, time, selector and multiplier values
- document all exported functions
- move and inline valid gain / valid time and related functions to header.
NOTE: As a side-effect this makes the internal iteration functions public as well.
- drop unlikely() from "cold path"
- add iio_gts_find_new_gain_by_old_gain_time()
v3 => v4:
- doc styling
- use memset to zero the helper struct at init
- drop unnecessary min calculation at iio_find_closest_gain_low()
- use namespace to all exports
- many minor stylings
- make available outside iio/light (move code to drivers/iio and move the header under include
- rename to look like other files under drivers/iio (s/iio/industrialio)
- drop unused functions
- don't export only internally used functions and make them static Note, I decided to keep iio_gts_total_gain_to_scale() exported as it is currently needed by the tests outside the helpers.
v2 => v3: (mostly fixes based on review by Andy)
- Fix typos
- Styling fixes
- Use namespace for exported symbols
- Protect allocs against argument overflow
- Fix include protection name
- add types.h inclusion and struct device forward declaration
RFCv1 => v2:
- fix include guardian
- Improve kernel doc for iio_init_iio_gts.
- Add iio_gts_scale_to_total_gain
- Add iio_gts_total_gain_to_scale
- Fix review comments from Jonathan
- add documentation to few functions
- replace 0xffffffffffffffffLLU by U64_MAX
- some styling fixes
- drop unnecessary NULL checks
- order function arguments by in / out purpose
- drop GAIN_SCALE_ITIME_MS()
- Add helpers for available scales and times
- Rename to iio-gts-helpers
--- drivers/iio/Kconfig | 3 + drivers/iio/Makefile | 1 + drivers/iio/industrialio-gts-helper.c | 1064 +++++++++++++++++++++++++ include/linux/iio/iio-gts-helper.h | 206 +++++ 4 files changed, 1274 insertions(+) create mode 100644 drivers/iio/industrialio-gts-helper.c create mode 100644 include/linux/iio/iio-gts-helper.h
drivers/iio/Kconfig +3 -0
@@ -30,6 +30,9 @@ config IIO_CONFIGFS (e.g. software triggers). For more info see Documentation/iio/iio_configfs.rst. +config IIO_GTS_HELPER + tristate + config IIO_TRIGGER bool "Enable triggered sampling support" help
drivers/iio/Makefile +1 -0
@@ -9,6 +9,7 @@ industrialio-$(CONFIG_IIO_BUFFER) += industrialio-buffer.o industrialio-$(CONFIG_IIO_TRIGGER) += industrialio-trigger.o obj-$(CONFIG_IIO_CONFIGFS) += industrialio-configfs.o +obj-$(CONFIG_IIO_GTS_HELPER) += industrialio-gts-helper.o obj-$(CONFIG_IIO_SW_DEVICE) += industrialio-sw-device.o obj-$(CONFIG_IIO_SW_TRIGGER) += industrialio-sw-trigger.o obj-$(CONFIG_IIO_TRIGGERED_EVENT) += industrialio-triggered-event.o
drivers/iio/industrialio-gts-helper.c new file +1064 -0
1,064 lines not on this page · raw message
include/linux/iio/iio-gts-helper.h new file +206 -0
206 lines not on this page · raw message
Signature · 14 lines
2.39.2 -- Matti Vaittinen, Linux device drivers ROHM Semiconductors, Finland SWDC Kiviharjunlenkki 1E 90220 OULU FINLAND ~~~ "I don't think so," said Rene Descartes. Just then he vanished ~~~ Simon says - in Latin please. ~~~ "non cogito me" dixit Rene Descarte, deinde evanescavit ~~~ Thanks to Simon Glass for the translation =]
Matti Vaittinen
maintainerPATCH v5 5/8 iio: test: test gain-time-scale helpers
In reply to Matti VaittinenSome light sensors can adjust both the HW-gain and integration time. There are cases where adjusting the integration time has similar impact to the scale of the reported values as gain setting has.
IIO users do typically expect to handle scale by a single writable 'scale' entry. Driver should then adjust the gain/time accordingly.
It however is difficult for a driver to know whether it should change gain or integration time to meet the requested scale. Usually it is preferred to have longer integration time which usually improves accuracy, but there may be use-cases where long measurement times can be an issue. Thus it can be preferable to allow also changing the integration time - but mitigate the scale impact by also changing the gain underneath. Eg, if integration time change doubles the measured values, the driver can reduce the HW-gain to half.
The theory of the computations of gain-time-scale is simple. However, some people (undersigned) got that implemented wrong for more than once. Hence some gain-time-scale helpers were introduced.
Add some simple tests to verify the most hairy functions.
---
Changes:
v4 => v5:
- remove empty lines from Kconfig
- adapt to drop of the non devm iio_init
- test also init with couple of invalid tables
v3 => v4:
- use dummy device to test devm interfaces
- adapt to the new header location
- drop tests for dropped interfaces
v2 => v3:
- Use namespace for iio-gts-helpers
RFCv1 => v2:
- add tests for available scales/times helpers
- adapt to renamed iio-gts-helpers.h header
--- drivers/iio/test/Kconfig | 14 + drivers/iio/test/Makefile | 1 + drivers/iio/test/iio-test-gts.c | 542 ++++++++++++++++++++++++++++++++ 3 files changed, 557 insertions(+) create mode 100644 drivers/iio/test/iio-test-gts.c
drivers/iio/test/Kconfig +14 -0
@@ -4,6 +4,20 @@ # # Keep in alphabetical order +config IIO_GTS_KUNIT_TEST + tristate "Test IIO formatting functions" if !KUNIT_ALL_TESTS + depends on KUNIT + select IIO_GTS_HELPER + select TEST_KUNIT_DEVICE_HELPERS + default KUNIT_ALL_TESTS + help + build unit tests for the IIO light sensor gain-time-scale helpers. + + For more information on KUnit and unit tests in general, please refer + to the KUnit documentation in Documentation/dev-tools/kunit/. + + If unsure, say N. Keep in alphabetical order + config IIO_RESCALE_KUNIT_TEST tristate "Test IIO rescale conversion functions" if !KUNIT_ALL_TESTS depends on KUNIT && IIO_RESCALE
drivers/iio/test/Makefile +1 -0
@@ -6,4 +6,5 @@ # Keep in alphabetical order obj-$(CONFIG_IIO_RESCALE_KUNIT_TEST) += iio-test-rescale.o obj-$(CONFIG_IIO_FORMAT_KUNIT_TEST) += iio-test-format.o +obj-$(CONFIG_IIO_GTS_KUNIT_TEST) += iio-test-gts.o CFLAGS_iio-test-format.o += $(DISABLE_STRUCTLEAK_PLUGIN)
drivers/iio/test/iio-test-gts.c new file +542 -0
542 lines not on this page · raw message
Signature · 14 lines
2.39.2 -- Matti Vaittinen, Linux device drivers ROHM Semiconductors, Finland SWDC Kiviharjunlenkki 1E 90220 OULU FINLAND ~~~ "I don't think so," said Rene Descartes. Just then he vanished ~~~ Simon says - in Latin please. ~~~ "non cogito me" dixit Rene Descarte, deinde evanescavit ~~~ Thanks to Simon Glass for the translation =]
Matti Vaittinen
maintainerRe: [PATCH v5 5/8] iio: test: test gain-time-scale helpers
Quoted 22 lines · Matti Vaittinen
Some light sensors can adjust both the HW-gain and integration time. There are cases where adjusting the integration time has similar impact to the scale of the reported values as gain setting has.
IIO users do typically expect to handle scale by a single writable 'scale' entry. Driver should then adjust the gain/time accordingly.
It however is difficult for a driver to know whether it should change gain or integration time to meet the requested scale. Usually it is preferred to have longer integration time which usually improves accuracy, but there may be use-cases where long measurement times can be an issue. Thus it can be preferable to allow also changing the integration time - but mitigate the scale impact by also changing the gain underneath. Eg, if integration time change doubles the measured values, the driver can reduce the HW-gain to half.
The theory of the computations of gain-time-scale is simple. However, some people (undersigned) got that implemented wrong for more than once. Hence some gain-time-scale helpers were introduced.
Add some simple tests to verify the most hairy functions.
Quoted 7 lines
Signed-off-by Matti Vaittinen <[email protected]>---
Changes:
v4 => v5:
- remove empty lines fromKconfig
- adapt to drop of the non devmiio_init
I think you may want to skip reviewing this specific patch. After having a chat with Greg, David, and Maxime it seems this will be changed quite a bit for v6.
Most notably, I am planning to drop the generic helpers and struct gts_test. I'll also simplify the signatures of __test_init_iio_gain_scale() and test_init_iio_gain_scale().
Yours,
-- Matti
Signature · 5 lines
Matti Vaittinen Linux kernel developer at ROHM Semiconductors Oulu Finland ~~ When things go utterly wrong vim users can always type :help! ~~
Matti Vaittinen
maintainerPATCH v5 6/8 MAINTAINERS: Add IIO gain-time-scale helpers
In reply to Matti VaittinenAdd myself as a maintainer for IIO light sensor helpers (helpers for maintaining the scale while adjusting intergration time or gain) and related Kunit tests.
---
RFCv1 =>
- No changes
--- MAINTAINERS | 8 ++++++++ 1 file changed, 8 insertions(+)
MAINTAINERS +8 -0
@@ -9938,6 +9938,14 @@ F: Documentation/ABI/testing/sysfs-bus-iio-adc-envelope-detector F: Documentation/devicetree/bindings/iio/adc/envelope-detector.yaml F: drivers/iio/adc/envelope-detector.c +IIO LIGHT SENSOR GAIN-TIME-SCALE HELPERS +M: Matti Vaittinen <[email protected]> +L: [email protected] +S: Maintained +F: drivers/iio/light/gain-time-scale-helper.c +F: drivers/iio/light/gain-time-scale-helper.h +F: drivers/iio/test/iio-test-gts.c + IIO MULTIPLEXER M: Peter Rosin <[email protected]> L: [email protected]
Signature · 14 lines
2.39.2 -- Matti Vaittinen, Linux device drivers ROHM Semiconductors, Finland SWDC Kiviharjunlenkki 1E 90220 OULU FINLAND ~~~ "I don't think so," said Rene Descartes. Just then he vanished ~~~ Simon says - in Latin please. ~~~ "non cogito me" dixit Rene Descarte, deinde evanescavit ~~~ Thanks to Simon Glass for the translation =]
Matti Vaittinen
maintainerPATCH v5 7/8 iio: light: ROHM BU27034 Ambient Light Sensor
In reply to Matti VaittinenROHM BU27034 is an ambient light sensor with 3 channels and 3 photo diodes capable of detecting a very wide range of illuminance. Typical application is adjusting LCD and backlight power of TVs and mobile phones.
Add initial support for the ROHM BU27034 ambient light sensor.
NOTE:
- Driver exposes 4 channels. One IIO_LIGHT channel providing the calculated lux values based on measured data from diodes #0 and #1. In addition, 3 IIO_INTENSITY channels are emitting the raw register data from all diodes for more intense user-space computations.
- Sensor has GAIN values that can be adjusted from 1x to 4096x.
- Sensor has adjustible measurement times of 5, 55, 100, 200 and 400 mS. Driver does not support 5 mS which has special limitations.
- Driver exposes standard 'scale' adjustment which is implemented by:
1) Trying to adjust only the GAIN
2) If GAIN adjustment alone can't provide requested scale, adjusting both the time and the gain is attempted.
- Driver exposes writable INT_TIME property that can be used for adjusting the measurement time. Time adjustment will also cause the driver to try to adjust the GAIN so that the overall scale is kept as close to the original as possible.
---
Changes
v4 => v5:
- spellcheck
- back to mlux again
- lux channel PROCESSED => RAW
- use new devm_init for GTS and drop explicit table building
- styling
- drop unnecessary loop in gain setting
- don't unnecessarily delay returning error
- fix integration time change compensation which was broken by v4 change allowing to use the (55 mS) in the time tables. (Rounding error when computing new gain based on times not multipliers).
v3 => v4:
- use min_t() for division by zero check
- adapt to new GTS helper header location
- calculate luxes not milli luxes
- drop scale for PROCESSED channel
- comment improvements
- do not allow changing gain (scale) for channel 2.
- 'tie' channel 2 scale to channel 0 scale
This is because channel 0 and channel 2 GAIN settings share part of the bits in the register. This means that setting one will also impact the other. The v3 of the patches attempted to work-around this by only disallowing the channel 2 gain setting to set the bits which were shared with channel 0 gain. This does not work because setting channel 0 gain (which was allowed to set also the shared bits) could result unsupported bit combinations for channel 2 gain. Thus it is safest to always set also the channel 2 gain to same value as channel 0 gain.
- Use the correct integration time (55 mS) in the gain table as the calcuations can be done based on the time multiplier.
- styling
v2 => v3:
- commit message update and typofixes
- switch warning messages to dbg
- drop incorrect comment about unchanged scales
- return 'no new data' if valid bit read failed
- shorten the 'div by zero' checks
- don't use u32 pointer when int * is epected in lux calculation
- add a comment clarifying why it is safe to return int from lux calculation
- simplify read_raw() by refactoring the measurement start / stop in another function and dropping the goto based unlocking.
- Styling fixes
- select IIO_BUFFER and IIO_KFIFO_BUF
- Alphabetical order of header includes
- Split multipication w/ overflow check to own function
- Do not hang in read_raw() if sensor does not return valid sample
- Spelling fix
- Do not require fwnode
- Use namespace for gts helpers
RFCv1 => v2:
- (really) protect read-only registers
- fix get and set gain
- buffered mode
- Protect the whole sequences including meas_en/meas_dis to avoid messing up the enable / disable order
- typofixes / doc improvements
- change dropped GAIN_SCALE_ITIME_MS() to GAIN_SCALE_ITIME_US()
- use more accurate scale for lux channel (milli lux)
- provide available scales / integration times (using helpers).
- adapt to renamed iio-gts-helpers.h file
- bu27034 - longer lines in Kconfig
- Drop bu27034_meas_en and bu27034_meas_dis wrappers.
- Change device-name from bu27034-als to bu27034
--- drivers/iio/light/Kconfig | 14 + drivers/iio/light/Makefile | 1 + drivers/iio/light/rohm-bu27034.c | 1482 ++++++++++++++++++++++++++++++ 3 files changed, 1497 insertions(+) create mode 100644 drivers/iio/light/rohm-bu27034.c
drivers/iio/light/Kconfig +14 -0
@@ -289,6 +289,20 @@ config JSA1212 To compile this driver as a module, choose M here: the module will be called jsa1212. +config ROHM_BU27034 + tristate "ROHM BU27034 ambient light sensor" + depends on I2C + select REGMAP_I2C + select IIO_GTS_HELPER + select IIO_BUFFER + select IIO_KFIFO_BUF + help + Enable support for the ROHM BU27034 ambient light sensor. ROHM BU27034 + is an ambient light sesnor with 3 channels and 3 photo diodes capable + of detecting a very wide range of illuminance. + Typical application is adjusting LCD and backlight power of TVs and + mobile phones. + config RPR0521 tristate "ROHM RPR0521 ALS and proximity sensor driver" depends on I2C
drivers/iio/light/Makefile +1 -0
@@ -38,6 +38,7 @@ obj-$(CONFIG_MAX44009) += max44009.o obj-$(CONFIG_NOA1305) += noa1305.o obj-$(CONFIG_OPT3001) += opt3001.o obj-$(CONFIG_PA12203001) += pa12203001.o +obj-$(CONFIG_ROHM_BU27034) += rohm-bu27034.o obj-$(CONFIG_RPR0521) += rpr0521.o obj-$(CONFIG_SI1133) += si1133.o obj-$(CONFIG_SI1145) += si1145.o
drivers/iio/light/rohm-bu27034.c new file +1482 -0
1,482 lines not on this page · raw message
Signature · 14 lines
2.39.2 -- Matti Vaittinen, Linux device drivers ROHM Semiconductors, Finland SWDC Kiviharjunlenkki 1E 90220 OULU FINLAND ~~~ "I don't think so," said Rene Descartes. Just then he vanished ~~~ Simon says - in Latin please. ~~~ "non cogito me" dixit Rene Descarte, deinde evanescavit ~~~ Thanks to Simon Glass for the translation =]
Jonathan Cameron
maintainerRe: [PATCH v5 7/8] iio: light: ROHM BU27034 Ambient Light Sensor
Quoted 27 lines · On Wed, 22 Mar 2023 11:07:56 +0200 Matti Vaittinen <[email protected]>…
ROHM BU27034 is an ambient light sensor with 3 channels and 3 photo diodes capable of detecting a very wide range of illuminance. Typical application is adjusting LCD and backlight power of TVs and mobile phones.
Add initial support for the ROHM BU27034 ambient light sensor.
NOTE:
- Driver exposes 4 channels. OneIIO_LIGHTchannel providing the calculated lux values based on measured data from diodes #0 and #1. In addition, 3IIO_INTENSITYchannels are emitting the raw register data from all diodes for more intense user-space computations.
- Sensor has GAIN values that can be adjusted from 1x to 4096x.
- Sensor has adjustible measurement times of 5, 55, 100, 200 and 400 mS. Driver does not support 5 mS which has special limitations.
- Driver exposes standard 'scale' adjustment which is implemented by:
1) Trying to adjust only the GAIN
2) If GAIN adjustment alone can't provide requested scale, adjusting both the time and the gain is attempted.
- Driver exposes writableINT_TIMEproperty that can be used for adjusting the measurement time. Time adjustment will also cause the driver to try to adjust the GAIN so that the overall scale is kept as close to the original as possible.
Quoted 2 lines
Signed-off-by Matti Vaittinen <[email protected]>
Hi Matti,
A few minor comments inline. I'll take a closer look at the rest of the series when the discussions around the tests and devices to be used for them settle down.
Thanks,
Jonathan
Quoted 8 lines
drivers/iio/light/rohm-bu27034.c new file +8
-0+ +static u64 bu27034_fixp_calc_t1 (unsigned int coeff,unsigned int ch0, +unsigned int ch1,unsigned int gain0, +unsigned int gain1) +{ +unsigned int helper, tmp; +u64 helper64; +
drivers/iio/light/rohm-bu27034.c line 833
Quoted 10 lines
drivers/iio/light/rohm-bu27034.c new file +10
-0+/* +* Here we could overflow even the 64bit value. Hence we +* multiply with gain0 only after the divisions - even though +* it may result loss of accuracy +*/ + helper64 = (u64 )coeff * (u64 )ch1 * (u64 )ch1; + helper = coeff * ch1 * ch1; + tmp = helper * gain0; + +if (helper == helper64 && (tmp / gain0 == helper))
Similar to below. Don't bother with the non 64 bit version.
Quoted 19 lines
drivers/iio/light/rohm-bu27034.c new file +19
-0+return tmp / (gain1 * gain1) / ch0; + + helper = gain1 * gain1; +if (helper > ch0) { +do_div (helper64, helper); + +return gain_mul_div_helper (helper64, gain0, ch0); + } + +do_div (helper64, ch0); + +return gain_mul_div_helper (helper64, gain0, helper); +} + +static u64 bu27034_fixp_calc_t23 (unsigned int coeff,unsigned int ch, +unsigned int gain) +{ +unsigned int helper; +u64 helper64;
drivers/iio/light/rohm-bu27034.c line 862
Quoted 10 lines
drivers/iio/light/rohm-bu27034.c new file +10
-0+ + helper64 = (u64 )coeff * (u64 )ch; + helper = coeff * ch; + +if (helper == helper64) +return helper / gain; + +do_div (helper64, gain); + +return helper64;
I suspect that this is a premature bit of optimization so I'd just do it in 64 bits always.
Also, if you did want to do this, check_mul_overflow() etc would help. (linux/overflow.h)
drivers/iio/light/rohm-bu27034.c line 1065
Quoted 8 lines
drivers/iio/light/rohm-bu27034.c new file +7
-0+} + +static int bu27034_calc_mlux (struct bu27034_data *data,__le16 *res,int *val) +{ +unsigned int gain0, gain1, meastime; +unsigned int d1_d0_ratio_scaled; +u16 ch0, ch1;
Stray space after the u16
drivers/iio/light/rohm-bu27034.c line 1070
Quoted 5 lines
drivers/iio/light/rohm-bu27034.c new file +5
-0+u64 helper64; +int ret; + +/* +* We return 0 luxes if calculation fails. This should be reasonably
0 lux
(I think)
Quoted 3 lines
drivers/iio/light/rohm-bu27034.c new file +3
-0+* easy to spot from the buffers especially if raw-data channels show +* valid values +*/
Re: [PATCH v5 7/8] iio: light: ROHM BU27034 Ambient Light Sensor
Quoted 87 lines · Jonathan Cameron
Quoted 27 lines · On Wed, 22 Mar 2023 11:07:56 +0200 Matti Vaittinen <[email protected]>…
ROHM BU27034 is an ambient light sensor with 3 channels and 3 photo diodes capable of detecting a very wide range of illuminance. Typical application is adjusting LCD and backlight power of TVs and mobile phones.
Add initial support for the ROHM BU27034 ambient light sensor.
NOTE:
- Driver exposes 4 channels. OneIIO_LIGHTchannel providing the calculated lux values based on measured data from diodes #0 and #1. In addition, 3IIO_INTENSITYchannels are emitting the raw register data from all diodes for more intense user-space computations.
- Sensor has GAIN values that can be adjusted from 1x to 4096x.
- Sensor has adjustible measurement times of 5, 55, 100, 200 and 400 mS. Driver does not support 5 mS which has special limitations.
- Driver exposes standard 'scale' adjustment which is implemented by:
1) Trying to adjust only the GAIN
2) If GAIN adjustment alone can't provide requested scale, adjusting both the time and the gain is attempted.
- Driver exposes writableINT_TIMEproperty that can be used for adjusting the measurement time. Time adjustment will also cause the driver to try to adjust the GAIN so that the overall scale is kept as close to the original as possible.Quoted 2 lines
Signed-off-by Matti Vaittinen <[email protected]>Hi Matti,
A few minor comments inline. I'll take a closer look at the rest of the series when the discussions around the tests and devices to be used for them settle down.
Thanks,
Jonathan
Quoted 8 lines
drivers/iio/light/rohm-bu27034.c new file +8
-0+ +static u64 bu27034_fixp_calc_t1 (unsigned int coeff,unsigned int ch0, +unsigned int ch1,unsigned int gain0, +unsigned int gain1) +{ +unsigned int helper, tmp; +u64 helper64; +drivers/iio/light/rohm-bu27034.c line 833
Quoted 10 lines
drivers/iio/light/rohm-bu27034.c new file +10
-0+/* +* Here we could overflow even the 64bit value. Hence we +* multiply with gain0 only after the divisions - even though +* it may result loss of accuracy +*/ + helper64 = (u64 )coeff * (u64 )ch1 * (u64 )ch1; + helper = coeff * ch1 * ch1; + tmp = helper * gain0; + +if (helper == helper64 && (tmp / gain0 == helper))Similar to below. Don't bother with the non 64 bit version.
Quoted 24 lines
drivers/iio/light/rohm-bu27034.c new file +24
-0+return tmp / (gain1 * gain1) / ch0; + + helper = gain1 * gain1; +if (helper > ch0) { +do_div (helper64, helper); + +return gain_mul_div_helper (helper64, gain0, ch0); + } + +do_div (helper64, ch0); + +return gain_mul_div_helper (helper64, gain0, helper); +} + +static u64 bu27034_fixp_calc_t23 (unsigned int coeff,unsigned int ch, +unsigned int gain) +{ +unsigned int helper; +u64 helper64; + + helper64 = (u64 )coeff * (u64 )ch; + helper = coeff * ch; + +if (helper == helper64)
Quoted 8 lines
drivers/iio/light/rohm-bu27034.c line 862
Quoted 5 lines
drivers/iio/light/rohm-bu27034.c new file +5
-0+return helper / gain; + +do_div (helper64, gain); + +return helper64;I suspect that this is a premature bit of optimization so I'd just do it in 64 bits always.
Probably so.
Quoted 3 lines
Also, if you did want to do this,
check_mul_overflow()etc would help. (linux/overflow.h)
Thanks! I'll check the overflow.h
The only reason why I did it like this is that I've been bitten badly by the do_div() in the past. It was actually quite expensive payment for a lesson learnt - my do_div() usage ended up in a customer devices in the field - and with a bit of bad luck we got a huge number to be divided with a small one... And the do_div() implementation for the architecture was a loop subtracting the divider.
The thing ended up halting the customer devices for many seconds, messing up lots of things. On top of that the project was huge - Amount of SW-developers was four figures. It took weeks until the bug report found it's way also to my desk - at which point I finally found the mistake I had made... And I didn't feel proud of it :|
And yes, we don't prevent the "divide big number by a tiny one" - issue by this check here. OTOH, I think I didn't see the loop-based do_div() implementation anymore either. It's just the habit of only using do_div() as a last resort. But yes, we probably can unconditionally use the do_div() here. I'll see what we have in the overflow.h though.
Thanks for the review again!
Yours,
-- Matti
Signature · 5 lines
Matti Vaittinen Linux kernel developer at ROHM Semiconductors Oulu Finland ~~ When things go utterly wrong vim users can always type :help! ~~
Matti Vaittinen
maintainerPATCH v5 8/8 MAINTAINERS: Add ROHM BU27034
In reply to Matti VaittinenAdd myself as a maintainer for ROHM BU27034 ALS driver.
---
Changes
v2 =>
- No changes
sRFCv1 => v2:
- Add iio-list
--- MAINTAINERS | 6 ++++++ 1 file changed, 6 insertions(+)
MAINTAINERS +6 -0
@@ -18100,6 +18100,12 @@ S: Maintained F: Documentation/devicetree/bindings/iio/light/bh1750.yaml F: drivers/iio/light/bh1750.c +ROHM BU27034 AMBIENT LIGHT SENSOR DRIVER +M: Matti Vaittinen <[email protected]> +L: [email protected] +S: Supported +F: drivers/iio/light/rohm-bu27034.c + ROHM MULTIFUNCTION BD9571MWV-M PMIC DEVICE DRIVERS M: Marek Vasut <[email protected]> L: [email protected]
Signature · 14 lines
2.39.2 -- Matti Vaittinen, Linux device drivers ROHM Semiconductors, Finland SWDC Kiviharjunlenkki 1E 90220 OULU FINLAND ~~~ "I don't think so," said Rene Descartes. Just then he vanished ~~~ Simon says - in Latin please. ~~~ "non cogito me" dixit Rene Descarte, deinde evanescavit ~~~ Thanks to Simon Glass for the translation =]
Quoted 6 lines · Matti Vaittinen
Revision history:
v4 => v5: Mostly fixes to review comments from Andy and Jonathan.
- more accurate change-log in individual patches- copy code from DRM test helper instead of moving it to simplify merging
1) Why do you think this is a problem?
2) How would we avoid spreading more copies of the same code in the future?
1) Merge conflicts is not a bad thing. It shows that people tested their code in isolation and stabilized it before submitting to the upper maintainer.
https://yarchive.net/comp/linux/git_merges_from_upstream.html
2) Spreading the same code when we _know_ this, should be very well justified. Merge conflict is an administrative point, and not a technical obstacle to avoid.
Quoted 4 lines
- document all exported GTS helpers.
- inline a few GTS helpers
- use again Milli lux for the bu27034 with RAWIIO_LIGHTchannel and scale
- Fix bug from added in v4 bu27034 time setting.
Signature · 2 lines
With Best Regards, Andy Shevchenko
Andy Shevchenko <[email protected]> writes:
Hello Andy,
Quoted 13 lines · Matti Vaittinen
Quoted 7 lines
Revision history:
v4 => v5: Mostly fixes to review comments from Andy and Jonathan.
- more accurate change-log in individual patches- copy code from DRM test helper instead of moving it to simplify merging
1) Why do you think this is a problem?
2) How would we avoid spreading more copies of the same code in the future?
Quoted 9 lines
1) Merge conflicts is not a bad thing. It shows that people tested their code in isolation and stabilized it before submitting to the upper maintainer.
https://yarchive.net/comp/linux/git_merges_from_upstream.html
2) Spreading the same code when we _know_ this, should be very well justified. Merge conflict is an administrative point, and not a technical obstacle to avoid.
I believe this was suggested by Maxime and the rationale is that by just copying the helpers for now, that would make it easier to land instead of requiring coordination between different subystems.
Otherwise the IIO tree will need to provide an inmutable branch for the DRM tree to merge and so on.
I agree with Maxime that a little bit of duplication (that can be cleaned up by each subsystem at their own pace) is the path of least resistance.
Signature · 5 lines
Best regards, Javier Martinez Canillas Core Platforms Red Hat
Matti Vaittinen
maintainerQuoted 25 lines · Javier Martinez Canillas
Andy Shevchenko <[email protected]> writes:
Hello Andy,
Quoted 21 lines · Matti Vaittinen
Quoted 7 lines
Revision history:
v4 => v5: Mostly fixes to review comments from Andy and Jonathan.
- more accurate change-log in individual patches- copy code from DRM test helper instead of moving it to simplify merging
1) Why do you think this is a problem?
2) How would we avoid spreading more copies of the same code in the future?1) Merge conflicts is not a bad thing. It shows that people tested their code in isolation and stabilized it before submitting to the upper maintainer.
https://yarchive.net/comp/linux/git_merges_from_upstream.html
2) Spreading the same code when we _know_ this, should be very well justified. Merge conflict is an administrative point, and not a technical obstacle to avoid.
I definitely agree. This is also why I did the renaming and not copying in the first version. In this version I did still add the subsequent patch 2/8 - which drops the duplicates from DRM tree.
Quoted 3 lines
I believe this was suggested by Maxime and the rationale is that by just copying the helpers for now, that would make it easier to land instead of requiring coordination between different subystems.
This is correct.
Quoted 2 lines
Otherwise the IIO tree will need to provide an inmutable branch for the DRM tree to merge and so on.
Or, if we carry the patch 1/8 via self-test tree, then we get even more players here.
Still, I am not opposing immutable branch because that would allow fast applying of the patch 2/8 as well. Longer that is delayed, more likely we will see more users of the DRM helpers and harder it gets to remove the duplicates later.
Quoted 2 lines
I agree with Maxime that a little bit of duplication (that can be cleaned up by each subsystem at their own pace) is the path of least resistance.
I'd say this depends. It probably is the path of least resistance for people maintaining the trees. It can also be the path of least resistance in general - but it depends on if there will be no new users for those DRM helpers while waiting the new APIs being merged in DRM tree. More users we see in DRM, more effort the clean-up requires.
I have no strong opinion on this specific case. I'd just be happy to see the IIO tests getting in preferably sooner than later - although 'soon' and 'late' does also depend on other factors besides these helpers...
Yours,
-- Matti
Signature · 5 lines
Matti Vaittinen Linux kernel developer at ROHM Semiconductors Oulu Finland ~~ When things go utterly wrong vim users can always type :help! ~~
Quoted 2 lines · Matti Vaittinen
Quoted 1 line · Javier Martinez Canillas
Quoted 1 line · Matti Vaittinen
...
Quoted 46 lines
Quoted 7 lines
Quoted 7 lines
Quoted 2 lines
- copy code from DRM test helper instead of moving it to simplify merging
1) Why do you think this is a problem?
2) How would we avoid spreading more copies of the same code in the future?Quoted 8 lines
Quoted 8 lines
1) Merge conflicts is not a bad thing. It shows that people tested their code in isolation and stabilized it before submitting to the upper maintainer.
https://yarchive.net/comp/linux/git_merges_from_upstream.html
2) Spreading the same code when we _know_ this, should be very well justified. Merge conflict is an administrative point, and not a technical obstacle to avoid.
I definitely agree. This is also why I did the renaming and not copying in the first version. In this version I did still add the subsequent patch 2/8
- which drops the duplicates from DRM tree.Quoted 3 lines
I believe this was suggested by Maxime and the rationale is that by just copying the helpers for now, that would make it easier to land instead of requiring coordination between different subystems.
This is correct.
Quoted 2 lines
Otherwise the IIO tree will need to provide an inmutable branch for the DRM tree to merge and so on.
Or, if we carry the patch 1/8 via self-test tree, then we get even more players here.
Still, I am not opposing immutable branch because that would allow fast applying of the patch 2/8 as well. Longer that is delayed, more likely we will see more users of the DRM helpers and harder it gets to remove the duplicates later.
Quoted 2 lines
I agree with Maxime that a little bit of duplication (that can be cleaned up by each subsystem at their own pace) is the path of least resistance.
I'd say this depends. It probably is the path of least resistance for people maintaining the trees. It can also be the path of least resistance in general - but it depends on if there will be no new users for those DRM helpers while waiting the new APIs being merged in DRM tree. More users we see in DRM, more effort the clean-up requires.
Quoted 3 lines
I have no strong opinion on this specific case. I'd just be happy to see the IIO tests getting in preferably sooner than later - although 'soon' and 'late' does also depend on other factors besides these helpers...
Since I'm not a maintainer of either, and one of them requires something, I can't oppose.
Signature · 2 lines
With Best Regards, Andy Shevchenko
Quoted 8 lines · Matti Vaittinen
Quoted 2 lines
I agree with Maxime that a little bit of duplication (that can be cleaned up by each subsystem at their own pace) is the path of least resistance.
I'd say this depends. It probably is the path of least resistance for people maintaining the trees. It can also be the path of least resistance in general - but it depends on if there will be no new users for those DRM helpers while waiting the new APIs being merged in DRM tree. More users we see in DRM, more effort the clean-up requires.
So far there's one user in DRM, and I'm not aware of any current work using it at the moment. Even if some show up in the short-term future, it's not going to be overwhelming.
Maxime