From patchwork Mon Dec 18 10:08:29 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christophe Leroy X-Patchwork-Id: 849957 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3z0cDy2qqGz9s84 for ; Mon, 18 Dec 2017 21:08:34 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757733AbdLRKIc (ORCPT ); Mon, 18 Dec 2017 05:08:32 -0500 Received: from pegase1.c-s.fr ([93.17.236.30]:60974 "EHLO pegase1.c-s.fr" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757648AbdLRKIb (ORCPT ); Mon, 18 Dec 2017 05:08:31 -0500 Received: from localhost (mailhub1-int [192.168.12.234]) by localhost (Postfix) with ESMTP id 3z0cDm0CB5z9ttFs; Mon, 18 Dec 2017 11:08:24 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at c-s.fr Received: from pegase1.c-s.fr ([192.168.12.234]) by localhost (pegase1.c-s.fr [192.168.12.234]) (amavisd-new, port 10024) with ESMTP id sT0PEvDBn3Xi; Mon, 18 Dec 2017 11:08:23 +0100 (CET) Received: from messagerie.si.c-s.fr (messagerie.si.c-s.fr [192.168.25.192]) by pegase1.c-s.fr (Postfix) with ESMTP id 3z0cDl6rTVz9ttBr; Mon, 18 Dec 2017 11:08:23 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 9ECBA8B864; Mon, 18 Dec 2017 11:08:29 +0100 (CET) X-Virus-Scanned: amavisd-new at c-s.fr Received: from messagerie.si.c-s.fr ([127.0.0.1]) by localhost (messagerie.si.c-s.fr [127.0.0.1]) (amavisd-new, port 10023) with ESMTP id mctnYnAgnrD4; Mon, 18 Dec 2017 11:08:29 +0100 (CET) Received: from PO15451.localdomain (po15451.idsi0.si.c-s.fr [172.25.231.40]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 6E7238B80F; Mon, 18 Dec 2017 11:08:29 +0100 (CET) Received: by localhost.localdomain (Postfix, from userid 0) id 323E26CBD3; Mon, 18 Dec 2017 11:08:29 +0100 (CET) Message-Id: <84f3fa77ff5a0b7ac73709de8bdcd93a2cf95271.1513591276.git.christophe.leroy@c-s.fr> From: Christophe Leroy Subject: [PATCH 1/4] gpio: sysfs: change 'value' attribute to prealloc To: Linus Walleij Cc: linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org Date: Mon, 18 Dec 2017 11:08:29 +0100 (CET) Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org The GPIO 'value' attribute is time critical. A small bench with 'perf record' on the app below shows that 80% of the time spent in sysfs_kf_seq_show() is spent in memset() for zeroising the buffer. |--67.48%--sysfs_kf_seq_show | | | |--54.40%--memset | | | |--11.49%--dev_attr_show | | | | | |--10.06%--value_show | | | | | | | |--4.75%--sprintf | | | | | This patch changes the attribute type to prealloc, eliminating the need to zeroise the buffer at each read. 'perf record' gives the following result. |--42.41%--sysfs_kf_read | | | |--39.73%--dev_attr_show | | | | | |--38.23%--value_show | | | | | | | |--29.22%--sprintf | | | | | Test done with the following small app: int main(int argc, char **argv) { int fd = open(argv[1], O_RDONLY); for (;;) { int buf[512]; read(fd, buf, 512); lseek(fd, 0, SEEK_SET); } exit(0); } Signed-off-by: Christophe Leroy --- drivers/gpio/gpiolib-sysfs.c | 2 +- include/linux/device.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c index 3f454eaf2101..7a3f4271393b 100644 --- a/drivers/gpio/gpiolib-sysfs.c +++ b/drivers/gpio/gpiolib-sysfs.c @@ -138,7 +138,7 @@ static ssize_t value_store(struct device *dev, return status; } -static DEVICE_ATTR_RW(value); +static DEVICE_ATTR_PREALLOC(value, S_IWUSR | S_IRUGO, value_show, value_store); static irqreturn_t gpio_sysfs_irq(int irq, void *priv) { diff --git a/include/linux/device.h b/include/linux/device.h index 9d32000725da..46ac622e5c6f 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -575,6 +575,9 @@ ssize_t device_store_bool(struct device *dev, struct device_attribute *attr, #define DEVICE_ATTR(_name, _mode, _show, _store) \ struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store) +#define DEVICE_ATTR_PREALLOC(_name, _mode, _show, _store) \ + struct device_attribute dev_attr_##_name = \ + __ATTR_PREALLOC(_name, _mode, _show, _store) #define DEVICE_ATTR_RW(_name) \ struct device_attribute dev_attr_##_name = __ATTR_RW(_name) #define DEVICE_ATTR_RO(_name) \ From patchwork Mon Dec 18 10:08:31 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christophe Leroy X-Patchwork-Id: 849962 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3z0cFx5xWZz9sR8 for ; Mon, 18 Dec 2017 21:09:25 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758103AbdLRKJK (ORCPT ); Mon, 18 Dec 2017 05:09:10 -0500 Received: from pegase1.c-s.fr ([93.17.236.30]:5737 "EHLO pegase1.c-s.fr" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757677AbdLRKId (ORCPT ); Mon, 18 Dec 2017 05:08:33 -0500 Received: from localhost (mailhub1-int [192.168.12.234]) by localhost (Postfix) with ESMTP id 3z0cDn5qrsz9ttfn; Mon, 18 Dec 2017 11:08:25 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at c-s.fr Received: from pegase1.c-s.fr ([192.168.12.234]) by localhost (pegase1.c-s.fr [192.168.12.234]) (amavisd-new, port 10024) with ESMTP id yFlsVGF1gEj9; Mon, 18 Dec 2017 11:08:25 +0100 (CET) Received: from messagerie.si.c-s.fr (messagerie.si.c-s.fr [192.168.25.192]) by pegase1.c-s.fr (Postfix) with ESMTP id 3z0cDn5CKZz9ttBr; Mon, 18 Dec 2017 11:08:25 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 62C8D8B857; Mon, 18 Dec 2017 11:08:31 +0100 (CET) X-Virus-Scanned: amavisd-new at c-s.fr Received: from messagerie.si.c-s.fr ([127.0.0.1]) by localhost (messagerie.si.c-s.fr [127.0.0.1]) (amavisd-new, port 10023) with ESMTP id xm6BBgc2fJCr; Mon, 18 Dec 2017 11:08:31 +0100 (CET) Received: from PO15451.localdomain (po15451.idsi0.si.c-s.fr [172.25.231.40]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 347018B80F; Mon, 18 Dec 2017 11:08:31 +0100 (CET) Received: by localhost.localdomain (Postfix, from userid 0) id 2C3556CBD3; Mon, 18 Dec 2017 11:08:31 +0100 (CET) Message-Id: In-Reply-To: <84f3fa77ff5a0b7ac73709de8bdcd93a2cf95271.1513591276.git.christophe.leroy@c-s.fr> References: <84f3fa77ff5a0b7ac73709de8bdcd93a2cf95271.1513591276.git.christophe.leroy@c-s.fr> From: Christophe Leroy Subject: [PATCH 2/4] gpio: sysfs: correct error handling on 'value' attribute read. To: Linus Walleij Cc: linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org Date: Mon, 18 Dec 2017 11:08:31 +0100 (CET) Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org 'value' attribute is supposed to only return 0 or 1 according to the documentation. With today's implementation, if gpiod_get_value_cansleep() fails the printed 'value' is a negative value. This patch ensures that an error is returned on read instead. Signed-off-by: Christophe Leroy --- drivers/gpio/gpiolib-sysfs.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c index 7a3f4271393b..1b0f415df03b 100644 --- a/drivers/gpio/gpiolib-sysfs.c +++ b/drivers/gpio/gpiolib-sysfs.c @@ -106,8 +106,12 @@ static ssize_t value_show(struct device *dev, mutex_lock(&data->mutex); - status = sprintf(buf, "%d\n", gpiod_get_value_cansleep(desc)); + status = gpiod_get_value_cansleep(desc); + if (status < 0) + goto err; + status = sprintf(buf, "%d\n", status); +err: mutex_unlock(&data->mutex); return status; From patchwork Mon Dec 18 10:08:33 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christophe Leroy X-Patchwork-Id: 849961 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3z0cFc0HGJz9sDB for ; Mon, 18 Dec 2017 21:09:08 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757869AbdLRKIh (ORCPT ); Mon, 18 Dec 2017 05:08:37 -0500 Received: from pegase1.c-s.fr ([93.17.236.30]:38521 "EHLO pegase1.c-s.fr" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757648AbdLRKIf (ORCPT ); Mon, 18 Dec 2017 05:08:35 -0500 Received: from localhost (mailhub1-int [192.168.12.234]) by localhost (Postfix) with ESMTP id 3z0cDr0lC7z9ttFs; Mon, 18 Dec 2017 11:08:28 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at c-s.fr Received: from pegase1.c-s.fr ([192.168.12.234]) by localhost (pegase1.c-s.fr [192.168.12.234]) (amavisd-new, port 10024) with ESMTP id xtavmbG-2qm1; Mon, 18 Dec 2017 11:08:28 +0100 (CET) Received: from messagerie.si.c-s.fr (messagerie.si.c-s.fr [192.168.25.192]) by pegase1.c-s.fr (Postfix) with ESMTP id 3z0cDq6ywZz9ttBr; Mon, 18 Dec 2017 11:08:27 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 8030B8B875; Mon, 18 Dec 2017 11:08:33 +0100 (CET) X-Virus-Scanned: amavisd-new at c-s.fr Received: from messagerie.si.c-s.fr ([127.0.0.1]) by localhost (messagerie.si.c-s.fr [127.0.0.1]) (amavisd-new, port 10023) with ESMTP id A1ZYkPujmwqR; Mon, 18 Dec 2017 11:08:33 +0100 (CET) Received: from PO15451.localdomain (po15451.idsi0.si.c-s.fr [172.25.231.40]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 43FEE8B80F; Mon, 18 Dec 2017 11:08:33 +0100 (CET) Received: by localhost.localdomain (Postfix, from userid 0) id 376E36CBD3; Mon, 18 Dec 2017 11:08:33 +0100 (CET) Message-Id: <1fbada4f02475f69abbccd105c92dc3512dd6ab0.1513591276.git.christophe.leroy@c-s.fr> In-Reply-To: <84f3fa77ff5a0b7ac73709de8bdcd93a2cf95271.1513591276.git.christophe.leroy@c-s.fr> References: <84f3fa77ff5a0b7ac73709de8bdcd93a2cf95271.1513591276.git.christophe.leroy@c-s.fr> From: Christophe Leroy Subject: [PATCH 3/4] gpio: sysfs: don't use sprintf() for 'value' attribute To: Linus Walleij Cc: linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org Date: Mon, 18 Dec 2017 11:08:33 +0100 (CET) Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org A bench with 'perf record' shows that most of time spent in value_show() is spent in sprintf() --42.41%--sysfs_kf_read | |--39.73%--dev_attr_show | | | |--38.23%--value_show | | | | | |--29.22%--sprintf | | | | | |--2.94%--gpiod_get_value_cansleep | | | value_show() only returns "0\n" or "1\n", therefore the use of sprintf() can be avoided With this patch we get the following result with 'perf record' --13.89%--sysfs_kf_read | |--10.72%--dev_attr_show | | | |--9.44%--value_show | | | | | |--4.61%--gpiod_get_value_cansleep Signed-off-by: Christophe Leroy --- drivers/gpio/gpiolib-sysfs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c index 1b0f415df03b..bb10e8ed456e 100644 --- a/drivers/gpio/gpiolib-sysfs.c +++ b/drivers/gpio/gpiolib-sysfs.c @@ -110,7 +110,9 @@ static ssize_t value_show(struct device *dev, if (status < 0) goto err; - status = sprintf(buf, "%d\n", status); + buf[0] = '0' + status; + buf[1] = '\n'; + status = 2; err: mutex_unlock(&data->mutex); From patchwork Mon Dec 18 10:08:35 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christophe Leroy X-Patchwork-Id: 849960 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3z0cFS1kZLz9sDB for ; Mon, 18 Dec 2017 21:09:00 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758034AbdLRKIq (ORCPT ); Mon, 18 Dec 2017 05:08:46 -0500 Received: from pegase1.c-s.fr ([93.17.236.30]:7209 "EHLO pegase1.c-s.fr" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757861AbdLRKIh (ORCPT ); Mon, 18 Dec 2017 05:08:37 -0500 Received: from localhost (mailhub1-int [192.168.12.234]) by localhost (Postfix) with ESMTP id 3z0cDs6Jz8z9ttC1; Mon, 18 Dec 2017 11:08:29 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at c-s.fr Received: from pegase1.c-s.fr ([192.168.12.234]) by localhost (pegase1.c-s.fr [192.168.12.234]) (amavisd-new, port 10024) with ESMTP id ErBws2vr6NzN; Mon, 18 Dec 2017 11:08:29 +0100 (CET) Received: from messagerie.si.c-s.fr (messagerie.si.c-s.fr [192.168.25.192]) by pegase1.c-s.fr (Postfix) with ESMTP id 3z0cDs5gtNz9ttBr; Mon, 18 Dec 2017 11:08:29 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 7877A8B80F; Mon, 18 Dec 2017 11:08:35 +0100 (CET) X-Virus-Scanned: amavisd-new at c-s.fr Received: from messagerie.si.c-s.fr ([127.0.0.1]) by localhost (messagerie.si.c-s.fr [127.0.0.1]) (amavisd-new, port 10023) with ESMTP id aKcyn5wsh1qZ; Mon, 18 Dec 2017 11:08:35 +0100 (CET) Received: from PO15451.localdomain (po15451.idsi0.si.c-s.fr [172.25.231.40]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 45E2A8B875; Mon, 18 Dec 2017 11:08:35 +0100 (CET) Received: by localhost.localdomain (Postfix, from userid 0) id 3E1736CBD3; Mon, 18 Dec 2017 11:08:35 +0100 (CET) Message-Id: In-Reply-To: <84f3fa77ff5a0b7ac73709de8bdcd93a2cf95271.1513591276.git.christophe.leroy@c-s.fr> References: <84f3fa77ff5a0b7ac73709de8bdcd93a2cf95271.1513591276.git.christophe.leroy@c-s.fr> From: Christophe Leroy Subject: [PATCH 4/4] gpio: sysfs: avoid using kstrtol() in 'value' attribute write To: Linus Walleij Cc: linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org Date: Mon, 18 Dec 2017 11:08:35 +0100 (CET) Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org A 'perf record' on an app continuously writing in the 'value' attribute show that most of the time is spent in kstrtol() --17.99%--value_store | |--10.17%--kstrtoint | | | |--8.82%--kstrtoll | |--2.50%--gpiod_set_value_cansleep | |--1.82%--u16_gpio_set | |--1.46%--value_store The normal case is to write 0 or 1 in the attribute, therefore this patch avoids the call to kstrtol() in the most common cases Then 'perf record' shows --7.21%--value_store | |--2.69%--u16_gpio_set | |--1.47%--value_store | |--1.08%--gpiod_set_value_cansleep | |--0.60%--mutex_lock | --0.58%--mutex_unlock Signed-off-by: Christophe Leroy --- drivers/gpio/gpiolib-sysfs.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c index bb10e8ed456e..31e2352632a2 100644 --- a/drivers/gpio/gpiolib-sysfs.c +++ b/drivers/gpio/gpiolib-sysfs.c @@ -8,6 +8,7 @@ #include #include #include +#include #include "gpiolib.h" @@ -124,7 +125,7 @@ static ssize_t value_store(struct device *dev, { struct gpiod_data *data = dev_get_drvdata(dev); struct gpio_desc *desc = data->desc; - ssize_t status; + ssize_t status = 0; mutex_lock(&data->mutex); @@ -133,7 +134,11 @@ static ssize_t value_store(struct device *dev, } else { long value; - status = kstrtol(buf, 0, &value); + if (size <= 2 && isdigit(buf[0]) && + (size == 1 || buf[1] == '\n')) + value = buf[0] - '0'; + else + status = kstrtol(buf, 0, &value); if (status == 0) { gpiod_set_value_cansleep(desc, value); status = size;