From patchwork Fri Dec 15 02:38:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kent Gibson X-Patchwork-Id: 179011 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:3b04:b0:fb:cd0c:d3e with SMTP id c4csp8999457dys; Thu, 14 Dec 2023 18:43:46 -0800 (PST) X-Google-Smtp-Source: AGHT+IHJn9/5/j3dLo4DOpZmOwJMG1OLYOJBnO9VaFnA+LQXqKF7RzdYY46NeCPy6JV8bvE2Qc/M X-Received: by 2002:a05:6359:4123:b0:170:c1a7:254 with SMTP id kh35-20020a056359412300b00170c1a70254mr10182264rwc.2.1702608226207; Thu, 14 Dec 2023 18:43:46 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1702608226; cv=none; d=google.com; s=arc-20160816; b=n3t8ICtIiz7PcFKh7sGzHku3QPFIysXzOZK4hniU0aYovgtAMqxAvxkw6QSpunIYUI NKomw7Gr5SKZNElOwLsutE6OFef++oldCmVxfNTb7WuirNt/lFV1FB9mEwvu+/BoxOvK qrH0G8U8U3EdOMqDtqrWzM+/om3Js1amWhrMKd3nNhzYxcYHsuDQTk59vmoyYgZ7CWWx It1guQM3sdgo13mhG/l7qe4HeaD86qHUkS1zxsEGXLcFa8o4n2wvQ3SAQ5GFk97Sc8jE RYaoDqBSUWV7+36+RKTFnDVXTUmShr5L3LzBQfOC06AoCjFawAeATAi1wv+aIloo7YVW np/w== ARC-Message-Signature: i=1; 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:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=CtO2jY+EJP8Yvc8VKZdfYbcqASBoJOxP1iWf7Ww080E=; fh=GNOA1jdeAuH+tfAEzFx15vIukVGFZnqrW9xHApUHjl0=; b=iefOKsNKckTMzen1eQ5SMHnK4GSQwM4a5c11hwABnrtrchZYiTF0y9B5Wi0zPF4zak 8UdNZVXlzNfThMLt5MzD4xARzN72fozoikX+d6ypIok2LjPK/CEF8fm+wnKr6m7oLSzB WTNBLzU0sqzeyjdctiF1fd7RFJK9FpY0OUaPXnwOZNDcHCxqgjuLljwGtSduEa5jywSG TNiMuDOQJrM6YX8Uy46VTYXd0sXe/vXtVXc1ecixsUcrbq3I6OVeG/u+aSbrLYjAJCl4 caHbEoTf+7PQ+mKh3pjVoseqIvhIs0lRuYKqKQWlSAZHUoz4TUPdqSPbEZwGa9kizInv m1Ww== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20230601 header.b=ieCk6gG9; spf=pass (google.com: domain of linux-kernel+bounces-367-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-367-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [2604:1380:40f1:3f00::1]) by mx.google.com with ESMTPS id pg3-20020a17090b1e0300b0028ac5d6a4e4si5263498pjb.120.2023.12.14.18.43.45 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Dec 2023 18:43:46 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-367-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) client-ip=2604:1380:40f1:3f00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20230601 header.b=ieCk6gG9; spf=pass (google.com: domain of linux-kernel+bounces-367-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-367-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com 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 sy.mirrors.kernel.org (Postfix) with ESMTPS id 6E8D3B20A39 for ; Fri, 15 Dec 2023 02:43:43 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 44D8ED291; Fri, 15 Dec 2023 02:39:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="ieCk6gG9" X-Original-To: linux-kernel@vger.kernel.org Received: from mail-oi1-f174.google.com (mail-oi1-f174.google.com [209.85.167.174]) (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 4CBC7D271; Fri, 15 Dec 2023 02:39:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-oi1-f174.google.com with SMTP id 5614622812f47-3b9ef61b6b8so194947b6e.3; Thu, 14 Dec 2023 18:39:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702607964; x=1703212764; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=CtO2jY+EJP8Yvc8VKZdfYbcqASBoJOxP1iWf7Ww080E=; b=ieCk6gG9OZ3zhBPcrphnGM4Zy31QEtol5Znhd8nXoBvILsf7aenHXe2gmoJX8B52Ha mlU9bLeeU499mQbATPYQtHDbtX0uyizU5J67KwAvOgOmSIQ4D8JeQLPxgiyDcgNKYHTn ichXppg1/BCx7dKJNrLTCsJK1YpEB9k4l3BDQnovo9OCKwlvBQuYeSmLKpLEBzSTNhQb y2ZKDbztadPCHk9W+bw5Dd5ivz3+OvfvMkhhOH4Qv8IaX1rhFYWMiqBi1D6JtJdI+58i Y/ijsgfqwByBRSBFmXfu8y+4dMqLLAN1SnG1cOf0RWE/NnZtOaA7XmPlu0kRBT8gSaai +GfQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702607964; x=1703212764; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=CtO2jY+EJP8Yvc8VKZdfYbcqASBoJOxP1iWf7Ww080E=; b=UuEnNACyOSfVsBN/oBcFiLz1FXOeZ/MM0J0v0/wIV4o3nqEbGd91ts0UDUF9DCXACa C5j/w+TA0oE3RNgPa+HJ1s2qCoJQvXXFPYflOMxrz1tZlmVl3v+Q19THtifap5oLsT5/ 7ETw0+obwpMnFVNNlgNbv/4NUoE+GKFNI4z76GP9f7HBKopwdv62haD8dM2xPdApckiv Wm3VgZH7MJOOAM5Bq3FaEO0fCcEXISJ+7yJNX4gzIu64tcwLju4en4oNDxnjajbDa8Hb UskjtRVrGMy8V8oPtbdr1dDA3PJGeQ46TV6IZ2MqJUG6HXTUNfwBXeBv2blamMGbCzQx 4FKA== X-Gm-Message-State: AOJu0YzndLHzrsSrj1Ew0Okia/OFACXTB8GXV7G4ab1qScDQxtO+M2rr O6DBRTst9z5iXMmQ/YjnohfhZq6lf3o= X-Received: by 2002:a05:6808:ecb:b0:3b9:d903:9fa9 with SMTP id q11-20020a0568080ecb00b003b9d9039fa9mr13502871oiv.105.1702607964084; Thu, 14 Dec 2023 18:39:24 -0800 (PST) Received: from rigel.home.arpa (60-241-235-125.tpgi.com.au. [60.241.235.125]) by smtp.gmail.com with ESMTPSA id fk16-20020a056a003a9000b006d26920a11dsm1437987pfb.0.2023.12.14.18.39.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Dec 2023 18:39:23 -0800 (PST) From: Kent Gibson To: linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org, brgl@bgdev.pl, linus.walleij@linaro.org, andy@kernel.org Cc: Kent Gibson Subject: [PATCH v3 3/5] gpiolib: cdev: reduce locking in gpio_desc_to_lineinfo() Date: Fri, 15 Dec 2023 10:38:03 +0800 Message-Id: <20231215023805.63289-4-warthog618@gmail.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231215023805.63289-1-warthog618@gmail.com> References: <20231215023805.63289-1-warthog618@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1785314123227676482 X-GMAIL-MSGID: 1785314123227676482 Reduce the time holding the gpio_lock by snapshotting the desc flags, rather than testing them individually while holding the lock. Accept that the calculation of the used field is inherently racy, and only check the availability of the line from pinctrl if other checks pass, so avoiding the check for lines that are otherwise in use. Signed-off-by: Kent Gibson --- drivers/gpio/gpiolib-cdev.c | 74 ++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 38 deletions(-) diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c index 5ba900e5461a..c140bcd63361 100644 --- a/drivers/gpio/gpiolib-cdev.c +++ b/drivers/gpio/gpiolib-cdev.c @@ -2388,74 +2388,72 @@ static void gpio_desc_to_lineinfo(struct gpio_desc *desc, struct gpio_v2_line_info *info) { struct gpio_chip *gc = desc->gdev->chip; - bool ok_for_pinctrl; - unsigned long flags; + unsigned long dflags; memset(info, 0, sizeof(*info)); info->offset = gpio_chip_hwgpio(desc); - /* - * This function takes a mutex so we must check this before taking - * the spinlock. - * - * FIXME: find a non-racy way to retrieve this information. Maybe a - * lock common to both frameworks? - */ - ok_for_pinctrl = pinctrl_gpio_can_use_line(gc, info->offset); + scoped_guard(spinlock_irqsave, &gpio_lock) { + if (desc->name) + strscpy(info->name, desc->name, sizeof(info->name)); - spin_lock_irqsave(&gpio_lock, flags); + if (desc->label) + strscpy(info->consumer, desc->label, + sizeof(info->consumer)); - if (desc->name) - strscpy(info->name, desc->name, sizeof(info->name)); - - if (desc->label) - strscpy(info->consumer, desc->label, sizeof(info->consumer)); + dflags = READ_ONCE(desc->flags); + } /* - * Userspace only need to know that the kernel is using this GPIO so - * it can't use it. + * Userspace only need know that the kernel is using this GPIO so it + * can't use it. + * The calculation of the used flag is slightly racy, as it may read + * desc, gc and pinctrl state without a lock covering all three at + * once. Worst case if the line is in transition and the calculation + * is inconsistent then it looks to the user like they performed the + * read on the other side of the transition - but that can always + * happen. + * The definitive test that a line is available to userspace is to + * request it. */ - info->flags = 0; - if (test_bit(FLAG_REQUESTED, &desc->flags) || - test_bit(FLAG_IS_HOGGED, &desc->flags) || - test_bit(FLAG_USED_AS_IRQ, &desc->flags) || - test_bit(FLAG_EXPORT, &desc->flags) || - test_bit(FLAG_SYSFS, &desc->flags) || + if (test_bit(FLAG_REQUESTED, &dflags) || + test_bit(FLAG_IS_HOGGED, &dflags) || + test_bit(FLAG_USED_AS_IRQ, &dflags) || + test_bit(FLAG_EXPORT, &dflags) || + test_bit(FLAG_SYSFS, &dflags) || !gpiochip_line_is_valid(gc, info->offset) || - !ok_for_pinctrl) + !pinctrl_gpio_can_use_line(gc, info->offset)) info->flags |= GPIO_V2_LINE_FLAG_USED; - if (test_bit(FLAG_IS_OUT, &desc->flags)) + if (test_bit(FLAG_IS_OUT, &dflags)) info->flags |= GPIO_V2_LINE_FLAG_OUTPUT; else info->flags |= GPIO_V2_LINE_FLAG_INPUT; - if (test_bit(FLAG_ACTIVE_LOW, &desc->flags)) + if (test_bit(FLAG_ACTIVE_LOW, &dflags)) info->flags |= GPIO_V2_LINE_FLAG_ACTIVE_LOW; - if (test_bit(FLAG_OPEN_DRAIN, &desc->flags)) + if (test_bit(FLAG_OPEN_DRAIN, &dflags)) info->flags |= GPIO_V2_LINE_FLAG_OPEN_DRAIN; - if (test_bit(FLAG_OPEN_SOURCE, &desc->flags)) + if (test_bit(FLAG_OPEN_SOURCE, &dflags)) info->flags |= GPIO_V2_LINE_FLAG_OPEN_SOURCE; - if (test_bit(FLAG_BIAS_DISABLE, &desc->flags)) + if (test_bit(FLAG_BIAS_DISABLE, &dflags)) info->flags |= GPIO_V2_LINE_FLAG_BIAS_DISABLED; - if (test_bit(FLAG_PULL_DOWN, &desc->flags)) + if (test_bit(FLAG_PULL_DOWN, &dflags)) info->flags |= GPIO_V2_LINE_FLAG_BIAS_PULL_DOWN; - if (test_bit(FLAG_PULL_UP, &desc->flags)) + if (test_bit(FLAG_PULL_UP, &dflags)) info->flags |= GPIO_V2_LINE_FLAG_BIAS_PULL_UP; - if (test_bit(FLAG_EDGE_RISING, &desc->flags)) + if (test_bit(FLAG_EDGE_RISING, &dflags)) info->flags |= GPIO_V2_LINE_FLAG_EDGE_RISING; - if (test_bit(FLAG_EDGE_FALLING, &desc->flags)) + if (test_bit(FLAG_EDGE_FALLING, &dflags)) info->flags |= GPIO_V2_LINE_FLAG_EDGE_FALLING; - if (test_bit(FLAG_EVENT_CLOCK_REALTIME, &desc->flags)) + if (test_bit(FLAG_EVENT_CLOCK_REALTIME, &dflags)) info->flags |= GPIO_V2_LINE_FLAG_EVENT_CLOCK_REALTIME; - else if (test_bit(FLAG_EVENT_CLOCK_HTE, &desc->flags)) + else if (test_bit(FLAG_EVENT_CLOCK_HTE, &dflags)) info->flags |= GPIO_V2_LINE_FLAG_EVENT_CLOCK_HTE; - - spin_unlock_irqrestore(&gpio_lock, flags); } struct gpio_chardev_data {