From: Bartosz Golaszewski Date: Tue, 6 Jan 2026 09:34:23 +0000 (+0100) Subject: gpio: shared: don't allocate the lookup table until we really need it X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a80208072df8f4ceb53cd905c1f4362f84ce397f;p=thirdparty%2Fkernel%2Flinux.git gpio: shared: don't allocate the lookup table until we really need it We allocate memory for the GPIO lookup table at the top of gpio_shared_add_proxy_lookup() but we don't use it until the very end. Depending on the timing, we may return earlier. Move the allocation towards the end. Fixes: a060b8c511ab ("gpiolib: implement low-level, shared GPIO support") Tested-by: Mark Brown Link: https://lore.kernel.org/r/20260106-gpio-shared-fixes-v2-3-c7091d2f7581@oss.qualcomm.com Signed-off-by: Bartosz Golaszewski --- diff --git a/drivers/gpio/gpiolib-shared.c b/drivers/gpio/gpiolib-shared.c index 4c57b0928760..076d8642675c 100644 --- a/drivers/gpio/gpiolib-shared.c +++ b/drivers/gpio/gpiolib-shared.c @@ -443,14 +443,10 @@ int gpio_shared_add_proxy_lookup(struct device *consumer, const char *con_id, unsigned long lflags) { const char *dev_id = dev_name(consumer); + struct gpiod_lookup_table *lookup; struct gpio_shared_entry *entry; struct gpio_shared_ref *ref; - struct gpiod_lookup_table *lookup __free(kfree) = - kzalloc(struct_size(lookup, table, 2), GFP_KERNEL); - if (!lookup) - return -ENOMEM; - list_for_each_entry(entry, &gpio_shared_list, list) { list_for_each_entry(ref, &entry->refs, list) { guard(mutex)(&ref->lock); @@ -482,6 +478,10 @@ int gpio_shared_add_proxy_lookup(struct device *consumer, const char *con_id, if (!key) return -ENOMEM; + lookup = kzalloc(struct_size(lookup, table, 2), GFP_KERNEL); + if (!lookup) + return -ENOMEM; + pr_debug("Adding machine lookup entry for a shared GPIO for consumer %s, with key '%s' and con_id '%s'\n", dev_id, key, ref->con_id ?: "none"); @@ -489,7 +489,7 @@ int gpio_shared_add_proxy_lookup(struct device *consumer, const char *con_id, lookup->table[0] = GPIO_LOOKUP(no_free_ptr(key), 0, ref->con_id, lflags); - ref->lookup = no_free_ptr(lookup); + ref->lookup = lookup; gpiod_add_lookup_table(ref->lookup); return 0;