All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/4] gpio: sysfs: change 'value' attribute to prealloc
@ 2017-12-18 10:08 Christophe Leroy
  2017-12-18 10:08 ` [PATCH 2/4] gpio: sysfs: correct error handling on 'value' attribute read Christophe Leroy
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: Christophe Leroy @ 2017-12-18 10:08 UTC (permalink / raw)
  To: Linus Walleij; +Cc: linux-kernel, linux-gpio

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 <christophe.leroy@c-s.fr>
---
 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) \
-- 
2.13.3


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/4] gpio: sysfs: correct error handling on 'value' attribute read.
  2017-12-18 10:08 [PATCH 1/4] gpio: sysfs: change 'value' attribute to prealloc Christophe Leroy
@ 2017-12-18 10:08 ` Christophe Leroy
  2017-12-18 10:08 ` [PATCH 3/4] gpio: sysfs: don't use sprintf() for 'value' attribute Christophe Leroy
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 10+ messages in thread
From: Christophe Leroy @ 2017-12-18 10:08 UTC (permalink / raw)
  To: Linus Walleij; +Cc: linux-kernel, linux-gpio

'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 <christophe.leroy@c-s.fr>
---
 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;
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/4] gpio: sysfs: don't use sprintf() for 'value' attribute
  2017-12-18 10:08 [PATCH 1/4] gpio: sysfs: change 'value' attribute to prealloc Christophe Leroy
  2017-12-18 10:08 ` [PATCH 2/4] gpio: sysfs: correct error handling on 'value' attribute read Christophe Leroy
@ 2017-12-18 10:08 ` Christophe Leroy
  2017-12-20  9:34   ` Linus Walleij
  2017-12-18 10:08 ` [PATCH 4/4] gpio: sysfs: avoid using kstrtol() in 'value' attribute write Christophe Leroy
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: Christophe Leroy @ 2017-12-18 10:08 UTC (permalink / raw)
  To: Linus Walleij; +Cc: linux-kernel, linux-gpio

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 <christophe.leroy@c-s.fr>
---
 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);
 
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 4/4] gpio: sysfs: avoid using kstrtol() in 'value' attribute write
  2017-12-18 10:08 [PATCH 1/4] gpio: sysfs: change 'value' attribute to prealloc Christophe Leroy
  2017-12-18 10:08 ` [PATCH 2/4] gpio: sysfs: correct error handling on 'value' attribute read Christophe Leroy
  2017-12-18 10:08 ` [PATCH 3/4] gpio: sysfs: don't use sprintf() for 'value' attribute Christophe Leroy
@ 2017-12-18 10:08 ` Christophe Leroy
  2017-12-20  9:35   ` Linus Walleij
  2017-12-18 10:18 ` [PATCH 1/4] gpio: sysfs: change 'value' attribute to prealloc Bartosz Golaszewski
  2017-12-20  9:32 ` Linus Walleij
  4 siblings, 1 reply; 10+ messages in thread
From: Christophe Leroy @ 2017-12-18 10:08 UTC (permalink / raw)
  To: Linus Walleij; +Cc: linux-kernel, linux-gpio

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 <christophe.leroy@c-s.fr>
---
 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 <linux/interrupt.h>
 #include <linux/kdev_t.h>
 #include <linux/slab.h>
+#include <linux/ctype.h>
 
 #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;
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/4] gpio: sysfs: change 'value' attribute to prealloc
  2017-12-18 10:08 [PATCH 1/4] gpio: sysfs: change 'value' attribute to prealloc Christophe Leroy
                   ` (2 preceding siblings ...)
  2017-12-18 10:08 ` [PATCH 4/4] gpio: sysfs: avoid using kstrtol() in 'value' attribute write Christophe Leroy
@ 2017-12-18 10:18 ` Bartosz Golaszewski
  2017-12-18 15:07   ` Christophe LEROY
  2017-12-20  9:32 ` Linus Walleij
  4 siblings, 1 reply; 10+ messages in thread
From: Bartosz Golaszewski @ 2017-12-18 10:18 UTC (permalink / raw)
  To: Christophe Leroy; +Cc: Linus Walleij, Linux Kernel Mailing List, linux-gpio

2017-12-18 11:08 GMT+01:00 Christophe Leroy <christophe.leroy@c-s.fr>:
> 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 <christophe.leroy@c-s.fr>
> ---
>  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) \
> --
> 2.13.3
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

I'm not sure we should be fixing performance issues in an interface
that's deprecated anyway...

The character device doesn't deal with strings so it will be much faster anyway.

Best regards,
Bartosz Golaszewski

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/4] gpio: sysfs: change 'value' attribute to prealloc
  2017-12-18 10:18 ` [PATCH 1/4] gpio: sysfs: change 'value' attribute to prealloc Bartosz Golaszewski
@ 2017-12-18 15:07   ` Christophe LEROY
  2017-12-18 17:40     ` Bartosz Golaszewski
  0 siblings, 1 reply; 10+ messages in thread
From: Christophe LEROY @ 2017-12-18 15:07 UTC (permalink / raw)
  To: Bartosz Golaszewski; +Cc: Linus Walleij, Linux Kernel Mailing List, linux-gpio



Le 18/12/2017 à 11:18, Bartosz Golaszewski a écrit :
> 2017-12-18 11:08 GMT+01:00 Christophe Leroy <christophe.leroy@c-s.fr>:
>> 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 <christophe.leroy@c-s.fr>
>> ---
>>   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) \
>> --
>> 2.13.3
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> I'm not sure we should be fixing performance issues in an interface
> that's deprecated anyway...

Many applications use that interface. I agree not to make deep changes 
for performance, but here the few changes are quite tiny, yet for a 
significant improvement, so aren't they worth it anyway ?

Christophe

> 
> The character device doesn't deal with strings so it will be much faster anyway.
> 
> Best regards,
> Bartosz Golaszewski
> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/4] gpio: sysfs: change 'value' attribute to prealloc
  2017-12-18 15:07   ` Christophe LEROY
