[PATCH v6 10/10] of: unittest: cover /aliases updates from overlay apply/revert
Abdurrahman Hussain <[email protected]>
| Newsgroups | gmane.linux.drivers.devicetree,gmane.linux.kernel |
|---|---|
| Message-ID | <[email protected]> |
Add overlay_alias.dtso and of_unittest_overlay_alias(). The overlay has two fragments: target-path="" grafts a labeled node under the run-time target base, and target-path="/aliases" adds `testcase-alias99 = &<label>` at the DT root. The runner applies it with a non-NULL base via of_overlay_fdt_apply() (overlay_data_apply() always passes NULL), asserts of_alias_get_id() on the grafted node returns 99, reverts, and asserts of_alias_get_highest_id() reports the stem gone. A precondition check runs before the apply. This exercises the reconfig notifier, the absolute target-path lookup, and the /aliases value rewrite together; any one missing turns the get_id assertion into -ENODEV. The grafted-node reference is dropped before of_overlay_remove(): overlay-created nodes must be back at refcount 1 when the changeset is destroyed. The post-remove assertion uses of_alias_get_highest_id() because it is keyed by stem and needs no node reference. The apply is wrapped in EXPECT_BEGIN/END for the "memory leak will occur" warning printed for properties added to nodes the overlay didn't create, like the other overlay tests. The overlay is not added to the fdtoverlay static build test: fdtoverlay has no target-base concept, so the empty target-path cannot be resolved statically. Assisted-by: Claude:claude-fable-5 [Claude Code] Signed-off-by: Abdurrahman Hussain <[email protected]> --- drivers/of/unittest-data/Makefile | 5 ++ drivers/of/unittest-data/overlay_alias.dtso | 25 ++++++++++ drivers/of/unittest.c | 73 +++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+) diff --git a/drivers/of/unittest-data/Makefile b/drivers/of/unittest-data/Makefile index 01a966e39f23..fdfec5a7923b 100644 --- a/drivers/of/unittest-data/Makefile +++ b/drivers/of/unittest-data/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_OF_OVERLAY) += overlay.dtbo.o \ overlay_18.dtbo.o \ overlay_19.dtbo.o \ overlay_20.dtbo.o \ + overlay_alias.dtbo.o \ overlay_bad_add_dup_node.dtbo.o \ overlay_bad_add_dup_prop.dtbo.o \ overlay_bad_phandle.dtbo.o \ @@ -66,6 +67,10 @@ DTC_FLAGS_testcases += -Wno-interrupts_property \ # overlay_bad_add_dup_prop.dtbo \ # overlay_bad_phandle.dtbo \ # overlay_bad_symbol.dtbo \ +# +# overlay_alias.dtbo needs a run-time target base for its empty target-path; +# fdtoverlay has no equivalent, so it is also not included: +# overlay_alias.dtbo \ apply_static_overlay_1 := overlay_0.dtbo \ overlay_1.dtbo \ diff --git a/drivers/of/unittest-data/overlay_alias.dtso b/drivers/of/unittest-data/overlay_alias.dtso new file mode 100644 index 000000000000..17e02d1940f6 --- /dev/null +++ b/drivers/of/unittest-data/overlay_alias.dtso @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +/plugin/; + +/* + * overlay_alias - declare an /aliases entry that points, via label, at a + * node grafted under the run-time target base (empty target-path). + */ + +/ { + fragment@0 { + target-path = ""; + __overlay__ { + testcase_target: alias-target { + }; + }; + }; + + fragment@1 { + target-path = "/aliases"; + __overlay__ { + testcase-alias99 = &testcase_target; + }; + }; +}; diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index e255f54f4d76..2f5e4056efae 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -3475,6 +3475,77 @@ static struct notifier_block of_nb = { .notifier_call = of_notify, }; +/* created by cmd_wrap_S_dtbo in scripts/Makefile.dtbs */ +extern uint8_t __dtbo_overlay_alias_begin[]; +extern uint8_t __dtbo_overlay_alias_end[]; + +static void __init of_unittest_overlay_alias(void) +{ + const char *base_path = + "/testcase-data/overlay-node/test-bus/test-unittest100"; + const char *target_path = + "/testcase-data/overlay-node/test-bus/test-unittest100/alias-target"; + u32 size = __dtbo_overlay_alias_end - __dtbo_overlay_alias_begin; + struct device_node *base, *target; + int ovcs_id = 0; + int id, ret; + + base = of_find_node_by_path(base_path); + if (!base) { + unittest(0, "could not find alias target base %s\n", base_path); + return; + } + + id = of_alias_get_highest_id("testcase-alias"); + if (id != -ENODEV) { + unittest(0, "unexpected testcase-alias%d before overlay apply\n", + id); + goto out_put_base; + } + + EXPECT_BEGIN(KERN_INFO, + "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /aliases/testcase-alias99"); + + ret = of_overlay_fdt_apply(__dtbo_overlay_alias_begin, size, + &ovcs_id, base); + + EXPECT_END(KERN_INFO, + "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /aliases/testcase-alias99"); + + if (ret < 0) { + unittest(0, "overlay_alias apply failed, ret = %d\n", ret); + if (ovcs_id) + of_overlay_remove(&ovcs_id); + goto out_put_base; + } + + target = of_find_node_by_path(target_path); + if (!target) { + unittest(0, "could not find grafted target %s\n", target_path); + } else { + id = of_alias_get_id(target, "testcase-alias"); + unittest(id == 99, + "of_alias_get_id() = %d after overlay apply, expected 99\n", + id); + /* changeset destroy expects overlay nodes back at refcount 1 */ + of_node_put(target); + } + + ret = of_overlay_remove(&ovcs_id); + if (ret) { + unittest(0, "overlay_alias remove failed, ret = %d\n", ret); + goto out_put_base; + } + + id = of_alias_get_highest_id("testcase-alias"); + unittest(id == -ENODEV, + "of_alias_get_highest_id() = %d after overlay remove, expected -ENODEV\n", + id); + +out_put_base: + of_node_put(base); +} + static void __init of_unittest_overlay_notify(void) { int ovcs_id; @@ -3649,6 +3720,8 @@ static void __init of_unittest_overlay(void) of_unittest_overlay_gpio(); + of_unittest_overlay_alias(); + of_unittest_remove_tracked_overlays(); of_unittest_overlay_notify(); -- 2.54.0