From: Johan Hovold <johan@kernel.org>
To: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Cc: Srinivas Kandagatla <srini@kernel.org>,
Bartosz Golaszewski <brgl@kernel.org>,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH v2 7/7] nvmem: synchronize nvmem device unregistering with SRCU
Date: Tue, 17 Mar 2026 12:31:24 +0100 [thread overview]
Message-ID: <abk7jM22_8qnmUkZ@hovoldconsulting.com> (raw)
In-Reply-To: <20260223-nvmem-unbind-v2-7-0df33a933dca@oss.qualcomm.com>
On Mon, Feb 23, 2026 at 11:57:08AM +0100, Bartosz Golaszewski wrote:
> With the provider-owned data split out into a separate structure, we can
> now protect it with SRCU.
>
> Protect all dereferences of nvmem->impl with an SRCU read lock.
> Synchronize SRCU in nvmem_unregister() after setting the implementation
> pointer to NULL. This has the effect of numbing down the device after
> nvmem_unregister() returns - it will no longer accept any consumer calls
> and return -ENODEV. The actual device will live on for as long as there
> are references to it but we will no longer reach into the consumer's
> memory which may be gone by this time.
>
> The change has the added benefit of dropping the - now redundant -
> reference counting with kref. We are left with a single release()
> function depending on the kobject reference counting provided by struct
> device.
You're actually fixing two separate issues here. And one of those issues
stem from the broken kref implementation added by:
c1de7f43bd84 ("nvmem: use kref")
Sure, the code was already broken (by returning -EBUSY when there were
references) but the above commit deferred deregistration until the last
reference is gone which is just wrong.
So the first issue is the deferred deregistration (kref) which allows
further lookups after the provider is gone and which keeps the sysfs
interface around which can lead to use-after-free.
The second issue is that other driver can try to access the nvmem after
it's gone and that bit you can fix with SRCU. But note that you don't
need that for sysfs as kernfs already drains any active user at
deregistration.
So I think this should be split in two after dropping some of the
unnecessary sysfs bits.
> @@ -289,10 +298,14 @@ static ssize_t bin_attr_nvmem_write(struct file *filp, struct kobject *kobj,
>
> static umode_t nvmem_bin_attr_get_umode(struct nvmem_device *nvmem)
> {
> - struct nvmem_impl *impl = nvmem->impl;
> -
> + struct nvmem_impl *impl;
> umode_t mode = 0400;
>
> + guard(srcu)(&nvmem->srcu);
> + impl = rcu_dereference(nvmem->impl);
> + if (!impl)
> + return 0;
> +
> if (!nvmem->root_only)
> mode |= 0044;
>
> @@ -333,7 +346,12 @@ static umode_t nvmem_attr_is_visible(struct kobject *kobj,
> {
> struct device *dev = kobj_to_dev(kobj);
> struct nvmem_device *nvmem = to_nvmem_device(dev);
> - struct nvmem_impl *impl = nvmem->impl;
> + struct nvmem_impl *impl;
> +
> + guard(srcu)(&nvmem->srcu);
> + impl = rcu_dereference(nvmem->impl);
> + if (!impl)
> + return 0;
>
> /*
> * If the device has no .reg_write operation, do not allow
These functions are only called during registration (and don't even
dereference the callback pointers) so adding locking here is a bit
misleading.
Perhaps you can just add another flag in a preparatory patch to stop
accessing the ops directly.
Note that read_only is already set if there is no write callback, so
you'd only need a flag for write_only.
> @@ -460,10 +478,9 @@ static int nvmem_sysfs_setup_compat(struct nvmem_device *nvmem,
> return 0;
> }
>
> -static void nvmem_sysfs_remove_compat(struct nvmem_device *nvmem,
> - const struct nvmem_config *config)
> +static void nvmem_sysfs_remove_compat(struct nvmem_device *nvmem)
> {
> - if (config->compat)
> + if (nvmem->flags & FLAG_COMPAT)
> device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom);
> }
The compat attribute should also be removed at deregistration so this
may not be needed.
> +static void nvmem_release(struct device *dev)
> +{
> + struct nvmem_device *nvmem = to_nvmem_device(dev);
> +
> + gpiod_put(nvmem->wp_gpio);
> + nvmem_sysfs_remove_compat(nvmem);
This one should be moved to nvmem_unregister().
> + nvmem_device_remove_all_cells(nvmem);
> + ida_free(&nvmem_ida, nvmem->id);
> + cleanup_srcu_struct(&nvmem->srcu);
> + kfree(nvmem);
> +}
Johan
prev parent reply other threads:[~2026-03-17 11:31 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-23 10:57 [PATCH v2 0/7] nvmem: survive unbind with active consumers Bartosz Golaszewski
2026-02-23 10:57 ` [PATCH v2 1/7] nvmem: remove unused field from struct nvmem_device Bartosz Golaszewski
2026-03-23 16:00 ` Johan Hovold
2026-02-23 10:57 ` [PATCH v2 2/7] nvmem: return -EOPNOTSUPP to in-kernel users on missing callbacks Bartosz Golaszewski
2026-03-23 16:21 ` Johan Hovold
2026-04-29 15:45 ` Bartosz Golaszewski
2026-02-23 10:57 ` [PATCH v2 3/7] nvmem: check the return value of gpiod_set_value_cansleep() Bartosz Golaszewski
2026-03-23 16:28 ` Johan Hovold
2026-02-23 10:57 ` [PATCH v2 4/7] nvmem: simplify locking with guard() Bartosz Golaszewski
2026-03-23 16:35 ` Johan Hovold
2026-04-29 15:45 ` Bartosz Golaszewski
2026-02-23 10:57 ` [PATCH v2 5/7] nvmem: remove unneeded __nvmem_device_put() Bartosz Golaszewski
2026-03-23 16:44 ` Johan Hovold
2026-04-29 15:45 ` Bartosz Golaszewski
2026-02-23 10:57 ` [PATCH v2 6/7] nvmem: split struct nvmem_device into refcounted and provider-owned data Bartosz Golaszewski
2026-03-17 10:44 ` Johan Hovold
2026-03-17 12:52 ` Bartosz Golaszewski
2026-03-23 16:45 ` Johan Hovold
2026-02-23 10:57 ` [PATCH v2 7/7] nvmem: synchronize nvmem device unregistering with SRCU Bartosz Golaszewski
2026-03-17 11:31 ` Johan Hovold [this message]
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=abk7jM22_8qnmUkZ@hovoldconsulting.com \
--to=johan@kernel.org \
--cc=bartosz.golaszewski@oss.qualcomm.com \
--cc=brgl@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=srini@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.