Received: by 2002:a05:7208:20d2:b0:82:bbfa:f723 with SMTP id z18csp57319rbz; Tue, 7 May 2024 10:24:33 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCX3PpggnqncH2q87OBoo0yYdpu7lvO+xYdpOSmZsf7Pzh5uHa2JORzD4VDLFxz9DrHyvaxcQ7LxrUIzVauOH/7kDKFbg85kt6zgx5MkuQ== X-Google-Smtp-Source: AGHT+IHyzWIIzwvRs2xMO4RF+KCBj6rmRlQFk//a/JnakKMxNJnvqZtg+c19LjJyOTPo8bF5s7tZ X-Received: by 2002:a50:9f8d:0:b0:56d:f3f3:f61f with SMTP id 4fb4d7f45d1cf-5731d9a284dmr324359a12.9.1715102673297; Tue, 07 May 2024 10:24:33 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1715102673; cv=pass; d=google.com; s=arc-20160816; b=fq8wXj9Q9KyF/Dfl3bO6KKAerkVRba/cyzmezaBntaBl7qaE7+DHZt4fAiWwBJJ8cs tYOeQZheHWOCpdVw/icc1OxXi37Cdp5UD+2V2gysPPaYTrsdIRKitNRNnqcV/9tpbTrm XO4Bo8PhNbdjw9eO89O8MRv1NutXwiq7qj5d6fbge7FBWXD4xnF/6CGw6XpSbQU2RLiS J+4SYd4X+46aBvD2Y40oTiScnPweOsiezA/v7Z2kQIkWtbw0tehTmjYKAnUYmD8qRAIx cABLxPBkkntKQNT31z3YlQQ/YyQ6Jk0FrCMMo4UBOOZzc8aYdmpG2egq/vbwYFUBNAEv 7vew== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:message-id:date:subject:cc:to :from:dkim-signature; bh=uEDX2iDh+s8adyF9eBgT3DFBAnbU/2Aa5SmRe7h56YI=; fh=vQrYQezAG6C/vqn0gWzA+QSnG7d1IWIM5kYF5hDj3oc=; b=EwoDPm4JNjUbctDFPobE6KuUAQxQkq5cYHnWZMEOOoBc22xg6e63Zv+0hzs7LO+Z4B +eK1lQD659qJS9YdARx4X1cwLZfLYVJCb4X84gALQOtaMuQ54pnH5zGPUnhgGXNzHEDv yjsSZykg5dB18CBQGUrZz2/bIiUZ5nTSCsgd4g0JlQfIE052RqrSYiyhhEnjbqGpWsG1 dZuQ8rNM5u+fMtjDQcmMDvLwjvw1LLlJgczV9IohLl1a3+zpRxnaQhyYSVIIs4jknbnX ebC4wd3dk56UVkxmI3D4pS1CwUjBl6RH5f/atvheFz5W8nllqU2F0me33FbXJNbRGXy7 O2dw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@bgdev-pl.20230601.gappssmtp.com header.s=20230601 header.b=A1pkl5pB; arc=pass (i=1 dkim=pass dkdomain=bgdev-pl.20230601.gappssmtp.com); spf=pass (google.com: domain of linux-kernel+bounces-171911-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-171911-linux.lists.archive=gmail.com@vger.kernel.org" Return-Path: Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id m4-20020a056402050400b00572bc9bcda1si6059953edv.347.2024.05.07.10.24.33 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 May 2024 10:24:33 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-171911-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@bgdev-pl.20230601.gappssmtp.com header.s=20230601 header.b=A1pkl5pB; arc=pass (i=1 dkim=pass dkdomain=bgdev-pl.20230601.gappssmtp.com); spf=pass (google.com: domain of linux-kernel+bounces-171911-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-171911-linux.lists.archive=gmail.com@vger.kernel.org" Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id DFD811F257E7 for ; Tue, 7 May 2024 17:24:32 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id BB4AC16C694; Tue, 7 May 2024 17:24:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bgdev-pl.20230601.gappssmtp.com header.i=@bgdev-pl.20230601.gappssmtp.com header.b="A1pkl5pB" Received: from mail-wr1-f48.google.com (mail-wr1-f48.google.com [209.85.221.48]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 85A1254BDA for ; Tue, 7 May 2024 17:24:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.48 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715102665; cv=none; b=iCCb5sOmTMSQGdUdwzJRzaAUxJCttQp+sJjPasT75/tD594ltCxuc9JNCnSPdJ72sO6WoteII/h73o3LLwxec2cQCdnaHHq4bLRV8ObM8JRIe3HX1qg4+jbMXbqaMZcWoMx3DhT1zq1yahUK9vS0QT6tqvA2VtckYTD8oXzi5eQ= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715102665; c=relaxed/simple; bh=yT2PcacFrSYofWrQQQRGh+R1/Ya5iCToKEc45jTUP4Q=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=Xjb4Q8hAg8TIm6uSb8JgyQ863haRreSIuym77OFrJo4r/1azXtpvdg2/rEAj4PLRydDwYeeEOBXA5lnxMKrHYPILMr18pQuGw53s21Lu9WxX1poAEGdHFuLoeYpRvb+8J9TD6p6sgfFvth7Tad60qX6GYjD9ZYgp0xzRVoAiob8= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=bgdev.pl; spf=none smtp.mailfrom=bgdev.pl; dkim=pass (2048-bit key) header.d=bgdev-pl.20230601.gappssmtp.com header.i=@bgdev-pl.20230601.gappssmtp.com header.b=A1pkl5pB; arc=none smtp.client-ip=209.85.221.48 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=bgdev.pl Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=bgdev.pl Received: by mail-wr1-f48.google.com with SMTP id ffacd0b85a97d-34db9a38755so3176960f8f.1 for ; Tue, 07 May 2024 10:24:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20230601.gappssmtp.com; s=20230601; t=1715102662; x=1715707462; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=uEDX2iDh+s8adyF9eBgT3DFBAnbU/2Aa5SmRe7h56YI=; b=A1pkl5pBMX82SStHjxp4m4RVyqMOLp8GZ57fbmJ3EEX8Jy0fcFzlwet4lQCVkLi1tr tU3vjrDqWu411SYdcPHvmutiEpSOt3fWX8w5oZcHYUwCZH0b1h2oXjkBXyk9dwuhUQdl iW1cewlDB8WAv5YN2GCRuPfS1W0KsXsRJapaHa30vSyjuTu3VUMJXzrY1yPPApRatO6U gzxQQ99SJ2gQ7lUx3vRpq9xxcFYFmrMnLdxEIxkrAEbc8c7deLvqKoeHvwqXocgDuaTs Jpci8ssktR1vHpVH6yxynjjhpDFsFOYEYD0Vlno9caGju3Mtnjyw4KRmlEe4c7aYA/aL NPxA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715102662; x=1715707462; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=uEDX2iDh+s8adyF9eBgT3DFBAnbU/2Aa5SmRe7h56YI=; b=Znj96Psf7dI/IuYwSzWYzn+NmGt8iDWKd/Jv7Lbfr6VC3G2G9Qg5azqovcs7dWZoXl sS/Fz5CL5KzSI/vyQVvPiZv12BTj3c7sKHupjNknQjx7NuhWkZdSpJtLSxG2LO9yin7N cafw8tPEYqBd1yTc7e78qyHcczbIwgVF31Cpn8SmnIL6D03pOfKOw5f6XLEMWsfPSrq9 NdnO7HrXRpzl1lQHnx+n943wEeyVE73HzOxxM2b6keU721pyK1a5rvbxaIs6uLpWghQw iJ53BuG2YV+pAPQSvZGxD16RcvnWZ1dWmORUiYxKlLmRKUGG8gxv0Nm2CY8i8qoKKwVS 0Pzw== X-Forwarded-Encrypted: i=1; AJvYcCUHqPNj1YFvUiA/FjRPa7E/S3bwacQr1J69+HwJYlrjA0PWVK+it/YBICwtQ9NdotE0L8vun0uwDgdt5R0idOcGg5MeT9lr9vJdv04m X-Gm-Message-State: AOJu0YwwLB7qlP44krVjlFsfvkPqPmZq68IRL5boaaC/AI2qJ1KQ+FOC 44agBrf1CRfVZOwxhwjMluv7jrEzmS7RFkc8Ql0+4bCDg0j6l9tCL7dfYD2X8Vs= X-Received: by 2002:adf:e34c:0:b0:34c:def3:2f82 with SMTP id ffacd0b85a97d-34fca241964mr366550f8f.27.1715102661691; Tue, 07 May 2024 10:24:21 -0700 (PDT) Received: from brgl-uxlite.home ([2a01:cb1d:75a:e000:581a:1d:3b79:3b03]) by smtp.gmail.com with ESMTPSA id d18-20020adfef92000000b0034c71090653sm13351376wro.57.2024.05.07.10.24.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 May 2024 10:24:21 -0700 (PDT) From: Bartosz Golaszewski To: Kent Gibson , Linus Walleij Cc: linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org, Bartosz Golaszewski , "Paul E . McKenney" Subject: [PATCH] gpiolib: use a single SRCU struct for all GPIO descriptors Date: Tue, 7 May 2024 19:24:14 +0200 Message-Id: <20240507172414.28513-1-brgl@bgdev.pl> X-Mailer: git-send-email 2.40.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Bartosz Golaszewski We used a per-descriptor SRCU struct in order to not impose a wait with synchronize_srcu() for descriptor X on read-only operations of descriptor Y. Now that we no longer call synchronize_srcu() on descriptor label change but only when releasing descriptor resources, we can use a single SRCU structure for all GPIO descriptors in a given chip. Suggested-by: Paul E. McKenney Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpiolib-cdev.c | 2 +- drivers/gpio/gpiolib.c | 41 +++++++++++++++++-------------------- drivers/gpio/gpiolib.h | 10 ++++----- 3 files changed, 25 insertions(+), 28 deletions(-) diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c index d09c7d728365..fea149ae7774 100644 --- a/drivers/gpio/gpiolib-cdev.c +++ b/drivers/gpio/gpiolib-cdev.c @@ -2351,7 +2351,7 @@ static void gpio_desc_to_lineinfo(struct gpio_desc *desc, dflags = READ_ONCE(desc->flags); - scoped_guard(srcu, &desc->srcu) { + scoped_guard(srcu, &desc->gdev->desc_srcu) { label = gpiod_get_label(desc); if (label && test_bit(FLAG_REQUESTED, &dflags)) strscpy(info->consumer, label, diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 2fa3756c9073..fa50db0c3605 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -112,8 +112,8 @@ const char *gpiod_get_label(struct gpio_desc *desc) if (!test_bit(FLAG_REQUESTED, &flags)) return NULL; - label = srcu_dereference_check(desc->label, &desc->srcu, - srcu_read_lock_held(&desc->srcu)); + label = srcu_dereference_check(desc->label, &desc->gdev->desc_srcu, + srcu_read_lock_held(&desc->gdev->desc_srcu)); return label->str; } @@ -138,7 +138,7 @@ static int desc_set_label(struct gpio_desc *desc, const char *label) old = rcu_replace_pointer(desc->label, new, 1); if (old) - call_srcu(&desc->srcu, &old->rh, desc_free_label); + call_srcu(&desc->gdev->desc_srcu, &old->rh, desc_free_label); return 0; } @@ -709,13 +709,10 @@ EXPORT_SYMBOL_GPL(gpiochip_line_is_valid); static void gpiodev_release(struct device *dev) { struct gpio_device *gdev = to_gpio_device(dev); - unsigned int i; - for (i = 0; i < gdev->ngpio; i++) { - /* Free pending label. */ - synchronize_srcu(&gdev->descs[i].srcu); - cleanup_srcu_struct(&gdev->descs[i].srcu); - } + /* Call pending kfree()s for descriptor labels. */ + synchronize_srcu(&gdev->desc_srcu); + cleanup_srcu_struct(&gdev->desc_srcu); ida_free(&gpio_ida, gdev->id); kfree_const(gdev->label); @@ -992,6 +989,10 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, if (ret) goto err_remove_from_list; + ret = init_srcu_struct(&gdev->desc_srcu); + if (ret) + goto err_cleanup_gdev_srcu; + #ifdef CONFIG_PINCTRL INIT_LIST_HEAD(&gdev->pin_ranges); #endif @@ -999,23 +1000,19 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, if (gc->names) { ret = gpiochip_set_desc_names(gc); if (ret) - goto err_cleanup_gdev_srcu; + goto err_cleanup_desc_srcu; } ret = gpiochip_set_names(gc); if (ret) - goto err_cleanup_gdev_srcu; + goto err_cleanup_desc_srcu; ret = gpiochip_init_valid_mask(gc); if (ret) - goto err_cleanup_gdev_srcu; + goto err_cleanup_desc_srcu; for (desc_index = 0; desc_index < gc->ngpio; desc_index++) { struct gpio_desc *desc = &gdev->descs[desc_index]; - ret = init_srcu_struct(&desc->srcu); - if (ret) - goto err_cleanup_desc_srcu; - if (gc->get_direction && gpiochip_line_is_valid(gc, desc_index)) { assign_bit(FLAG_IS_OUT, &desc->flags, !gc->get_direction(gc, desc_index)); @@ -1027,7 +1024,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, ret = of_gpiochip_add(gc); if (ret) - goto err_cleanup_desc_srcu; + goto err_free_valid_mask; ret = gpiochip_add_pin_ranges(gc); if (ret) @@ -1074,10 +1071,10 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, gpiochip_remove_pin_ranges(gc); err_remove_of_chip: of_gpiochip_remove(gc); -err_cleanup_desc_srcu: - while (desc_index--) - cleanup_srcu_struct(&gdev->descs[desc_index].srcu); +err_free_valid_mask: gpiochip_free_valid_mask(gc); +err_cleanup_desc_srcu: + cleanup_srcu_struct(&gdev->desc_srcu); err_cleanup_gdev_srcu: cleanup_srcu_struct(&gdev->srcu); err_remove_from_list: @@ -2407,7 +2404,7 @@ char *gpiochip_dup_line_label(struct gpio_chip *gc, unsigned int offset) if (!test_bit(FLAG_REQUESTED, &desc->flags)) return NULL; - guard(srcu)(&desc->srcu); + guard(srcu)(&desc->gdev->desc_srcu); label = kstrdup(gpiod_get_label(desc), GFP_KERNEL); if (!label) @@ -4798,7 +4795,7 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_device *gdev) } for_each_gpio_desc(gc, desc) { - guard(srcu)(&desc->srcu); + guard(srcu)(&desc->gdev->desc_srcu); if (test_bit(FLAG_REQUESTED, &desc->flags)) { gpiod_get_direction(desc); is_out = test_bit(FLAG_IS_OUT, &desc->flags); diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h index 69a353c789f0..8e0e211ebf08 100644 --- a/drivers/gpio/gpiolib.h +++ b/drivers/gpio/gpiolib.h @@ -31,6 +31,7 @@ * @chip: pointer to the corresponding gpiochip, holding static * data for this device * @descs: array of ngpio descriptors. + * @desc_srcu: ensures consistent state of GPIO descriptors exposed to users * @ngpio: the number of GPIO lines on this GPIO device, equal to the size * of the @descs array. * @can_sleep: indicate whether the GPIO chip driver's callbacks can sleep @@ -61,6 +62,7 @@ struct gpio_device { struct module *owner; struct gpio_chip __rcu *chip; struct gpio_desc *descs; + struct srcu_struct desc_srcu; int base; u16 ngpio; bool can_sleep; @@ -150,7 +152,6 @@ struct gpio_desc_label { * @label: Name of the consumer * @name: Line name * @hog: Pointer to the device node that hogs this line (if any) - * @srcu: SRCU struct protecting the label pointer. * * These are obtained using gpiod_get() and are preferable to the old * integer-based handles. @@ -188,7 +189,6 @@ struct gpio_desc { #ifdef CONFIG_OF_DYNAMIC struct device_node *hog; #endif - struct srcu_struct srcu; }; #define gpiod_not_found(desc) (IS_ERR(desc) && PTR_ERR(desc) == -ENOENT) @@ -256,7 +256,7 @@ static inline int gpio_chip_hwgpio(const struct gpio_desc *desc) #define gpiod_err(desc, fmt, ...) \ do { \ - scoped_guard(srcu, &desc->srcu) { \ + scoped_guard(srcu, &desc->gdev->desc_srcu) { \ pr_err("gpio-%d (%s): " fmt, desc_to_gpio(desc), \ gpiod_get_label(desc) ? : "?", ##__VA_ARGS__); \ } \ @@ -264,7 +264,7 @@ do { \ #define gpiod_warn(desc, fmt, ...) \ do { \ - scoped_guard(srcu, &desc->srcu) { \ + scoped_guard(srcu, &desc->gdev->desc_srcu) { \ pr_warn("gpio-%d (%s): " fmt, desc_to_gpio(desc), \ gpiod_get_label(desc) ? : "?", ##__VA_ARGS__); \ } \ @@ -272,7 +272,7 @@ do { \ #define gpiod_dbg(desc, fmt, ...) \ do { \ - scoped_guard(srcu, &desc->srcu) { \ + scoped_guard(srcu, &desc->gdev->desc_srcu) { \ pr_debug("gpio-%d (%s): " fmt, desc_to_gpio(desc), \ gpiod_get_label(desc) ? : "?", ##__VA_ARGS__); \ } \ -- 2.40.1