mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Krzysztof Kozlowski <krzk@kernel.org>
To: Abdurrahman Hussain <abdurrahman@nexthop.ai>
Cc: Rob Herring <robh@kernel.org>,
	Saravana Kannan <saravanak@kernel.org>,
	 devicetree@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v4 2/6] of: incrementally update /aliases lookup on reconfig notifications
Date: Wed, 22 Jul 2026 09:35:56 +0200	[thread overview]
Message-ID: <20260722-light-modest-mosquito-cd4f0a@quoll> (raw)
In-Reply-To: <20260721-nh-of-alias-overlay-v4-2-8ad097e31e36@nexthop.ai>

On Tue, Jul 21, 2026 at 06:01:47PM -0700, Abdurrahman Hussain wrote:
> /aliases entries added by a device-tree overlay are stored in the live
> tree but never enter the global aliases_lookup list that of_alias_scan()
> builds at boot. As a result, of_alias_get_id() returns -ENODEV for
> aliases declared inside overlays, and any driver that relies on
> alias-based numbering (i2c-xiic, spi, tty, mmc, ...) silently loses its
> pinned id and falls back to auto-assignment.
> 
> Fix by registering an internal OF reconfig notifier that mirrors
> /aliases changes into aliases_lookup. Registration happens at
> core_initcall_sync time, safely after the boot-time of_alias_scan(),
> which runs pre-initcall from unflatten_device_tree() (or
> of_pdt_build_devicetree() on OF-real platforms):
> 
>   OF_RECONFIG_ADD_PROPERTY    -> of_alias_create()
>   OF_RECONFIG_REMOVE_PROPERTY -> of_alias_destroy()
>   OF_RECONFIG_UPDATE_PROPERTY -> destroy + create
>   OF_RECONFIG_ATTACH_NODE     -> adopt the node as of_aliases
>   OF_RECONFIG_DETACH_NODE     -> drop every aliases_lookup entry
> 
> The reconfig notifier chain fires from both direct changesets and
> overlay apply/revert, so the same code path covers runtime dt
> modifications and overlay-declared aliases without any overlay-
> specific hook in drivers/of/overlay.c. Grant Likely suggested this
> shape on Geert Uytterhoeven's 2015 RFC [1]; Geert's original hook was
> in dynamic.c directly.
> 
> Match the /aliases target node structurally (exact name "aliases",
> parent == root, via the shared of_node_is_aliases()) rather than by
> pointer against the of_aliases global. A system with no boot-time
> /aliases has of_aliases == NULL, so an overlay that creates /aliases
> from scratch would otherwise be missed from the first ATTACH_NODE
> onward. The name compare is exact rather than of_node_name_eq():
> the latter ignores unit addresses and would also match a root node
> named "aliases@1", which neither path lookup nor the DT spec treats
> as the aliases node. ATTACH publishes the adopted node
> in of_aliases with a reference held; DETACH clears the pointer and
> drops that reference again. Both pointer updates happen under
> devtree_lock, pairing with the locked reader in
> of_find_node_opts_by_path() from the previous patch — a reader either
> observes NULL or takes its own reference before the notifier's put
> can be the last one. Dropping the reference at DETACH also keeps the
> node at refcount 1 by the time an overlay changeset that created
> /aliases is destroyed, which __of_changeset_entry_destroy() insists
> on before it lets the node be freed.
> 
> Only per-property notifications populate aliases_lookup —
> the notifier does not walk the attached node's property list, which
> would race with devtree_lock-protected property mutations. A direct
> of_attach_node() caller that pre-populates /aliases is not tracked,
> matching pre-series behavior.
> 
> DETACH_NODE conversely drops every aliases_lookup entry — but only
> when the detached node is the tracked of_aliases. __of_attach_node()
> has no duplicate-name check, so a stray second root node named
> "aliases" can exist; detaching it must not wipe entries backed by the
> real node. Walking aliases_lookup itself (under aliases_mutex) avoids
> the same property-list race. Overlay revert additionally emits per-
> property REMOVE events beforehand; the sweep catches direct
> of_detach_node() callers that don't. The per-entry teardown is
> factored into __of_alias_del(), shared by the single-name destroy and
> the detach-time sweep.
> 
> One ordering caveat is inherent to the notification architecture:
> within a single changeset, a device created by an earlier ATTACH
> entry can be probed by of_platform_notify() before a later /aliases
> ADD_PROPERTY entry reaches this notifier. Overlays that declare an
> alias for a node they also create should order the /aliases fragment
> first if the target bus is populated with a bound driver at apply
> time.
> 
> The notifier machinery is built only for CONFIG_OF_DYNAMIC kernels:
> without it no reconfig notifications exist and
> of_reconfig_notifier_register() is a stub returning -EINVAL, so an
> unconditional registration would fail the initcall on every
> non-dynamic DT kernel.
> 
> Factor the per-property loop body of of_alias_scan() into
> of_alias_create() so the boot-time scan and the runtime notifier
> share one code path. Owned (runtime) entries kstrdup the alias name
> so the alias_prop survives the property that spawned it — required
> for the overlay revert path where the source property is freed. A
> one-bit @owned flag on struct alias_prop distinguishes kmalloc'd
> entries from memblock-backed ones so the destroy path kfree()s the
> right ones. Every entry, boot-time or runtime, holds the target-node
> reference that of_find_node_by_path() returned at create time;
> destroy drops it symmetrically.
> 
> The destroy path unlinks matching entries regardless of ownership
> (freeing storage only for owned ones) so an overlay UPDATE against a
> boot-time alias leaves at most one entry per stem+id. This addresses
> the allocator-mismatch worry Grant flagged on the 2015 series [2] and
> the duplicate-mapping side effect that would otherwise leak through.
> 
> Serialize aliases_lookup on a dedicated aliases_mutex: readers
> (of_alias_get_id, of_alias_get_highest_id, of_device_uevent) and the
> reconfig notifier hold it around every access. Boot-time
> of_alias_scan() runs single-threaded during init and stays lockless.
> This is preferable to piggy-backing on of_mutex because the reconfig
> notifier is called both under of_mutex (overlay apply path) and
> outside of it (direct of_add_property() path from dynamic.c), so a
> nested acquisition would deadlock on some callers.
> 
> Validate the property value before feeding it to of_find_node_by_path():
> pp->value must be non-empty and null-terminated within pp->length. An
> overlay that hasn't been through /aliases fixup can otherwise present
> a fragment-internal string that isn't a valid live-tree path or a
> malformed non-terminated value, and of_find_node_by_path() derefs it
> as a C string — an OOB read on the malformed case.
> 
> The refactor also fixes a pre-existing one-byte out-of-bounds read in
> the stem parser: the old loop tested isdigit(*(end - 1)) before
> checking end > start, reading one byte before the property name when
> the name is empty or all digits. of_alias_create() checks the bound
> first and rejects a zero-length stem.
> 
> Naming builds on Geert's original series:
>   - "of: Extract of_alias_create()"                     [3]
>   - "of: Add of_alias_destroy()"                        [4]
>   - "of/dynamic: Update list of aliases on aliases changes" [5]

