gpio: sysfs: backports of memleak fixes to 3.12
Subsystems (2)
cover gpio: sysfs: backports of memleak fixes to 3.12
Hi Greg,
Here are backports of two fixes for memory leaks in the gpio sysfs interface that are needed in the stable trees.
Tested on 3.12, but will not compile on 3.10 or earlier which lacks device_create_with_groups. I'll send a second version for these kernels.
Johan
Johan Hovold (2):
gpio: sysfs: fix gpio-chip device-attribute leak
gpio: sysfs: fix gpio device-attribute leak
drivers/gpio/gpiolib.c | 46 +++++++++++++++++++++------------------------- 1 file changed, 21 insertions(+), 25 deletions(-)
Signature · 1 line
2.0.5
PATCH 1/2 gpio: sysfs: fix gpio-chip device-attribute leak
Commit 121b6a79955a3a3fd7bbb9b8cb88d5b9dad6283d upstream.
The gpio-chip device attributes were never destroyed when the device was removed.
Fix by using device_create_with_groups() to create the device attributes of the chip class device.
Note that this also fixes the attribute-creation race with userspace.
--- drivers/gpio/gpiolib.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-)
drivers/gpio/gpiolib.c +8 -11
@@ -627,16 +627,13 @@ static ssize_t chip_ngpio_show(struct device *dev, } static DEVICE_ATTR(ngpio, 0444, chip_ngpio_show, NULL); -static const struct attribute *gpiochip_attrs[] = { +static struct attribute *gpiochip_attrs[] = { &dev_attr_base.attr, &dev_attr_label.attr, &dev_attr_ngpio.attr,NULL , }; - -static const struct attribute_group gpiochip_attr_group = { - .attrs = (struct attribute **) gpiochip_attrs, -}; +ATTRIBUTE_GROUPS (gpiochip);/* * /sys/class/gpio/export ... write-only
@@ -1001,13 +998,13 @@ static int gpiochip_export(struct gpio_chip *chip)/* use chip->base for the ID; it's already known to be unique */ mutex_lock (&sysfs_lock); - dev =device_create (&gpio_class, chip->dev,MKDEV (0 ,0 ), chip, -"gpiochip%d" , chip->base); -if (!IS_ERR (dev)) { - status =sysfs_create_group (&dev->kobj, - &gpiochip_attr_group); - }else + dev =device_create_with_groups (&gpio_class, chip->dev,MKDEV (0 ,0 ), + chip, gpiochip_groups, +"gpiochip%d" , chip->base); +if (IS_ERR (dev)) status =PTR_ERR (dev); +else + status =0 ; chip->exported = (status ==0 );mutex_unlock (&sysfs_lock);
Signature · 1 line
2.0.5
PATCH 2/2 gpio: sysfs: fix gpio device-attribute leak
In reply to Johan HovoldCommit 0915e6feb38de8d3601819992a5bd050201a56fa upstream.
The gpio device attributes were never destroyed when the gpio was unexported (or on export failures).
Use device_create_with_groups() to create the default device attributes of the gpio class device. Note that this also fixes the attribute-creation race with userspace for these attributes.
Remove contingent attributes in export error path and on unexport.
--- drivers/gpio/gpiolib.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-)
drivers/gpio/gpiolib.c +13 -14
@@ -362,7 +362,7 @@ static ssize_t gpio_value_store(struct device *dev,return status; } -static const DEVICE_ATTR(value, 0644, +static DEVICE_ATTR(value, 0644, gpio_value_show, gpio_value_store);static irqreturn_t gpio_sysfs_irq (int irq,void *priv)
@@ -580,18 +580,16 @@ static ssize_t gpio_active_low_store(struct device *dev,return status ? : size; } -static const DEVICE_ATTR(active_low, 0644, +static DEVICE_ATTR(active_low, 0644, gpio_active_low_show, gpio_active_low_store); -static const struct attribute *gpio_attrs[] = { +static struct attribute *gpio_attrs[] = { &dev_attr_value.attr, &dev_attr_active_low.attr,NULL , }; -static const struct attribute_group gpio_attr_group = { - .attrs = (struct attribute **) gpio_attrs, -}; +ATTRIBUTE_GROUPS (gpio);/* * /sys/class/gpio/gpiochipN/
@@ -788,18 +786,15 @@ static int gpiod_export(struct gpio_desc *desc, bool direction_may_change)if (desc->chip->names && desc->chip->names[offset]) ioname = desc->chip->names[offset]; - dev =device_create (&gpio_class, desc->chip->dev,MKDEV (0 ,0 ), - desc, ioname ? ioname :"gpio%u" , -desc_to_gpio (desc)); + dev =device_create_with_groups (&gpio_class, desc->chip->dev, +MKDEV (0 ,0 ), desc, gpio_groups, + ioname ? ioname :"gpio%u" , +desc_to_gpio (desc));if (IS_ERR (dev)) { status =PTR_ERR (dev); goto fail_unlock; } - status =sysfs_create_group (&dev->kobj, &gpio_attr_group); -if (status) - goto fail_unregister_device; -if (direction_may_change) { status =device_create_file (dev, &dev_attr_direction);if (status)
@@ -810,13 +805,15 @@ static int gpiod_export(struct gpio_desc *desc, bool direction_may_change) !test_bit(FLAG_IS_OUT, &desc->flags))) { status =device_create_file (dev, &dev_attr_edge);if (status) - goto fail_unregister_device; + goto fail_remove_attr_direction; }set_bit (FLAG_EXPORT , &desc->flags);mutex_unlock (&sysfs_lock);return 0 ; +fail_remove_attr_direction: +device_remove_file (dev, &dev_attr_direction); fail_unregister_device:device_unregister (dev); fail_unlock:
@@ -959,6 +956,8 @@ static void gpiod_unexport(struct gpio_desc *desc) dev =class_find_device (&gpio_class,NULL , desc, match_export);if (dev) { +device_remove_file (dev, &dev_attr_edge); +device_remove_file (dev, &dev_attr_direction);gpio_setup_irq (desc, dev,0 );clear_bit (FLAG_EXPORT , &desc->flags); }else
Signature · 1 line
2.0.5
cover gpio: sysfs: backports of memleak fixes to 3.10
In reply to Johan HovoldAnd here are the backports of the two fixes for memory leaks in the gpio sysfs interface for 3.10 and earlier.
Tested on 3.12 and compile-tested on 3.10.
Johan
Johan Hovold (2):
gpio: sysfs: fix gpio-chip device-attribute leak
gpio: sysfs: fix gpio device-attribute leak
drivers/gpio/gpiolib.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-)
Signature · 1 line
2.0.5
PATCH 1/2 gpio: sysfs: fix gpio-chip device-attribute leak
Commit 121b6a79955a3a3fd7bbb9b8cb88d5b9dad6283d upstream.
The gpio-chip device attributes were never destroyed when the device was removed.
Fix by using device_create_with_groups() to create the device attributes of the chip class device.
Note that this also fixes the attribute-creation race with userspace.
[johan: fix leak without device_create_with_groups, which wasn't introduced until 3.11 ]
--- drivers/gpio/gpiolib.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/gpio/gpiolib.c +3 -2
@@ -627,7 +627,7 @@ static ssize_t chip_ngpio_show(struct device *dev, } static DEVICE_ATTR(ngpio, 0444, chip_ngpio_show, NULL); -static const struct attribute *gpiochip_attrs[] = { +static struct attribute *gpiochip_attrs[] = { &dev_attr_base.attr, &dev_attr_label.attr, &dev_attr_ngpio.attr,
@@ -635,7 +635,7 @@ static const struct attribute *gpiochip_attrs[] = { };static const struct attribute_group gpiochip_attr_group = { - .attrs = (struct attribute **) gpiochip_attrs, + .attrs = gpiochip_attrs, };/*
@@ -1036,6 +1036,7 @@ static void gpiochip_unexport(struct gpio_chip *chip)mutex_lock (&sysfs_lock); dev =class_find_device (&gpio_class,NULL , chip, match_export);if (dev) { +sysfs_remove_group (&dev->kobj, &gpiochip_attr_group);put_device (dev);device_unregister (dev); chip->exported =0 ;
Signature · 1 line
2.0.5
PATCH 2/2 gpio: sysfs: fix gpio device-attribute leak
In reply to Johan HovoldCommit 0915e6feb38de8d3601819992a5bd050201a56fa upstream.
The gpio device attributes were never destroyed when the gpio was unexported (or on export failures).
Use device_create_with_groups() to create the default device attributes of the gpio class device. Note that this also fixes the attribute-creation race with userspace for these attributes.
Remove contingent attributes in export error path and on unexport.
[johan: fix leaks without device_create_with_groups, which wasn't introduced until 3.11 ]
--- drivers/gpio/gpiolib.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-)
drivers/gpio/gpiolib.c +13 -6
@@ -362,7 +362,7 @@ static ssize_t gpio_value_store(struct device *dev,return status; } -static const DEVICE_ATTR(value, 0644, +static DEVICE_ATTR(value, 0644, gpio_value_show, gpio_value_store);static irqreturn_t gpio_sysfs_irq (int irq,void *priv)
@@ -580,17 +580,17 @@ static ssize_t gpio_active_low_store(struct device *dev,return status ? : size; } -static const DEVICE_ATTR(active_low, 0644, +static DEVICE_ATTR(active_low, 0644, gpio_active_low_show, gpio_active_low_store); -static const struct attribute *gpio_attrs[] = { +static struct attribute *gpio_attrs[] = { &dev_attr_value.attr, &dev_attr_active_low.attr,NULL , };static const struct attribute_group gpio_attr_group = { - .attrs = (struct attribute **) gpio_attrs, + .attrs = gpio_attrs, };/*
@@ -806,20 +806,24 @@ static int gpiod_export(struct gpio_desc *desc, bool direction_may_change)if (direction_may_change) { status =device_create_file (dev, &dev_attr_direction);if (status) - goto fail_unregister_device; + goto fail_remove_attr_group; }if (gpiod_to_irq (desc) >=0 && (direction_may_change || !test_bit (FLAG_IS_OUT , &desc->flags))) { status =device_create_file (dev, &dev_attr_edge);if (status) - goto fail_unregister_device; + goto fail_remove_attr_direction; }set_bit (FLAG_EXPORT , &desc->flags);mutex_unlock (&sysfs_lock);return 0 ; +fail_remove_attr_direction: +device_remove_file (dev, &dev_attr_direction); +fail_remove_attr_group: +sysfs_remove_group (&dev->kobj, &gpio_attr_group); fail_unregister_device:device_unregister (dev); fail_unlock:
@@ -962,6 +966,9 @@ static void gpiod_unexport(struct gpio_desc *desc) dev =class_find_device (&gpio_class,NULL , desc, match_export);if (dev) { +device_remove_file (dev, &dev_attr_edge); +device_remove_file (dev, &dev_attr_direction); +sysfs_remove_group (&dev->kobj, &gpio_attr_group);gpio_setup_irq (desc, dev,0 );clear_bit (FLAG_EXPORT , &desc->flags); }else
Signature · 1 line
2.0.5
Greg Kroah-Hartman
maintainerQuoted 7 lines · Johan Hovold
Hi Greg,
Here are backports of two fixes for memory leaks in the gpio sysfs interface that are needed in the stable trees.
Tested on 3.12, but will not compile on 3.10 or earlier which lacks
device_create_with_groups. I'll send a second version for these kernels.
Thanks for all of these, now applied.
greg k-h