staging: iio: adc: ad7280a: use devm_* APIs
Subsystems (4)
PATCH v3 1/1 staging: iio: adc: ad7280a: use devm_* APIs
devm_* APIs are device managed and make code simpler.
---
Since v2:
* iio_device_register -> devm_iio_device_register
Since v1:
* request_threaded_irq -> devm_request_threaded_irq
--- drivers/staging/iio/adc/ad7280a.c | 61 +++++++++++-------------------- 1 file changed, 22 insertions(+), 39 deletions(-)
drivers/staging/iio/adc/ad7280a.c +22 -39
@@ -8,7 +8,6 @@#include <linux/device.h> #include <linux/kernel.h> -#include <linux/slab.h> #include <linux/sysfs.h> #include <linux/spi/spi.h> #include <linux/err.h>
@@ -492,8 +491,8 @@ static int ad7280_channel_init(struct ad7280_state *st) {int dev, ch, cnt; - st->channels =kcalloc ((st->slave_num +1 ) *12 +2 , -sizeof (*st->channels),GFP_KERNEL ); + st->channels =devm_kcalloc (&st->spi->dev, (st->slave_num +1 ) *12 +2 , +sizeof (*st->channels),GFP_KERNEL );if (!st->channels)return -ENOMEM ;
@@ -553,9 +552,9 @@ static int ad7280_attr_init(struct ad7280_state *st) {int dev, ch, cnt; - st->iio_attr =kcalloc (2 ,sizeof (*st->iio_attr) * - (st->slave_num +1 ) *AD7280A_CELLS_PER_DEV , -GFP_KERNEL ); + st->iio_attr =devm_kcalloc (&st->spi->dev,2 ,sizeof (*st->iio_attr) * + (st->slave_num +1 ) *AD7280A_CELLS_PER_DEV , +GFP_KERNEL );if (!st->iio_attr)return -ENOMEM ;
@@ -692,7 +691,8 @@ static irqreturn_t ad7280_event_handler(int irq, void *private)unsigned int *channels;int i, ret; - channels =kcalloc (st->scan_cnt,sizeof (*channels),GFP_KERNEL ); + channels =devm_kcalloc (&st->spi->dev, st->scan_cnt,sizeof (*channels), +GFP_KERNEL );if (!channels)return IRQ_HANDLED ;
@@ -744,7 +744,7 @@ static irqreturn_t ad7280_event_handler(int irq, void *private) } out: -kfree (channels); +devm_kfree (&st->spi->dev, channels);return IRQ_HANDLED ; }
@@ -909,48 +909,38 @@ static int ad7280_probe(struct spi_device *spi) ret =ad7280_attr_init (st);if (ret <0 ) - goto error_free_channels; +return ret; - ret =iio_device_register (indio_dev); + ret =devm_iio_device_register (&spi->dev, indio_dev);if (ret) - goto error_free_attr; +return ret;if (spi->irq >0 ) { ret =ad7280_write (st,AD7280A_DEVADDR_MASTER ,AD7280A_ALERT ,1 ,AD7280A_ALERT_RELAY_SIG_CHAIN_DOWN );if (ret) - goto error_unregister; +return ret; ret =ad7280_write (st,ad7280a_devaddr (st->slave_num),AD7280A_ALERT ,0 ,AD7280A_ALERT_GEN_STATIC_HIGH | (pdata->chain_last_alert_ignore &0xF ));if (ret) - goto error_unregister; - - ret =request_threaded_irq (spi->irq, -NULL , - ad7280_event_handler, -IRQF_TRIGGER_FALLING | -IRQF_ONESHOT , - indio_dev->name, - indio_dev); +return ret; + + ret =devm_request_threaded_irq (&spi->dev, spi->irq, +NULL , + ad7280_event_handler, +IRQF_TRIGGER_FALLING | +IRQF_ONESHOT , + indio_dev->name, + indio_dev);if (ret) - goto error_unregister; +return ret; }return 0 ; -error_unregister: -iio_device_unregister (indio_dev); - -error_free_attr: -kfree (st->iio_attr); - -error_free_channels: -kfree (st->channels); - -return ret; }static int ad7280_remove (struct spi_device *spi)
@@ -958,16 +948,9 @@ static int ad7280_remove(struct spi_device *spi)struct iio_dev *indio_dev =spi_get_drvdata (spi);struct ad7280_state *st =iio_priv (indio_dev); -if (spi->irq >0 ) -free_irq (spi->irq, indio_dev); -iio_device_unregister (indio_dev); -ad7280_write (st,AD7280A_DEVADDR_MASTER ,AD7280A_CONTROL_HB ,1 ,AD7280A_CTRL_HB_PWRDN_SW | st->ctrl_hb); -kfree (st->channels); -kfree (st->iio_attr); -return 0 ; }
Signature · 1 line
2.19.1
Jonathan Cameron
maintainerQuoted 3 lines · On Fri, 19 Oct 2018 20:20:13 +0200 Slawomir Stepien <[email protected]> wrote:
devm_* APIs are device managed and make code simpler.
Signed-off-by Slawomir Stepien <[email protected]>
Hi Slawomir,
There are some complexities in using the managed allocators, almost always around possible race conditions. See inline.
Jonathan
Quoted 57 lines
---
Since v2:
*iio_device_register->devm_iio_device_registerSince v1:
*request_threaded_irq->devm_request_threaded_irq--- drivers/staging/iio/adc/ad7280a.c | 61 +++++++++++-------------------- 1 file changed, 22 insertions(+), 39 deletions(-)drivers/staging/iio/adc/ad7280a.c +7
-7@@ -8,7 +8,6 @@#include <linux/device.h> #include <linux/kernel.h> -#include <linux/slab.h> #include <linux/sysfs.h> #include <linux/spi/spi.h> #include <linux/err.h> @@ -492,8 +491,8 @@ static int ad7280_channel_init(struct ad7280_state *st) {int dev, ch, cnt; - st->channels =kcalloc ((st->slave_num +1 ) *12 +2 , -sizeof (*st->channels),GFP_KERNEL ); + st->channels =devm_kcalloc (&st->spi->dev, (st->slave_num +1 ) *12 +2 , +sizeof (*st->channels),GFP_KERNEL );if (!st->channels)return -ENOMEM ;@@ -553,9 +552,9 @@ static int ad7280_attr_init(struct ad7280_state *st) {int dev, ch, cnt; - st->iio_attr =kcalloc (2 ,sizeof (*st->iio_attr) * - (st->slave_num +1 ) *AD7280A_CELLS_PER_DEV , -GFP_KERNEL ); + st->iio_attr =devm_kcalloc (&st->spi->dev,2 ,sizeof (*st->iio_attr) * + (st->slave_num +1 ) *AD7280A_CELLS_PER_DEV , +GFP_KERNEL );if (!st->iio_attr)return -ENOMEM ;@@ -692,7 +691,8 @@ static irqreturn_t ad7280_event_handler(int irq, void *private)unsigned int *channels;int i, ret; - channels =kcalloc (st->scan_cnt,sizeof (*channels),GFP_KERNEL ); + channels =devm_kcalloc (&st->spi->dev, st->scan_cnt,sizeof (*channels), +GFP_KERNEL );if (!channels)return IRQ_HANDLED ;
drivers/staging/iio/adc/ad7280a.c static irqreturn_t ad7280_event_handler(int irq, void *private) · line 747
Quoted 5 lines
drivers/staging/iio/adc/ad7280a.c +1
-1@@ -744,7 +744,7 @@ static irqreturn_t ad7280_event_handler(int irq, void *private) } out: -kfree (channels); +devm_kfree (&st->spi->dev, channels);
Now this I really don't want to see.
Using the managed framework is far from free. Please don't do it when the normal path is to free the buffer like this...
Quoted 67 lines
drivers/staging/iio/adc/ad7280a.c +14
-24return IRQ_HANDLED ; }@@ -909,48 +909,38 @@ static int ad7280_probe(struct spi_device *spi) ret =ad7280_attr_init (st);if (ret <0 ) - goto error_free_channels; +return ret; - ret =iio_device_register (indio_dev); + ret =devm_iio_device_register (&spi->dev, indio_dev);if (ret) - goto error_free_attr; +return ret;if (spi->irq >0 ) { ret =ad7280_write (st,AD7280A_DEVADDR_MASTER ,AD7280A_ALERT ,1 ,AD7280A_ALERT_RELAY_SIG_CHAIN_DOWN );if (ret) - goto error_unregister; +return ret; ret =ad7280_write (st,ad7280a_devaddr (st->slave_num),AD7280A_ALERT ,0 ,AD7280A_ALERT_GEN_STATIC_HIGH | (pdata->chain_last_alert_ignore &0xF ));if (ret) - goto error_unregister; - - ret =request_threaded_irq (spi->irq, -NULL , - ad7280_event_handler, -IRQF_TRIGGER_FALLING | -IRQF_ONESHOT , - indio_dev->name, - indio_dev); +return ret; + + ret =devm_request_threaded_irq (&spi->dev, spi->irq, +NULL , + ad7280_event_handler, +IRQF_TRIGGER_FALLING | +IRQF_ONESHOT , + indio_dev->name, + indio_dev);if (ret) - goto error_unregister; +return ret; }return 0 ; -error_unregister: -iio_device_unregister (indio_dev); - -error_free_attr: -kfree (st->iio_attr); - -error_free_channels: -kfree (st->channels); - -return ret; }static int ad7280_remove (struct spi_device *spi)
drivers/staging/iio/adc/ad7280a.c static int ad7280_remove(struct spi_device *spi) · line 952
Quoted 9 lines
drivers/staging/iio/adc/ad7280a.c +0
-4@@ -958,16 +948,9 @@ static int ad7280_remove(struct spi_device *spi)struct iio_dev *indio_dev =spi_get_drvdata (spi);struct ad7280_state *st =iio_priv (indio_dev); -if (spi->irq >0 ) -free_irq (spi->irq, indio_dev); -iio_device_unregister (indio_dev); -ad7280_write (st,AD7280A_DEVADDR_MASTER ,AD7280A_CONTROL_HB ,1 ,AD7280A_CTRL_HB_PWRDN_SW | st->ctrl_hb);
So here, you need to think very carefully about what the various steps are doing. By moving to devm_iio_device_unregister what difference has it made to the sequence of calls in remove?
The upshot is you just turned the device off before removing the interfaces which would allow userspace / kernel consumers to access the device. A classic race condition that 'might' open up opportunities for problems.
Often the reality is that these sorts of races have very minimal impact, but they do break the cardinal rule that code should be obviously right (if possible). Hence you can't do this sort of conversion so simply. You can consider using the devm_add_action approach to ensure the tear down is in the right order though...
drivers/staging/iio/adc/ad7280a.c static int ad7280_remove(struct spi_device *spi) · line 969
Quoted 3 lines
drivers/staging/iio/adc/ad7280a.c +0
-2-kfree (st->channels); -kfree (st->iio_attr);
These two are obviously fine as nothing happens after them anyway!
Quoted 4 lines
drivers/staging/iio/adc/ad7280a.c +0
-1-return 0 ; }
Quoted 11 lines · Jonathan Cameron
Quoted 3 lines · On Fri, 19 Oct 2018 20:20:13 +0200 Slawomir Stepien <[email protected]> wrote:
devm_* APIs are device managed and make code simpler.
Signed-off-by Slawomir Stepien <[email protected]>Hi Slawomir,
There are some complexities in using the managed allocators, almost always around possible race conditions. See inline.
Thank you so much for pointing the problems!
Quoted 13 lines
Quoted 13 lines
drivers/staging/iio/adc/ad7280a.c +2
-1@@ -692,7 +691,8 @@ static irqreturn_t ad7280_event_handler(int irq, void *private)unsigned int *channels;int i, ret; - channels =kcalloc (st->scan_cnt,sizeof (*channels),GFP_KERNEL ); + channels =devm_kcalloc (&st->spi->dev, st->scan_cnt,sizeof (*channels), +GFP_KERNEL );if (!channels)return IRQ_HANDLED ;@@ -744,7 +744,7 @@ static irqreturn_t ad7280_event_handler(int irq, void *private) }
Quoted 7 lines
drivers/staging/iio/adc/ad7280a.c static irqreturn_t ad7280_event_handler(int irq, void *private) · line 747
Quoted 3 lines
drivers/staging/iio/adc/ad7280a.c +1
-1out: -kfree (channels); +devm_kfree (&st->spi->dev, channels);Now this I really don't want to see.
Using the managed framework is far from free. Please don't do it when the normal path is to free the buffer like this...
OK
Quoted 22 lines
drivers/staging/iio/adc/ad7280a.c static int ad7280_remove(struct spi_device *spi) · line 952
Quoted 13 lines
drivers/staging/iio/adc/ad7280a.c +0
-4return IRQ_HANDLED ; }static int ad7280_remove (struct spi_device *spi)@@ -958,16 +948,9 @@ static int ad7280_remove(struct spi_device *spi)struct iio_dev *indio_dev =spi_get_drvdata (spi);struct ad7280_state *st =iio_priv (indio_dev); -if (spi->irq >0 ) -free_irq (spi->irq, indio_dev); -iio_device_unregister (indio_dev); -ad7280_write (st,AD7280A_DEVADDR_MASTER ,AD7280A_CONTROL_HB ,1 ,AD7280A_CTRL_HB_PWRDN_SW | st->ctrl_hb);So here, you need to think very carefully about what the various steps are doing. By moving to
devm_iio_device_unregisterwhat difference has it made to the sequence of calls in remove?The upshot is you just turned the device off before removing the interfaces which would allow userspace / kernel consumers to access the device. A classic race condition that 'might' open up opportunities for problems.
Quoted 5 lines
Often the reality is that these sorts of races have very minimal impact, but they do break the cardinal rule that code should be obviously right (if possible). Hence you can't do this sort of conversion so simply. You can consider using the
devm_add_actionapproach to ensure the tear down is in the right order though...
Yes I understand the problem here. I have some questions regarding devm_add_action that might solve the problem here:
1. My understanding is that the action has to be added on the devres list before the devm_iio_device_register call, so during unwinding the action will be called after the call to devm_iio_device_unreg. Other order will be still not correct. Am I thinking correctly here?
Please note that doing the action from probe is changing the current behaviour of the driver - we will put the device into power-down software state also from probe() (if irq setup fails).
2. devm_iio_device_unregister from what I see could be used here in place of iio_device_unregister. Maybe that is the best way to go?
Signature · 1 line
Slawomir Stepien
Jonathan Cameron
maintainerQuoted 12 lines · On Tue, 23 Oct 2018 15:32:34 +0200 Slawomir Stepien <[email protected]> wrote:
Quoted 11 lines · Jonathan Cameron
On Fri, 19 Oct 2018 20:20:13 +0200
Slawomir Stepien <[email protected]> wrote:
=20Quoted 3 lines
devm_* APIs are device managed and make code simpler. =20
Signed-off-by Slawomir Stepien <[email protected]> =20=20
Hi Slawomir,
=20
There are some complexities in using the managed allocators, almost always around possible race conditions. See inline. =20
Quoted 4 lines
=20
Thank you so much for pointing the problems!
=20Quoted 1 line
Review static irqreturn_t ad7280_event_handler(int irq, =
Quoted 1 line
(quoted diff) +0
-0@@ -692,7 +691,8 @@ static irqreturn_t ad7280_event_handler(int irq, =
void *private)
Quoted 5 lines
Quoted 5 lines
Review
Quoted 5 lines
drivers/staging/iio/adc/ad7280a.c +0
-0unsigned int *channels;int i, ret;=20
(quoted diff) +1
-1- channels =3D kcalloc(st->scan_cnt, sizeof(*channels), GFP_KERNEL); + channels =3D devm_kcalloc(&st->spi->dev, st->scan_cnt, sizeof(*chan=
nels),
Quoted 5 lines
Quoted 5 lines
Review static irqreturn_t ad7280_event_handler(int irq, =
Quoted 5 lines
drivers/staging/iio/adc/ad7280a.c +1
-0+ GFP_KERNEL);if (!channels)return IRQ_HANDLED ;=20
(quoted diff) +0
-0@@ -744,7 +744,7 @@ static irqreturn_t ad7280_event_handler(int irq, =
void *private)
Quoted 8 lines
Quoted 8 lines
Review
Quoted 5 lines
(quoted diff) +0
-0}=20
out:(quoted diff) +1
-1- kfree(channels); + devm_kfree(&st->spi->dev, channels); =20=20
Now this I really don't want to see.
Using the managed framework is far from free. Please don't do it when t=
he
Quoted 31 lines
Quoted 1 line
normal path is to free the buffer like this... =20
=20
OK
=20Quoted 19 lines
drivers/staging/iio/adc/ad7280a.c static int ad7280_remove(struct spi_device *spi)
Quoted 13 lines
drivers/staging/iio/adc/ad7280a.c +0
-0return IRQ_HANDLED ; }static int ad7280_remove (struct spi_device *spi)@@ -958,16 +948,9 @@ static int ad7280_remove(struct spi_device *spi) struct iio_dev *indio_dev =3D spi_get_drvdata(spi); struct ad7280_state *st =3D iio_priv(indio_dev);=20
drivers/staging/iio/adc/ad7280a.c +0
-4-if (spi->irq >0 ) -free_irq (spi->irq, indio_dev); -iio_device_unregister (indio_dev); -ad7280_write (st,AD7280A_DEVADDR_MASTER ,AD7280A_CONTROL_HB ,1 , AD7280A_CTRL_HB_PWRDN_SW | st->ctrl_hb); =20So here, you need to think very carefully about what the various steps are doing. By moving to
devm_iio_device_unregisterwhat difference has it made to the sequence of calls in remove? =20
The upshot is you just turned the device off before removing the interfaces which would allow userspace / kernel consumers toQuoted 8 lines
access the device. A classic race condition that 'might' open up opportunities for problems.
=20
Often the reality is that these sorts of races have very minimal impact, but they do break the cardinal rule that code should be obviously right (if possible). Hence you can't do this sort of conversion so simply. You can consider using thedevm_add_actionapproach to ensure the tear down is in the right order though... =20
Quoted 5 lines
=20
Yes I understand the problem here. I have some questions regardingdevm_add_actionthat might solve the problem here:
=20
1. My understanding is that the action has to be added on the devres list=
before
Quoted 1 line
the
devm_iio_device_registercall, so during unwinding the action will be=
called
Quoted 1 line
after the call to
devm_iio_device_unreg. Other order will be still not co=
rrect.
Quoted 1 line
Am I thinking correctly here?
Yes. That's correct.
Quoted 2 lines
=20
Please note that doing the action from probe is changing the current beha=
viour
Quoted 1 line
of the driver - we will put the device into power-down software state als=
o from
Quoted 1 line
probe()(if irq setup fails).
True. In the case an irq being specified but not probing successfully we wi= ll
fail the probe and put the device into a power down state. However, to my mind that's the right thing to do anyway. I can't see why we would want the device powered up having decided to abandon the attempt to load a driver for it? (am I missing something?)
The more 'interesting' question is why we are registering the interrupts after iio_device_register in the first place. We have exposed our userspace interfaces, but not yet an interrupt that I assume has something to do with=
them?
iio_device_register should almost always be the last thing run in probe.
Quoted 2 lines
=20
2.devm_iio_device_unregisterfrom what I see could be used here in place=
of
Quoted 2 lines
iio_device_unregister. Maybe that is the best way to go? =20
Definitely not this one. The only rare case for manually using the counter parts to the devm_ setup functions is to replace some data or configuration rather to manually unwind the steps for some error path.
Thanks,
Jonathan
Hi
Quoted 35 lines · Jonathan Cameron
Quoted 26 lines
Quoted 20 lines
drivers/staging/iio/adc/ad7280a.c static int ad7280_remove(struct spi_device *spi) · line 952
Quoted 11 lines
static int
ad7280_remove(struct spi_device *spi)drivers/staging/iio/adc/ad7280a.c +0
-4@@ -958,16 +948,9 @@ static int ad7280_remove(struct spi_device *spi)struct iio_dev *indio_dev =spi_get_drvdata (spi);struct ad7280_state *st =iio_priv (indio_dev); -if (spi->irq >0 ) -free_irq (spi->irq, indio_dev); -iio_device_unregister (indio_dev); -ad7280_write (st,AD7280A_DEVADDR_MASTER ,AD7280A_CONTROL_HB ,1 ,AD7280A_CTRL_HB_PWRDN_SW | st->ctrl_hb);So here, you need to think very carefully about what the various steps are doing. By moving to
devm_iio_device_unregisterwhat difference has it made to the sequence of calls in remove?The upshot is you just turned the device off before removing the interfaces which would allow userspace / kernel consumers to access the device. A classic race condition that 'might' open up opportunities for problems.
Quoted 5 lines
Often the reality is that these sorts of races have very minimal impact, but they do break the cardinal rule that code should be obviously right (if possible). Hence you can't do this sort of conversion so simply. You can consider using the
devm_add_actionapproach to ensure the tear down is in the right order though...Quoted 7 lines
Yes I understand the problem here. I have some questions regarding
devm_add_actionthat might solve the problem here:1. My understanding is that the action has to be added on the devres list before the
devm_iio_device_registercall, so during unwinding the action will be called after the call todevm_iio_device_unreg. Other order will be still not correct. Am I thinking correctly here?Yes. That's correct.
Quoted 1 line
Quoted 8 lines
Quoted 3 lines
Please note that doing the action from probe is changing the current behaviour of the driver - we will put the device into power-down software state also from
probe()(if irq setup fails).True. In the case an irq being specified but not probing successfully we will fail the probe and put the device into a power down state. However, to my mind that's the right thing to do anyway. I can't see why we would want the device powered up having decided to abandon the attempt to load a driver for it? (am I missing something?)
I'll send a patch with this action.
Quoted 5 lines
The more 'interesting' question is why we are registering the interrupts after
iio_device_registerin the first place. We have exposed our userspace interfaces, but not yet an interrupt that I assume has something to do with them?
iio_device_registershould almost always be the last thing run in probe.
I've looked at the data sheet and the code and concluded that the order is OK. Why? The irq handler can only fire after conversion is completed. The conversion can start only in two ways:
(1) falling edge of CNVST input (default) which we don't control
(2) rising edge of CS, which we control
Since we only using the 2nd option, then it is wise to allow users to have CNVST connected and going down, before any readout of the values using this driver (this will change the CS). This way we will not loose any alert about UV or OV.
In case we have irq handler ready before iio_device_register, then I assume that we might loose alert change event. Maybe it's hard (timing), but I think it's possible.
What do you think?
Quoted 6 lines
Quoted 3 lines
2.
devm_iio_device_unregisterfrom what I see could be used here in place ofiio_device_unregister. Maybe that is the best way to go?Definitely not this one. The only rare case for manually using the counter parts to the
devm_setup functions is to replace some data or configuration rather to manually unwind the steps for some error path.
OK, got it!
Signature · 1 line
Slawomir Stepien
Jonathan Cameron
maintainerQuoted 5 lines · On Mon, 29 Oct 2018 17:47:24 +0100 Slawomir Stepien <[email protected]> wrote:
Hi
=20Quoted 2 lines · Jonathan Cameron
Quoted 2 lines
Quoted 2 lines
Review static int ad7280_remove(struct spi_device *=
Quoted 2 lines
static int
ad7280_remove(struct spi_device *spi)(quoted diff) +0
-0@@ -958,16 +948,9 @@ static int ad7280_remove(struct spi_device *=
spi)
Quoted 15 lines
Quoted 15 lines
Quoted 15 lines
Quoted 15 lines
drivers/staging/iio/adc/ad7280a.c static int ad7280_remove(struct spi_device *spi)
Quoted 9 lines
(quoted diff) +0
-0struct iio_dev *indio_dev =3D spi_get_drvdata(spi); struct ad7280_state *st =3D iio_priv(indio_dev);=20
drivers/staging/iio/adc/ad7280a.c +0
-4-if (spi->irq >0 ) -free_irq (spi->irq, indio_dev); -iio_device_unregister (indio_dev); -ad7280_write (st,AD7280A_DEVADDR_MASTER ,AD7280A_CONTROL_HB ,1 , AD7280A_CTRL_HB_PWRDN_SW | st->ctrl_hb); =20So here, you need to think very carefully about what the various steps are doing. By moving to
devm_iio_device_unregisterwhat difference has it made to the sequence of calls in remove? =20
The upshot is you just turned the device off before removing the interfaces which would allow userspace / kernel consumers to
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
access the device. A classic race condition that 'might' open up opportunities for problems.
=20
Often the reality is that these sorts of races have very minimal impact, but they do break the cardinal rule that code should be obviously right (if possible). Hence you can't do this sort of conversion so simply. You can consider using thedevm_add_action
approach to ensure the tear down is in the right order though... =
=20
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
=20
Yes I understand the problem here. I have some questions regardingdevm_add_actionthat might solve the problem here:
=20
1. My understanding is that the action has to be added on the devres =
list before
Quoted 1 line
Quoted 1 line
Quoted 1 line
the
devm_iio_device_registercall, so during unwinding the action wil=
l be called
Quoted 1 line
Quoted 1 line
Quoted 1 line
after the call to
devm_iio_device_unreg. Other order will be still no=
t correct.
Quoted 4 lines
Quoted 4 lines
Quoted 1 line
Am I thinking correctly here? =20
Yes. That's correct. =20
Quoted 2 lines
=20
Please note that doing the action from probe is changing the current =
behaviour
Quoted 1 line
Quoted 1 line
Quoted 1 line
of the driver - we will put the device into power-down software state=
also from
Quoted 2 lines
Quoted 2 lines
Quoted 1 line
probe()(if irq setup fails). =20True. In the case an irq being specified but not probing successfully w=
e will
Quoted 1 line
Quoted 1 line
fail the probe and put the device into a power down state. However, to=
my
Quoted 2 lines
Quoted 2 lines
mind that's the right thing to do anyway. I can't see why we would want the device powered up having decided to abandon the attempt to load a d=
river
Quoted 6 lines
Quoted 1 line
for it? (am I missing something?) =20
=20
I'll send a patch with this action.
=20Quoted 2 lines
The more 'interesting' question is why we are registering the interrupts after
iio_device_registerin the first place. We have exposed our user=
space
Quoted 1 line
Quoted 1 line
interfaces, but not yet an interrupt that I assume has something to do =
with them?
Quoted 2 lines
Quoted 2 lines
=20
iio_device_registershould almost always be the last thing run in probe=
. =20
Quoted 2 lines
=20
I've looked at the data sheet and the code and concluded that the order i=
s OK.
Quoted 1 line
Why? The irq handler can only fire after conversion is completed. The con=
version
Quoted 3 lines
can start only in two ways:
=20
(1) falling edge of CNVST input (default) which we don't control
That's a potential problem. We shouldn't start by default in a mode where interrupts can occur before we are potentially ready for them. They should only be enabled by a specific request from userspace.
A quick at the datasheet suggests this is easily done by writing 0 to the alert register and only enabling it on demand.
Quoted 3 lines
(2) rising edge of CS, which we control
=20
Since we only using the 2nd option, then it is wise to allow users to hav=
e CNVST
Quoted 1 line
connected and going down, before any readout of the values using this dri=
ver
Quoted 1 line
(this will change the CS). This way we will not loose any alert about UV =
or OV.
I agree we are looking at theoretical race, but as I mentioned it's about obviously correct (and general correct ordering) rather than anthing else. In theory we can have very long delay between exposing the interfaces and setting up the interrupt. So it's possible to hit case 2 before we get the interrupt set up.
Quoted 2 lines
=20
In case we have irq handler ready beforeiio_device_register, then I assu=
me that
Quoted 1 line
we might loose alert change event. Maybe it's hard (timing), but I think =
it's
Quoted 5 lines
possible.
=20
What do you think?
=20Quoted 1 line
Quoted 1 line
2.
devm_iio_device_unregisterfrom what I see could be used here in p=
lace of
Quoted 5 lines
Quoted 5 lines
Quoted 2 lines
iio_device_unregister. Maybe that is the best way to go?
=20Definitely not this one. The only rare case for manually using the counter parts to the
devm_setup functions is to replace some data or configuration rather to manually unwind the steps for some error path. =
=20
Quoted 3 lines
=20
OK, got it!
=20
Quoted 59 lines · Jonathan Cameron
Quoted 57 lines · On Mon, 29 Oct 2018 17:47:24 +0100 Slawomir Stepien <[email protected]> wrote:
Quoted 35 lines · Jonathan Cameron
Quoted 26 lines
Quoted 20 lines
drivers/staging/iio/adc/ad7280a.c static int ad7280_remove(struct spi_device *spi) · line 952
Quoted 11 lines
static int
ad7280_remove(struct spi_device *spi)drivers/staging/iio/adc/ad7280a.c +0
-4@@ -958,16 +948,9 @@ static int ad7280_remove(struct spi_device *spi)struct iio_dev *indio_dev =spi_get_drvdata (spi);struct ad7280_state *st =iio_priv (indio_dev); -if (spi->irq >0 ) -free_irq (spi->irq, indio_dev); -iio_device_unregister (indio_dev); -ad7280_write (st,AD7280A_DEVADDR_MASTER ,AD7280A_CONTROL_HB ,1 ,AD7280A_CTRL_HB_PWRDN_SW | st->ctrl_hb);So here, you need to think very carefully about what the various steps are doing. By moving to
devm_iio_device_unregisterwhat difference has it made to the sequence of calls in remove?The upshot is you just turned the device off before removing the interfaces which would allow userspace / kernel consumers to access the device. A classic race condition that 'might' open up opportunities for problems.
Quoted 5 lines
Often the reality is that these sorts of races have very minimal impact, but they do break the cardinal rule that code should be obviously right (if possible). Hence you can't do this sort of conversion so simply. You can consider using the
devm_add_actionapproach to ensure the tear down is in the right order though...Quoted 7 lines
Yes I understand the problem here. I have some questions regarding
devm_add_actionthat might solve the problem here:1. My understanding is that the action has to be added on the devres list before the
devm_iio_device_registercall, so during unwinding the action will be called after the call todevm_iio_device_unreg. Other order will be still not correct. Am I thinking correctly here?Yes. That's correct.
Quoted 1 line
Quoted 8 lines
Quoted 3 lines
Please note that doing the action from probe is changing the current behaviour of the driver - we will put the device into power-down software state also from
probe()(if irq setup fails).True. In the case an irq being specified but not probing successfully we will fail the probe and put the device into a power down state. However, to my mind that's the right thing to do anyway. I can't see why we would want the device powered up having decided to abandon the attempt to load a driver for it? (am I missing something?)
I'll send a patch with this action.
Quoted 5 lines
The more 'interesting' question is why we are registering the interrupts after
iio_device_registerin the first place. We have exposed our userspace interfaces, but not yet an interrupt that I assume has something to do with them?
iio_device_registershould almost always be the last thing run in probe.I've looked at the data sheet and the code and concluded that the order is OK. Why? The irq handler can only fire after conversion is completed. The conversion can start only in two ways:
Quoted 6 lines
Quoted 1 line
(1) falling edge of CNVST input (default) which we don't control
That's a potential problem. We shouldn't start by default in a mode where interrupts can occur before we are potentially ready for them. They should only be enabled by a specific request from userspace.
A quick at the datasheet suggests this is easily done by writing 0 to the alert register and only enabling it on demand.
Do I understand this correctly: the interrupts should be enabled on user request, for example by writing 1 to additional iio_dev_attr, and disabled when writing 0 to that file?
Should that also be like this when using device tree node with interupt properties (e.g. interrupts) for that device (also working on that)?
Quoted 10 lines
Quoted 5 lines
(2) rising edge of CS, which we control
Since we only using the 2nd option, then it is wise to allow users to have CNVST connected and going down, before any readout of the values using this driver (this will change the CS). This way we will not loose any alert about UV or OV.
I agree we are looking at theoretical race, but as I mentioned it's about obviously correct (and general correct ordering) rather than anthing else. In theory we can have very long delay between exposing the interfaces and setting up the interrupt. So it's possible to hit case 2 before we get the interrupt set up.
Signature · 1 line
Slawomir Stepien
Jonathan Cameron
maintainerQuoted 6 lines · On Fri, 9 Nov 2018 19:23:51 +0100 Slawomir Stepien <[email protected]> wrote:
Quoted 5 lines · Jonathan Cameron
On Mon, 29 Oct 2018 17:47:24 +0100
Slawomir Stepien <[email protected]> wrote: =20Quoted 3 lines
On pa=C5=BA 28, 2018 12:16, Jonathan Cameron wrote: =20
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Review static int ad7280_remove(struct spi_devi=
Quoted 2 lines
static int
ad7280_remove(struct spi_device *spi)(quoted diff) +0
-0@@ -958,16 +948,9 @@ static int ad7280_remove(struct spi_devi=
ce *spi)
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Review
Quoted 8 lines
(quoted diff) +0
-0struct iio_dev *indio_dev =3D spi_get_drvdata(spi); struct ad7280_state *st =3D iio_priv(indio_dev);=20
(quoted diff) +0
-4- if (spi->irq > 0) - free_irq(spi->irq, indio_dev); - iio_device_unregister(indio_dev); - ad7280_write(st, AD7280A_DEVADDR_MASTER, AD7280A_CONTROL_HB=
, 1,
Quoted 14 lines
Quoted 14 lines
Quoted 14 lines
Quoted 14 lines
Quoted 14 lines
Quoted 14 lines
Quoted 1 line
AD7280A_CTRL_HB_PWRDN_SW|st->ctrl_hb); =20So here, you need to think very carefully about what the various steps are doing. By moving to
devm_iio_device_unregisterwhat difference has it made to the sequence of calls in remove? =20
The upshot is you just turned the device off before removing the interfaces which would allow userspace / kernel consumers to access the device. A classic race condition that 'might' open up opportunities for problems.
=20
Often the reality is that these sorts of races have very minimal impact, but they do break the cardinal rule that code should be obviously right (if possible). Hence you can't do this sort of conversion so simply. You can consider using the devm_add_a=
ction
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
approach to ensure the tear down is in the right order though..=
. =20
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
=20
Yes I understand the problem here. I have some questions regardingdevm_add_actionthat might solve the problem here:
=20
1. My understanding is that the action has to be added on the dev=
res list before
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
the
devm_iio_device_registercall, so during unwinding the action=
will be called
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
after the call to
devm_iio_device_unreg. Other order will be stil=
l not correct.
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 1 line
Am I thinking correctly here? =20
Yes. That's correct. =20
Quoted 2 lines
=20
Please note that doing the action from probe is changing the curr=
ent behaviour
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
of the driver - we will put the device into power-down software s=
tate also from
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 1 line
probe()(if irq setup fails). =20True. In the case an irq being specified but not probing successful=
ly we will
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
fail the probe and put the device into a power down state. However=
, to my
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
mind that's the right thing to do anyway. I can't see why we would=
want
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
the device powered up having decided to abandon the attempt to load=
a driver
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 1 line
for it? (am I missing something?) =20
=20
I'll send a patch with this action.
=20Quoted 1 line
The more 'interesting' question is why we are registering the inter=
rupts
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
after
iio_device_registerin the first place. We have exposed our =
userspace
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
interfaces, but not yet an interrupt that I assume has something to=
do with them?
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
=20
iio_device_registershould almost always be the last thing run in p=
robe. =20
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
=20
I've looked at the data sheet and the code and concluded that the ord=
er is OK.
Quoted 1 line
Quoted 1 line
Quoted 1 line
Why? The irq handler can only fire after conversion is completed. The=
conversion
Quoted 4 lines
Quoted 4 lines
Quoted 3 lines
can start only in two ways:
=20
(1) falling edge of CNVST input (default) which we don't control =20That's a potential problem. We shouldn't start by default in a mode wh=
ere
Quoted 1 line
Quoted 1 line
interrupts can occur before we are potentially ready for them. They sh=
ould
Quoted 2 lines
Quoted 2 lines
only be enabled by a specific request from userspace.
A quick at the datasheet suggests this is easily done by writing 0 to t=
he
Quoted 4 lines
Quoted 1 line
alert register and only enabling it on demand. =20
=20
Do I understand this correctly: the interrupts should be enabled on user request, for example by writing 1 to additionaliio_dev_attr, and disable=
d when
Quoted 1 line
writing 0 to that file?
We should move explicitly from a safe mode (software triggered) to this rem= ote
mode. It's a form of trigger, be it one we can't 'see' in software. There are other instances of such hardware triggers (stm32 drivers have some). It isn't a problem, but you need to provide the validation functions to ensure they can't be used to trigger other devices etc.
Quoted 2 lines
Should that also be like this when using device tree node with interupt properties (e.g. interrupts) for that device (also working on that)?
The default should never be to trigger capture on a remote signal. That sh= ould
only be enabled once the driver is ready for it, but a deliberate action fr= om
userspace.
Quoted 4 lines
=20
Quoted 3 lines
Quoted 3 lines
(2) rising edge of CS, which we control
=20
Since we only using the 2nd option, then it is wise to allow users to=
have CNVST
Quoted 1 line
Quoted 1 line
Quoted 1 line
connected and going down, before any readout of the values using this=
driver
Quoted 1 line
Quoted 1 line
Quoted 1 line
(this will change the CS). This way we will not loose any alert about=
UV or OV. =20
Quoted 1 line
Quoted 1 line
I agree we are looking at theoretical race, but as I mentioned it's abo=
ut
Quoted 1 line
Quoted 1 line
obviously correct (and general correct ordering) rather than anthing el=
se.
Quoted 1 line
Quoted 1 line
In theory we can have very long delay between exposing the interfaces a=
nd
Quoted 3 lines
Quoted 2 lines
setting up the interrupt. So it's possible to hit case 2 before we get the interrupt set up. =20
=20