@ 2017-12-18 17:40     ` Bartosz Golaszewski
  0 siblings, 0 replies; 10+ messages in thread
From: Bartosz Golaszewski @ 2017-12-18 17:40 UTC (permalink / raw)
  To: Christophe LEROY; +Cc: Linus Walleij, Linux Kernel Mailing List, linux-gpio

2017-12-18 16:07 GMT+01:00 Christophe LEROY <christophe.leroy@c-s.fr>:
>
>
> Le 18/12/2017 à 11:18, Bartosz Golaszewski a écrit :
>>
>> 2017-12-18 11:08 GMT+01:00 Christophe Leroy <christophe.leroy@c-s.fr>:
>>>
>>> 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 <christophe.leroy@c-s.fr>
>>> ---
>>>   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) \
>>> --
>>> 2.13.3
>>>
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
>>> the body of a message to majordomo@vger.kernel.org
>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>
>>
>> I'm not sure we should be fixing performance issues in an interface
>> that's deprecated anyway...
>
>
> Many applications use that interface. I agree not to make deep changes for
> performance, but here the few changes are quite tiny, yet for a significant
> improvement, so aren't they worth it anyway ?
>
> Christophe

Well, TBH if anything, I'd prefer to worsen the performance to
actually discourage people from using sysfs for GPIOs. :)

It's not up to me though, so let's wait for Linus' opinion.

Thanks,
Bartosz

>
>
>>
>> The character device doesn't deal with strings so it will be much faster
>> anyway.
>>
>> Best regards,
>> Bartosz Golaszewski
>>
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/4] gpio: sysfs: change 'value' attribute to prealloc
  2017-12-18 10:08 [PATCH 1/4] gpio: sysfs: change 'value' attribute to prealloc Christophe Leroy
                   ` (3 preceding siblings ...)
  2017-12-18 10:18 ` [PATCH 1/4] gpio: sysfs: change 'value' attribute to prealloc Bartosz Golaszewski
@ 2017-12-20  9:32 ` Linus Walleij
  4 siblings, 0 replies; 10+ messages in thread
From: Linus Walleij @ 2017-12-20  9:32 UTC (permalink / raw)
  To: Christophe Leroy; +Cc: linux-kernel, linux-gpio

On Mon, Dec 18, 2017 at 11:08 AM, Christophe Leroy
<christophe.leroy@c-s.fr> wrote:

> 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 <christophe.leroy@c-s.fr>

I applied this because I don't want to waste honest development efforts.

Fixes and improvements I can accept. But not extensions.

But as Bartosz says it would be nice to focus efforts on the non-deprecated
ABI.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 3/4] gpio: sysfs: don't use sprintf() for 'value' attribute
  2017-12-18 10:08 ` [PATCH 3/4] gpio: sysfs: don't use sprintf() for 'value' attribute Christophe Leroy
@ 2017-12-20  9:34   ` Linus Walleij
  0 siblings, 0 replies; 10+ messages in thread
From: Linus Walleij @ 2017-12-20  9:34 UTC (permalink / raw)
  To: Christophe Leroy; +Cc: linux-kernel, linux-gpio

On Mon, Dec 18, 2017 at 11:08 AM, Christophe Leroy
<christophe.leroy@c-s.fr> wrote:

> 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 <christophe.leroy@c-s.fr>

Patch applied.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 4/4] gpio: sysfs: avoid using kstrtol() in 'value' attribute write
  2017-12-18 10:08 ` [PATCH 4/4] gpio: sysfs: avoid using kstrtol() in 'value' attribute write Christophe Leroy
@ 2017-12-20  9:35   ` Linus Walleij
  0 siblings, 0 replies; 10+ messages in thread
From: Linus Walleij @ 2017-12-20  9:35 UTC (permalink / raw)
  To: Christophe Leroy; +Cc: linux-kernel, linux-gpio

On Mon, Dec 18, 2017 at 11:08 AM, Christophe Leroy
<christophe.leroy@c-s.fr> wrote:

> 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 <christophe.leroy@c-s.fr>

Patch applied.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2017-12-20  9:35 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-12-18 10:08 [PATCH 1/4] gpio: sysfs: change 'value' attribute to prealloc Christophe Leroy
2017-12-18 10:08 ` [PATCH 2/4] gpio: sysfs: correct error handling on 'value' attribute read Christophe Leroy
2017-12-18 10:08 ` [PATCH 3/4] gpio: sysfs: don't use sprintf() for 'value' attribute Christophe Leroy
2017-12-20  9:34   ` Linus Walleij
2017-12-18 10:08 ` [PATCH 4/4] gpio: sysfs: avoid using kstrtol() in 'value' attribute write Christophe Leroy
2017-12-20  9:35   ` Linus Walleij
2017-12-18 10:18 ` [PATCH 1/4] gpio: sysfs: change 'value' attribute to prealloc Bartosz Golaszewski
2017-12-18 15:07   ` Christophe LEROY
2017-12-18 17:40     ` Bartosz Golaszewski
2017-12-20  9:32 ` Linus Walleij

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.