This is not a contest who can ask AI to create the longest commit msg
ever.

You need to configure your LLM properly to Linux kernel coding style.

Best regards,
Krzysztof


  reply	other threads:[~2026-07-22  7:36 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-22  1:01 [PATCH v4 0/6] of: teach overlay code to keep /aliases in sync Abdurrahman Hussain
2026-07-22  1:01 ` [PATCH v4 1/6] of: resolve alias-prefixed paths under devtree_lock Abdurrahman Hussain
2026-07-22  7:30   ` Krzysztof Kozlowski
2026-07-22 19:09     ` Abdurrahman Hussain
2026-07-22  1:01 ` [PATCH v4 2/6] of: incrementally update /aliases lookup on reconfig notifications Abdurrahman Hussain
2026-07-22  7:35   ` Krzysztof Kozlowski [this message]
2026-07-22  1:01 ` [PATCH v4 3/6] of/overlay: look up absolute target-paths absolutely Abdurrahman Hussain
2026-07-22  1:01 ` [PATCH v4 4/6] of/overlay: return ERR_PTR from dup_and_fixup_symbol_prop() Abdurrahman Hussain
2026-07-22  7:36   ` Krzysztof Kozlowski
2026-07-22 19:09     ` Abdurrahman Hussain
2026-07-22  1:01 ` [PATCH v4 5/6] of/overlay: rewrite /aliases path values to live-tree paths Abdurrahman Hussain
2026-07-22  1:01 ` [PATCH v4 6/6] of: unittest: cover /aliases updates from overlay apply/revert Abdurrahman Hussain

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260722-light-modest-mosquito-cd4f0a@quoll \
    --to=krzk@kernel.org \
    --cc=abdurrahman@nexthop.ai \
    --cc=devicetree@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=robh@kernel.org \
    --cc=saravanak@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®