Received: by 2002:a89:288:0:b0:1f7:eeee:6653 with SMTP id j8csp558041lqh; Tue, 7 May 2024 07:25:29 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCU+a65xod32AwPfnpYhdTXK+TCqXYCJIpRA/3Z/8f8Y4isup2UGUI1+0gImvdhKYpkIQfge0Tj24RnJpVywKrb1r5tJxX+uujbWAe0y/Q== X-Google-Smtp-Source: AGHT+IFFzpuN1ISHZL8bH8BF1ZSLSgn7w9gbG+A4WMQLQqA2Yz5FFd7LTXd3RIxB8K5lTGA/tCdc X-Received: by 2002:a50:930a:0:b0:56e:3f0:a163 with SMTP id m10-20020a50930a000000b0056e03f0a163mr11755166eda.14.1715091928835; Tue, 07 May 2024 07:25:28 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1715091928; cv=pass; d=google.com; s=arc-20160816; b=0i6rr0grQRF7+VV7IUJdihCd4uHDwi7UsvXyoKNtDaRrjAcutlBRuSG+q7IURv8p1F /Bw9bfQhOpy54BZO+10yXYwf9jXr/EQh4ugYANMR9Gn8TlSo+XDouv5NNTqfzhankj33 hWCCrS8wm9y/p/lqVtcIOj+sBrCp9QGSf+AeGXBWk8uIlxwbx8ycCPmmicPqOki91mb+ yVW32ExJKOlB4X4gtGmrH+8NqJoYde2IWTy0DnrBompCv1B9UwJbFqrN2ind/NiqI1JM /n37fAozwSWLVN88k2NN2gmlXIg8nkTQZkHprBkmENYO/zLt7NDebCkibNkahraxTUPZ tCfg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=in-reply-to:content-disposition:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:reply-to:message-id :subject:cc:to:from:date:dkim-signature; bh=ArtQc4WTQcWjbH3BTxJ9rKiK8F6dCtZvyTe9LgYs2TU=; fh=o00fS5S/Am0TyW6Ypo1eda2iER1XBFYx8yYi8PnMwqY=; b=nEZ0tbhcOiY7NpnlHEakMJlkYG5YIQapaJQi2EwBerxjI88Vc4PcX8PONx/4svO3D4 DEYo1STr5dsKhQ66NB9mFRvx+4AXVGvun005rgrsj1YiQyMFf+uRsHDAuYIIvDVJ/JIk z5lc/GH6m/BhyHbKbzzxY9xR3DDu/KLInlsnNzxfoh1xuh5KC4YU1X7a3lHqEIv++hjW g9Jhj8Nm4DqmxPAKW+KsR5qkzAMjJB0rG0w8Cegvq1bgeBrg/JU6xP/lY5lZiuEwkpR+ Mq0i6SfD6TqLPe80HkIPMN2vVdsJl6Yb5NxH17CB9ElzlMkg/nvREp4GAW51G/Jlk6+C Zqqg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=Tj8C9NPF; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-171567-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-171567-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [147.75.80.249]) by mx.google.com with ESMTPS id h15-20020a056402280f00b005729ec3f02esi6067154ede.301.2024.05.07.07.25.28 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 May 2024 07:25:28 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-171567-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) client-ip=147.75.80.249; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=Tj8C9NPF; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-171567-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-171567-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=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 3A2221F22E6E for ; Tue, 7 May 2024 14:25:28 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id C732815FD0E; Tue, 7 May 2024 14:24:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Tj8C9NPF" Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CD15A15F417; Tue, 7 May 2024 14:24:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715091854; cv=none; b=W58cYllsnQEZ5Y/qcqpI2g6a/lybGGUQCNGt7JfItk7W+2KR72RQxd0+Jugs0FsU1bzPWbVLOFHpAiOrT7OCVndEm8eee0VJhKpbil7ZGI1KwVkVv4Hx4W+0xBx2UDwTAeXdcavNmghROAFkNdjPbHITAfb1ryzC5l5wwa/FNfg= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715091854; c=relaxed/simple; bh=Zp41r/yYmWHwZsrp8pLB9sTFQRfp3NwkITAqbXQDiSU=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=cS/VfPyVONB1tRgHOAv6Srp8kaXjU5xFsp/b/6dOeXMhIAFS9nE//ar26W9IX/dhoWXY7plXOvsTHhyYEmBkOeWYHEaZqM8PLRpMS9rD48HhefZSOZmJ0icQ1bwy0dmj6mlz8fDfJ9Dl/H8/Me8DrXmS+Mhf1e0u945Tt7da8MA= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Tj8C9NPF; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 615FBC2BBFC; Tue, 7 May 2024 14:24:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1715091854; bh=Zp41r/yYmWHwZsrp8pLB9sTFQRfp3NwkITAqbXQDiSU=; h=Date:From:To:Cc:Subject:Reply-To:References:In-Reply-To:From; b=Tj8C9NPF1Ns9iCUnWotpt1qn0fdCPefMgCAZ/4hxDQ6Gb/c3+r6bTxekCJe3Rh9x0 PKR3LWbXCksqpwY9bbOObzd26dixMWFjtoNJcWPNaLo3wMCZmP7zmDTkwffRRX8SFt QDBFlMHMNrqtTCI+EOSed54Z5TSFyOBCB3czHtseUzYO8xXtSOGHPSzBQckaJvlxaO sBXCZpPzabwdL+VE9emrPflwh5OmvcLYtwq+YFi0991I3yun6BWA+bRiM3oMmCb481 Gu0fw/njd9xKaG3wbFccid+f3bRstjRu3p0bPVQrqpiAWZKLhoio1sciBZFNKST1LV m38WWOdUnGWfQ== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id 0596ACE12BD; Tue, 7 May 2024 07:24:14 -0700 (PDT) Date: Tue, 7 May 2024 07:24:14 -0700 From: "Paul E. McKenney" To: Bartosz Golaszewski Cc: Kent Gibson , Linus Walleij , linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org, Bartosz Golaszewski , Neil Armstrong Subject: Re: [PATCH] gpiolib: fix the speed of descriptor label setting with SRCU Message-ID: <597f5da2-71be-4144-a570-fdc4f06c4cc6@paulmck-laptop> Reply-To: paulmck@kernel.org References: <20240507121346.16969-1-brgl@bgdev.pl> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20240507121346.16969-1-brgl@bgdev.pl> On Tue, May 07, 2024 at 02:13:46PM +0200, Bartosz Golaszewski wrote: > From: Bartosz Golaszewski > > Commit 1f2bcb8c8ccd ("gpio: protect the descriptor label with SRCU") > caused a massive drop in performance of requesting GPIO lines due to the > call to synchronize_srcu() on each label change. Rework the code to not > wait until all read-only users are done with reading the label but > instead atomically replace the label pointer and schedule its release > after all read-only critical sections are done. > > To that end wrap the descriptor label in a struct that also contains the > rcu_head struct required for deferring tasks using call_srcu() and stop > using kstrdup_const() as we're required to allocate memory anyway. Just > allocate enough for the label string and rcu_head in one go. > > Reported-by: Neil Armstrong > Closes: https://lore.kernel.org/linux-gpio/CAMRc=Mfig2oooDQYTqo23W3PXSdzhVO4p=G4+P8y1ppBOrkrJQ@mail.gmail.com/ > Fixes: 1f2bcb8c8ccd ("gpio: protect the descriptor label with SRCU") > Suggested-by: Paul E. McKenney > Signed-off-by: Bartosz Golaszewski Looks good to me! Acked-by: Paul E. McKenney One semi-related question... Why the per-descriptor srcu_struct? Please see below for more on this question. Thanx, Paul > --- > drivers/gpio/gpiolib.c | 31 ++++++++++++++++++++++++------- > drivers/gpio/gpiolib.h | 7 ++++++- > 2 files changed, 30 insertions(+), 8 deletions(-) > > diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c > index 94903fc1c145..2fa3756c9073 100644 > --- a/drivers/gpio/gpiolib.c > +++ b/drivers/gpio/gpiolib.c > @@ -101,6 +101,7 @@ static bool gpiolib_initialized; > > const char *gpiod_get_label(struct gpio_desc *desc) > { > + struct gpio_desc_label *label; > unsigned long flags; > > flags = READ_ONCE(desc->flags); > @@ -108,23 +109,36 @@ const char *gpiod_get_label(struct gpio_desc *desc) > !test_bit(FLAG_REQUESTED, &flags)) > return "interrupt"; > > - return test_bit(FLAG_REQUESTED, &flags) ? > - srcu_dereference(desc->label, &desc->srcu) : NULL; > + if (!test_bit(FLAG_REQUESTED, &flags)) > + return NULL; > + > + label = srcu_dereference_check(desc->label, &desc->srcu, > + srcu_read_lock_held(&desc->srcu)); > + > + return label->str; > +} > + > +static void desc_free_label(struct rcu_head *rh) > +{ > + kfree(container_of(rh, struct gpio_desc_label, rh)); > } > > static int desc_set_label(struct gpio_desc *desc, const char *label) > { > - const char *new = NULL, *old; > + struct gpio_desc_label *new = NULL, *old; > > if (label) { > - new = kstrdup_const(label, GFP_KERNEL); > + new = kzalloc(struct_size(new, str, strlen(label) + 1), > + GFP_KERNEL); > if (!new) > return -ENOMEM; > + > + strcpy(new->str, label); > } > > old = rcu_replace_pointer(desc->label, new, 1); > - synchronize_srcu(&desc->srcu); > - kfree_const(old); > + if (old) > + call_srcu(&desc->srcu, &old->rh, desc_free_label); > > return 0; > } > @@ -697,8 +711,11 @@ 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++) > + for (i = 0; i < gdev->ngpio; i++) { > + /* Free pending label. */ > + synchronize_srcu(&gdev->descs[i].srcu); > cleanup_srcu_struct(&gdev->descs[i].srcu); > + } If the srcu_struct was shared among all of these, you could just do one synchronize_srcu() and one cleanup_srcu_struct() instead of needing to do one per gdev->desc[] entry. You might be able to go further and have one srcu_struct for all the gpio devices. Or did you guys run tests and find some performance problem with sharing srcu_struct structures? (I wouldn't expect one, but sometimes the hardware has a better imagination than I do.) > ida_free(&gpio_ida, gdev->id); > kfree_const(gdev->label); > diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h > index f67d5991ab1c..69a353c789f0 100644 > --- a/drivers/gpio/gpiolib.h > +++ b/drivers/gpio/gpiolib.h > @@ -137,6 +137,11 @@ int gpiod_set_transitory(struct gpio_desc *desc, bool transitory); > > void gpiod_line_state_notify(struct gpio_desc *desc, unsigned long action); > > +struct gpio_desc_label { > + struct rcu_head rh; > + char str[]; > +}; > + > /** > * struct gpio_desc - Opaque descriptor for a GPIO > * > @@ -177,7 +182,7 @@ struct gpio_desc { > #define FLAG_EVENT_CLOCK_HTE 19 /* GPIO CDEV reports hardware timestamps in events */ > > /* Connection label */ > - const char __rcu *label; > + struct gpio_desc_label __rcu *label; > /* Name of the GPIO */ > const char *name; > #ifdef CONFIG_OF_DYNAMIC > -- > 2.40.1 >