mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
To: Linus Walleij <linusw@kernel.org>,
	Bartosz Golaszewski <brgl@kernel.org>,
	Marek Szyprowski <m.szyprowski@samsung.com>
Cc: linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org,
	Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Subject: [PATCH v2 2/3] gpio: shared: fix a race condition
Date: Tue, 06 Jan 2026 10:34:22 +0100	[thread overview]
Message-ID: <20260106-gpio-shared-fixes-v2-2-c7091d2f7581@oss.qualcomm.com> (raw)
In-Reply-To: <20260106-gpio-shared-fixes-v2-0-c7091d2f7581@oss.qualcomm.com>

When matching the reset-gpio reference with the actual firmware node
consuming the GPIO, we also need to lock the structure associated with
the latter as it can change while we're doing it.

Due to triggering lockdep false-positives, we need to use a per-reference
lockdep class but accidentally, this also allows us to remove the
previous lockdep workaround for cleaner code.

Fixes: 49416483a953 ("gpio: shared: allow sharing a reset-gpios pin between reset-gpio and gpiolib")
Reported-by: Marek Szyprowski <m.szyprowski@samsung.com>
Closes: https://lore.kernel.org/all/00107523-7737-4b92-a785-14ce4e93b8cb@samsung.com/
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
---
 drivers/gpio/gpiolib-shared.c | 20 +++++++++-----------
 1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/drivers/gpio/gpiolib-shared.c b/drivers/gpio/gpiolib-shared.c
index a68af06a6cc4e1e33946d7f200cecd4d3dc066af..4c57b0928760c3f9f251ca88cfc54ee5887d50c9 100644
--- a/drivers/gpio/gpiolib-shared.c
+++ b/drivers/gpio/gpiolib-shared.c
@@ -38,6 +38,7 @@ struct gpio_shared_ref {
 	int dev_id;
 	/* Protects the auxiliary device struct and the lookup table. */
 	struct mutex lock;
+	struct lock_class_key lock_key;
 	struct auxiliary_device adev;
 	struct gpiod_lookup_table *lookup;
 };
@@ -99,7 +100,8 @@ static struct gpio_shared_ref *gpio_shared_make_ref(struct fwnode_handle *fwnode
 	ref->flags = flags;
 	ref->con_id = no_free_ptr(con_id_cpy);
 	ref->fwnode = fwnode;
-	mutex_init(&ref->lock);
+	lockdep_register_key(&ref->lock_key);
+	mutex_init_with_key(&ref->lock, &ref->lock_key);
 
 	return no_free_ptr(ref);
 }
@@ -378,6 +380,11 @@ static bool gpio_shared_dev_is_reset_gpio(struct device *consumer,
 	 * arguments match the ones from this consumer's node.
 	 */
 	list_for_each_entry(real_ref, &entry->refs, list) {
+		if (real_ref == ref)
+			continue;
+
+		guard(mutex)(&real_ref->lock);
+
 		if (!real_ref->fwnode)
 			continue;
 
@@ -568,15 +575,6 @@ void gpio_device_teardown_shared(struct gpio_device *gdev)
 		if (!device_match_fwnode(&gdev->dev, entry->fwnode))
 			continue;
 
-		/*
-		 * For some reason if we call synchronize_srcu() in GPIO core,
-		 * descent here and take this mutex and then recursively call
-		 * synchronize_srcu() again from gpiochip_remove() (which is
-		 * totally fine) called after gpio_shared_remove_adev(),
-		 * lockdep prints a false positive deadlock splat. Disable
-		 * lockdep here.
-		 */
-		lockdep_off();
 		list_for_each_entry(ref, &entry->refs, list) {
 			guard(mutex)(&ref->lock);
 
@@ -589,7 +587,6 @@ void gpio_device_teardown_shared(struct gpio_device *gdev)
 
 			gpio_shared_remove_adev(&ref->adev);
 		}
-		lockdep_on();
 	}
 }
 
@@ -685,6 +682,7 @@ static void gpio_shared_drop_ref(struct gpio_shared_ref *ref)
 {
 	list_del(&ref->list);
 	mutex_destroy(&ref->lock);
+	lockdep_unregister_key(&ref->lock_key);
 	kfree(ref->con_id);
 	ida_free(&gpio_shared_ida, ref->dev_id);
 	fwnode_handle_put(ref->fwnode);

-- 
2.47.3


  parent reply	other threads:[~2026-01-06  9:34 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-01-06  9:34 [PATCH v2 0/3] gpio: shared: another set of small fixes Bartosz Golaszewski
2026-01-06  9:34 ` [PATCH v2 1/3] gpio: shared: assign the correct firmware node for reset-gpio use-case Bartosz Golaszewski
2026-01-06  9:34 ` Bartosz Golaszewski [this message]
2026-01-06  9:34 ` [PATCH v2 3/3] gpio: shared: don't allocate the lookup table until we really need it Bartosz Golaszewski
2026-01-06 13:22 ` [PATCH v2 0/3] gpio: shared: another set of small fixes Mark Brown
2026-01-07  8:31 ` Bartosz Golaszewski
2026-01-08 12:13 ` Cosmin Tanislav
2026-01-08 12:18   ` Bartosz Golaszewski
2026-01-08 13:47     ` Cosmin Tanislav
2026-01-08 12:22   ` Marek Szyprowski

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=20260106-gpio-shared-fixes-v2-2-c7091d2f7581@oss.qualcomm.com \
    --to=bartosz.golaszewski@oss.qualcomm.com \
    --cc=brgl@kernel.org \
    --cc=linusw@kernel.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=m.szyprowski@samsung.com \
    /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®