From: Lorenzo Bianconi <lorenzo@kernel.org>
To: Silvano Seva <s.seva@4sigma.it>
Cc: a.greco@4sigma.it, Jonathan Cameron <jic23@kernel.org>,
Lars-Peter Clausen <lars@metafoo.de>,
"open list:ST LSM6DSx IMU IIO DRIVER" <linux-iio@vger.kernel.org>,
open list <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] iio: imu: st_lsm6dsx: fix possible lockup during FIFO read
Date: Fri, 7 Mar 2025 15:40:52 +0100 [thread overview]
Message-ID: <Z8sFdGG4bDyALrsi@lore-desk> (raw)
In-Reply-To: <CALKJsrqc__ZeLoZ5V+hBxVMU+Crpv_YG0KM69N1CXuHc_rM-FQ@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 4045 bytes --]
> On Thu, Mar 6, 2025 at 4:48 PM Lorenzo Bianconi <lorenzo@kernel.org> wrote:
> >
> > > Prevent st_lsm6dsx_read_fifo and st_lsm6dsx_read_tagged_fifo functions
> > > from falling in an infinite loop in case pattern_len is equal to zero and
> > > the device FIFO is not empty.
> > >
> > > Signed-off-by: Silvano Seva <s.seva@4sigma.it>
> > > ---
> > > drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | 8 ++++++++
> > > 1 file changed, 8 insertions(+)
> > >
> > > diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
> > > index 0a7cd8c1aa33..7f343614f8a5 100644
> > > --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
> > > +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
> > > @@ -395,12 +395,17 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)
> > > fifo_len = (le16_to_cpu(fifo_status) & fifo_diff_mask) *
> > > ST_LSM6DSX_CHAN_SIZE;
> > > fifo_len = (fifo_len / pattern_len) * pattern_len;
> > > + if (!fifo_len)
> > > + return 0;
> >
> > I do not think this check is necessary since if fifo_len is 0 we will not run
> > the for loop, right?
>
> This check is present in the st_lsm6dsx_read_tagged_fifo() function, i
> added it here for consistency. I agree with you that is not strictly
> necessary.
>
> >
> > >
> > > acc_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]);
> > > gyro_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_GYRO]);
> > > if (hw->iio_devs[ST_LSM6DSX_ID_EXT0])
> > > ext_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_EXT0]);
> > >
> > > + if (!pattern_len)
> > > + pattern_len = ST_LSM6DSX_SAMPLE_SIZE;
> >
> > same here, I do not think pattern_len can be 0 since hw->sip must be greater
> > than 0 in order to enable the FIFO. Moreover, this check should be some lines
> > above since we have already divided fifo_len by pattern_len here.
> >
>
> There is a situation causing the subsequent for loop to never
> terminate, hanging the kernel boot process: given a system which
> doesn't have an hardware reset line allowing the kernel to
> re-initialize the IMU hardware, in case of an hot reboot the driver
> probe() function attempts to flush the FIFO, which may contain some
> data, while the hw->sip is zero.
> The complete execution path is the following:
> - call of st_lsm6dsx_probe();
> - allocation of the st_lsm6dsx_hw structure via the devm_kzalloc,
> zero-initializing the sip field;
> - call of st_lsm6dsx_init_device();
> - call of st_lsm6dsx_reset_device();
> - call of st_lsm6dsx_flush_fifo();
> - call of st_lsm6dsx_read_fifo/st_lsm6dsx_read_tagged_fifo via the
> fifo_ops function pointer.
ack, I can see the issue now, thx for pointing this out. I should we should set
pattern_len to ST_LSM6DSX_SAMPLE_SIZE or ST_LSM6DSX_TAGGED_SAMPLE_SIZE if it is
0. Can you please move the check before updating fifo_len in
st_lsm6dsx_read_fifo()?
Regards,
Lorenzo
>
> An alternative solution to solve this situation is initializing the
> hw->sip field to a sane default value in either the probe() or
> init_device() function.
>
> > > +
> > > for (read_len = 0; read_len < fifo_len; read_len += pattern_len) {
> > > err = st_lsm6dsx_read_block(hw, ST_LSM6DSX_REG_FIFO_OUTL_ADDR,
> > > hw->buff, pattern_len,
> > > @@ -623,6 +628,9 @@ int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw)
> > > if (!fifo_len)
> > > return 0;
> > >
> > > + if (!pattern_len)
> > > + pattern_len = ST_LSM6DSX_TAGGED_SAMPLE_SIZE;
> >
> > for the reason above, this is not necessary.
> >
> > Regards,
> > Lorenzo
> >
> > > +
> > > for (read_len = 0; read_len < fifo_len; read_len += pattern_len) {
> > > err = st_lsm6dsx_read_block(hw,
> > > ST_LSM6DSX_REG_FIFO_OUT_TAG_ADDR,
> > > --
> > > 2.48.1
> > >
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
next prev parent reply other threads:[~2025-03-07 14:40 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-03-03 13:21 [PATCH] iio: imu: st_lsm6dsx: fix possible lockup during FIFO read Silvano Seva
2025-03-06 15:48 ` Lorenzo Bianconi
2025-03-07 9:20 ` Silvano Seva
2025-03-07 14:40 ` Lorenzo Bianconi [this message]
2025-03-10 13:22 ` Silvano Seva
2025-03-10 13:29 ` Silvano Seva
-- strict thread matches above, loose matches on Subject: below --
2025-03-10 13:36 Lorenzo Bianconi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Z8sFdGG4bDyALrsi@lore-desk \
--to=lorenzo@kernel.org \
--cc=a.greco@4sigma.it \
--cc=jic23@kernel.org \
--cc=lars@metafoo.de \
--cc=linux-iio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=s.seva@4sigma.it \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.