Hi Nuno, noname.nuno@xxxxxxxxx wrote on Tue, 20 Sep 2022 16:56:01 +0200: > On Tue, 2022-09-20 at 15:53 +0200, Miquel Raynal wrote: > > Hi Nuno, > > > > Nuno.Sa@xxxxxxxxxx wrote on Tue, 20 Sep 2022 13:15:32 +0000: > > > > > > -----Original Message----- > > > > From: Miquel Raynal <miquel.raynal@xxxxxxxxxxx> > > > > Sent: Tuesday, September 20, 2022 2:56 PM > > > > To: Sa, Nuno <Nuno.Sa@xxxxxxxxxx> > > > > Cc: linux-arm-kernel@xxxxxxxxxxxxxxxxxxx; > > > > linux-rockchip@xxxxxxxxxxxxxxxxxxx; > > > > linux-amlogic@xxxxxxxxxxxxxxxxxxx; linux-imx@xxxxxxx; linux- > > > > iio@xxxxxxxxxxxxxxx; Chunyan Zhang <zhang.lyra@xxxxxxxxx>; > > > > Hennerich, > > > > Michael <Michael.Hennerich@xxxxxxxxxx>; Martin Blumenstingl > > > > <martin.blumenstingl@xxxxxxxxxxxxxx>; Sascha Hauer > > > > <s.hauer@xxxxxxxxxxxxxx>; Cixi Geng <cixi.geng1@xxxxxxxxxx>; > > > > Kevin > > > > Hilman <khilman@xxxxxxxxxxxx>; Vladimir Zapolskiy <vz@xxxxxxxxx>; > > > > Pengutronix Kernel Team <kernel@xxxxxxxxxxxxxx>; Alexandru > > > > Ardelean > > > > <aardelean@xxxxxxxxxxx>; Fabio Estevam <festevam@xxxxxxxxx>; > > > > Andriy > > > > Tryshnivskyy <andriy.tryshnivskyy@xxxxxxxxxxxxxxx>; Haibo Chen > > > > <haibo.chen@xxxxxxx>; Shawn Guo <shawnguo@xxxxxxxxxx>; Hans de > > > > Goede <hdegoede@xxxxxxxxxx>; Jerome Brunet > > > > <jbrunet@xxxxxxxxxxxx>; > > > > Heiko Stuebner <heiko@xxxxxxxxx>; Florian Boor > > > > <florian.boor@xxxxxxxxxxxxxxxxx>; Regus, Ciprian > > > > <Ciprian.Regus@xxxxxxxxxx>; Lars-Peter Clausen <lars@xxxxxxxxxx>; > > > > Andy > > > > Shevchenko <andy.shevchenko@xxxxxxxxx>; Jonathan Cameron > > > > <jic23@xxxxxxxxxx>; Neil Armstrong <narmstrong@xxxxxxxxxxxx>; > > > > Baolin > > > > Wang <baolin.wang@xxxxxxxxxxxxxxxxx>; Jyoti Bhayana > > > > <jbhayana@xxxxxxxxxx>; Chen-Yu Tsai <wens@xxxxxxxx>; Orson Zhai > > > > <orsonzhai@xxxxxxxxx> > > > > Subject: Re: [PATCH 13/15] iio: health: max30100: do not use > > > > internal iio_dev > > > > lock > > > > > > > > [External] > > > > > > > > Hi Nuno, > > > > > > > > Nuno.Sa@xxxxxxxxxx wrote on Tue, 20 Sep 2022 12:44:08 +0000: > > > > > > > > > > -----Original Message----- > > > > > > From: Miquel Raynal <miquel.raynal@xxxxxxxxxxx> > > > > > > Sent: Tuesday, September 20, 2022 2:23 PM > > > > > > To: Sa, Nuno <Nuno.Sa@xxxxxxxxxx> > > > > > > Cc: linux-arm-kernel@xxxxxxxxxxxxxxxxxxx; linux- > > > > rockchip@xxxxxxxxxxxxxxxxxxx; > > > > > > linux-amlogic@xxxxxxxxxxxxxxxxxxx; linux-imx@xxxxxxx; linux- > > > > > > iio@xxxxxxxxxxxxxxx; Chunyan Zhang <zhang.lyra@xxxxxxxxx>; > > > > Hennerich, > > > > > > Michael <Michael.Hennerich@xxxxxxxxxx>; Martin Blumenstingl > > > > > > <martin.blumenstingl@xxxxxxxxxxxxxx>; Sascha Hauer > > > > > > <s.hauer@xxxxxxxxxxxxxx>; Cixi Geng <cixi.geng1@xxxxxxxxxx>; > > > > > > Kevin > > > > > > Hilman <khilman@xxxxxxxxxxxx>; Vladimir Zapolskiy > > > > > > <vz@xxxxxxxxx>; > > > > > > Pengutronix Kernel Team <kernel@xxxxxxxxxxxxxx>; Alexandru > > > > Ardelean > > > > > > <aardelean@xxxxxxxxxxx>; Fabio Estevam <festevam@xxxxxxxxx>; > > > > Andriy > > > > > > Tryshnivskyy <andriy.tryshnivskyy@xxxxxxxxxxxxxxx>; Haibo > > > > > > Chen > > > > > > <haibo.chen@xxxxxxx>; Shawn Guo <shawnguo@xxxxxxxxxx>; Hans > > > > > > de > > > > > > Goede <hdegoede@xxxxxxxxxx>; Jerome Brunet > > > > <jbrunet@xxxxxxxxxxxx>; > > > > > > Heiko Stuebner <heiko@xxxxxxxxx>; Florian Boor > > > > > > <florian.boor@xxxxxxxxxxxxxxxxx>; Regus, Ciprian > > > > > > <Ciprian.Regus@xxxxxxxxxx>; Lars-Peter Clausen > > > > > > <lars@xxxxxxxxxx>; > > > > Andy > > > > > > Shevchenko <andy.shevchenko@xxxxxxxxx>; Jonathan Cameron > > > > > > <jic23@xxxxxxxxxx>; Neil Armstrong <narmstrong@xxxxxxxxxxxx>; > > > > > > Baolin > > > > > > Wang <baolin.wang@xxxxxxxxxxxxxxxxx>; Jyoti Bhayana > > > > > > <jbhayana@xxxxxxxxxx>; Chen-Yu Tsai <wens@xxxxxxxx>; Orson > > > > > > Zhai > > > > > > <orsonzhai@xxxxxxxxx> > > > > > > Subject: Re: [PATCH 13/15] iio: health: max30100: do not use > > > > > > internal > > > > iio_dev > > > > > > lock > > > > > > > > > > > > [External] > > > > > > > > > > > > Hi Nuno, > > > > > > > > > > > > > > > > Hi Miquel, > > > > > > > > > > Thanks for reviewing... > > > > > > > > > > > nuno.sa@xxxxxxxxxx wrote on Tue, 20 Sep 2022 13:28:19 +0200: > > > > > > > > > > > > > The pattern used in this device does not quite fit in the > > > > > > > iio_device_claim_direct_mode() typical usage. In this case, > > > > > > > iio_buffer_enabled() was being used not to prevent the raw > > > > > > > access but > > > > to > > > > > > > allow it. Hence to get rid of the 'mlock' we need to: > > > > > > > > > > > > > > 1. Use iio_device_claim_direct_mode() to check if direct > > > > > > > mode can be > > > > > > > claimed and if we can return -EINVAL (as the original > > > > > > > code); > > > > > > > > > > > > > > 2. Make sure that buffering is not disabled while doing a > > > > > > > raw read. For > > > > > > > that, we can make use of the local lock that already > > > > > > > exists. > > > > > > > > > > > > > > While at it, fixed a minor coding style complain... > > > > > > > > > > > > > > Signed-off-by: Nuno Sá <nuno.sa@xxxxxxxxxx> > > > > > > > --- > > > > > > > drivers/iio/health/max30100.c | 24 +++++++++++++++++------ > > > > > > > - > > > > > > > 1 file changed, 17 insertions(+), 7 deletions(-) > > > > > > > > > > > > > > diff --git a/drivers/iio/health/max30100.c > > > > b/drivers/iio/health/max30100.c > > > > > > > index ad5717965223..aa494cad5df0 100644 > > > > > > > --- a/drivers/iio/health/max30100.c > > > > > > > +++ b/drivers/iio/health/max30100.c > > > > > > > @@ -185,8 +185,19 @@ static int > > > > > > > max30100_buffer_postenable(struct > > > > > > iio_dev *indio_dev) > > > > > > > static int max30100_buffer_predisable(struct iio_dev > > > > > > > *indio_dev) > > > > > > > { > > > > > > > struct max30100_data *data = iio_priv(indio_dev); > > > > > > > + int ret; > > > > > > > + > > > > > > > + /* > > > > > > > + * As stated in the comment in the read_raw() > > > > > > > function, temperature > > > > > > > + * can only be acquired if the engine is running. > > > > > > > As such the mutex > > > > > > > + * is used to make sure we do not power down while > > > > > > > doing a > > > > > > temperature > > > > > > > + * reading. > > > > > > > + */ > > > > > > > + mutex_lock(&data->lock); > > > > > > > + ret = max30100_set_powermode(data, false); > > > > > > > + mutex_unlock(&data->lock); > > > > > > > > > > > > > > - return max30100_set_powermode(data, false); > > > > > > > + return ret; > > > > > > > } > > > > > > > > > > > > > > static const struct iio_buffer_setup_ops > > > > > > > max30100_buffer_setup_ops > > > > = { > > > > > > > @@ -387,18 +398,17 @@ static int max30100_read_raw(struct > > > > > > > iio_dev > > > > > > *indio_dev, > > > > > > > * Temperature reading can only be acquired > > > > > > > while engine > > > > > > > * is running > > > > > > > */ > > > > > > > - mutex_lock(&indio_dev->mlock); > > > > > > > - > > > > > > > - if (!iio_buffer_enabled(indio_dev)) > > > > > > > + if > > > > > > > (!iio_device_claim_direct_mode(indio_dev)) { > > > > > > > > > > > > I wonder if this line change here is really needed. I agree > > > > > > the whole > > > > > > construction looks like what iio_device_claim_direct_mode() > > > > > > does but in > > > > > > practice I don't see the point of acquiring any lock here if > > > > > > we just > > > > > > release it no matter what happens right after. > > > > > > > > > > > > > > > > I can see that this is odd (at the very least) but AFAIK, this > > > > > is the only way > > > > > to safely infer if buffering is enabled or not. > > > > > iio_buffer_enabled() has no > > > > > protection against someone concurrently enabling/disabling the > > > > > buffer. > > > > > > > > Yes, but this is only relevant if you want to infer that the > > > > "buffers > > > > are enabled" and be sure that it cannot be otherwise during the > > > > next > > > > lines until you release the lock. Acquiring a lock, doing the if > > > > and > > > > then unconditionally releasing the lock, IMHO, does not make any > > > > sense > > > > (but I'm not a locking guru) because when you enter the else > > > > clause, > > > > you are not protected anyway, so in both cases all this is > > > > completely > > > > racy. > > > > > > > > > > Ahh crap, yes you are right... It is still racy since we can still > > > try to read > > > the temperature with the device powered off. I'm not really sure > > > how to > > > address this. One way could be to just use an internal control > > > variable > > > to reflect the device power state (set/clear on the buffer > > > callbacks) and > > > only use the local lock (completely ditching the call to > > > iio_device_claim_direct_mode())... > > > > I tend to prefer this option than the one below. > > > > I guess your implementation already prevents buffer_predisable() to > > run > > thanks to the local lock being held during the operation. Maybe we > > should just verify that buffers are enabled from within the local > > lock > > being held instead of just acquiring it for the get_temp() measure. > > It > > would probably solve the situation here. > > > > Not sure if I understood... You mean something like: > > mutex_lock(&data->lock); > if (!iio_buffer_enabled(indio_dev)) { > ret = -EINVAL; > } else { > ret = max30100_get_temp(data, val); > if (!ret) > ret = IIO_VAL_INT; > > } > mutex_unlock(&data->lock); > > If so, I think this is still racy since we release the lock after the > predisable which means we could still detect the buffers as enabled (in > the above block) and try to get_temp on a powered down device. True. > > Since we pretty much only care about the power state of the device (and > we are using the buffering state to infer that AFAIU), I was thinking > in something like: > > > mutex_lock(&data->lock); > if (!data->powered) { > ret = -EINVAL; > } else { > ret = max30100_get_temp(data, val); > if (!ret) > ret = IIO_VAL_INT; > > } > mutex_unlock(&data->lock); LGTM. > > Then, in the predisable, something like I have but setting the flag to > false and the opposite on the postenable... Naturally we could also > just read the registers (and I actually tend to prefer it) instead of a > new flag but I guess the flag is enough in this case. > > - Nuno Sá > > Thanks, Miquèl