RE: [RFC PATCH 1/4] iio: core: Introduce iio_push_to_buffers_with_ts_na() for non aligned case.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




> -----Original Message-----
> From: Sa, Nuno <Nuno.Sa@xxxxxxxxxx>
> Sent: Monday, May 3, 2021 9:15 AM
> To: Jonathan Cameron <jic23@xxxxxxxxxx>
> Cc: linux-iio@xxxxxxxxxxxxxxx; Jonathan Cameron
> <Jonathan.Cameron@xxxxxxxxxx>
> Subject: RE: [RFC PATCH 1/4] iio: core: Introduce
> iio_push_to_buffers_with_ts_na() for non aligned case.
> 
> 
> 
> 
> > -----Original Message-----
> > From: Jonathan Cameron <jic23@xxxxxxxxxx>
> > Sent: Sunday, May 2, 2021 6:09 PM
> > To: Sa, Nuno <Nuno.Sa@xxxxxxxxxx>
> > Cc: linux-iio@xxxxxxxxxxxxxxx; Jonathan Cameron
> > <Jonathan.Cameron@xxxxxxxxxx>
> > Subject: Re: [RFC PATCH 1/4] iio: core: Introduce
> > iio_push_to_buffers_with_ts_na() for non aligned case.
> >
> >
> > On Sun, 2 May 2021 09:10:56 +0000
> > "Sa, Nuno" <Nuno.Sa@xxxxxxxxxx> wrote:
> >
> > > > From: Jonathan Cameron <jic23@xxxxxxxxxx>
> > > > Sent: Saturday, May 1, 2021 7:25 PM
> > > > To: linux-iio@xxxxxxxxxxxxxxx
> > > > Cc: Jonathan Cameron <Jonathan.Cameron@xxxxxxxxxx>
> > > > Subject: [RFC PATCH 1/4] iio: core: Introduce
> > > > iio_push_to_buffers_with_ts_na() for non aligned case.
> > > >
> > > > From: Jonathan Cameron <Jonathan.Cameron@xxxxxxxxxx>
> > > >
> > > > Whilst it is almost always possible to arrange for scan data to be
> > > > read directly into a buffer that is suitable for passing to
> > > > iio_push_to_buffers_with_timestamp(), there are a few places
> > where
> > > > leading data needs to be skipped over.
> > > >
> > > > For these cases introduce a function that will allocate an
> > appropriate
> > > > sized and aligned bounce buffer (if not already allocated) and
> copy
> > > > the unaligned data into that before calling
> > > > iio_push_to_buffers_with_timestamp() on the bounce buffer.
> > > > We tie the lifespace of this buffer to that of the iio_dev.dev
> > > > which should ensure no memory leaks occur.
> > > >
> > > > Signed-off-by: Jonathan Cameron
> > <Jonathan.Cameron@xxxxxxxxxx>
> > > > ---
> > > >  drivers/iio/industrialio-buffer.c | 36
> > > > +++++++++++++++++++++++++++++++
> > > >  include/linux/iio/buffer.h        |  4 ++++
> > > >  include/linux/iio/iio-opaque.h    |  4 ++++
> > > >  3 files changed, 44 insertions(+)
> > > >
> > > > diff --git a/drivers/iio/industrialio-buffer.c
> > b/drivers/iio/industrialio-
> > > > buffer.c
> > > > index 9a8e16c7e9af..818dfaa73665 100644
> > > > --- a/drivers/iio/industrialio-buffer.c
> > > > +++ b/drivers/iio/industrialio-buffer.c
> > > > @@ -1727,6 +1727,42 @@ int iio_push_to_buffers(struct iio_dev
> > > > *indio_dev, const void *data)
> > > >  }
> > > >  EXPORT_SYMBOL_GPL(iio_push_to_buffers);
> > > >
> > > > +/**
> > > > + * iio_push_to_buffers_with_ts_na() - push to registered
> buffer,
> > > > + *    no alignment or space requirements.
> > > > + * @indio_dev:		iio_dev structure for device.
> > > > + * @data:		channel data excluding the timestamp.
> > > > + * @data_sz:		size of data.
> > > > + * @timestamp:		timestamp for the sample data.
> > > > + *
> > > > + * This special variant of iio_push_to_buffers_with_timetamp()
> > does
> > > > + * not require space for the timestamp, or 8 byte alignment of
> > data.
> > > > + * It does however require an allocation on first call and
> additional
> > > > + * coppies on all calls, so should be avoided if possible
> > > > + */
> > > > +int iio_push_to_buffers_with_ts_na(struct iio_dev *indio_dev,
> > > > +				   const void *data,
> > > > +				   size_t data_sz,
> > > > +				   int64_t timestamp)
> > > > +{
> > > > +	struct iio_dev_opaque *iio_dev_opaque =
> > > > to_iio_dev_opaque(indio_dev);
> > > > +
> > > > +	data_sz = min_t(size_t, indio_dev->scan_bytes, data_sz);
> > > I'm not really sure  about this. Is it really a good idea to silently
> > truncate
> > > the data if some erroneous driver calls this with data_sz >
> > scan_bytes?
> > > (I don't think it's ever valid for data_sz to be bigger than
> scan_bytes)
> >
> > It's not probably not.  This is just a fairly nasty way of papering over
> > anyone doing that.
> >
> > > We might be discarding data that userland actually requested. So,
> I'm
> > > not sure if it would not be better to be strict here and return error,
> > so that
> > > driver developers could catch this early on...
> >
> > I'm fairly sure we'll never be discarding data userspace requested
> > because scan_bytes will be the maximum possible and is the size of
> > the
> > kfifo element.  Any more data that comes in is going to be dropped
> > anyway
> > assuming it ends up in a kfifo_put()
> 
> I think it depends. Think on a totally erroneous driver that does not
> track
> enabled elements and just pushes all elements to IIO buffers. If
> userspace
> just requested, let's say, the last 2 elements, I believe those would be
> definitely discarded by this... More subtle things could also happen I
> guess...
> In this case, we can arguably say that the driver is completely broken
> and while
> I'm fairly sure such a scenario would never pass through revision, I
> think that
> if we make things more strict, we might minimize the chances of such
> patches
> to appear in the first place (unless someone is sending patches without
> testing them at all).
> 
> > I wondered if we wanted to enforce this?  It would not seem totally
> > silly for a driver that wasn't bothering to track the size of it's enabled
> > channels to provide data_sz == maximum size it ever needs.
> > Docs should definitely say if that's valid however, and it's definitely
> less
> > than optimal because we may copy garbage that will then be
> > overwritten by
> > the timestamp.
> >
> > >
> > > data_sz < scan_bytes is also probably not valid as that might
> happen
> > > if some drivers call this without the scan elements properly aligned
> > > which will definitely be problematic... Naturally in this case we
> would
> > > have to take into account timestamp possible alignment fill bytes as
> it
> > > could be possible (and likely) that data_sz won't include those
> bits...
> >
> > data_sz < scan_bytes is intentionally valid (and indeed I made one
> > of the drivers do this).  Given we are bouncing anyway, why insist
> the
> > driver provides space for padding + timestamp?  That can be done
> for
> > the bounce buffer.
> 
> What I meant was that if data_sz < scan_bytes - timestamp - padding,
> then
> the driver is most likely not guaranteeing properly aligned elements. I
> was
> not that clear :)
> 
> Anyways, I still feel that if we are taking the data_sz parameter on the
> API,
> we should handle it more strictly. But I do not feel too strong about
> this (as
> you said, It's not expected to exist too much users of this) and in the
> end
> of the day it still behaves the same way as
> 'iio_push_to_buffers_with_timestamp()'...
> 
> > >
> > > Alternatively, we could be consistent with
> > 'iio_push_to_buffers_with_timestamp()'
> > > and assume drivers play along in terms of alignment and size
> > > (so, removing the data_sz parameter)...
> > >
> > > My point is, if we are taking the data_sz parameter, maybe we
> > should be pedantic
> > > about it...
> > > > +	if (iio_dev_opaque->bounce_buffer_size !=  indio_dev-
> > > > >scan_bytes) {
> > >
> > > Where do we set ' bounce_buffer_size '? I guess we do not want
> to
> > > get  here all the time...
> >
> > :( oops
> >
> > > > +		iio_dev_opaque->bounce_buffer =
> > > > +			devm_krealloc(&indio_dev->dev,
> > > > +				      iio_dev_opaque->bounce_buffer,
> > > > +				      indio_dev->scan_bytes,
> > > > GFP_KERNEL);
> > >
> > > I'm also not a big fan of realloc so I prefer to avoid it unless really
> > needed...
> > > Here, maybe we could just allocate this once during device/buffer
> > initialization
> > > and allocate it for the maximum possible size, i.e all scan elements
> > enabled...
> >
> > We can but to do that requires more invasive changes. Perhaps not
> > horrible ones,
> > but we'd need to add stuff to caller drivers to configure the bounce
> > buffer, or
> > some flag to see they needed to enable support for this.  Only 3
> > drivers out of
> > all those in IIO are currently using this code (might be a few others
> that
> > could
> > take advantage but not many - so need to keep it localized).
> 
> I was not thinking that way. I was just thinking in always allocating the
> bounce
> buffer. But I do agree that it is less than ideal to allocate something
> that will
> almost never be used...
> 
> > I suppose we could have an
> > iio_unaligned_push_to_buffers_prepare() to be called from the
> > update_scan_mode()
> > callback (typed to be useable as that callback if nothing else to be
> done
> > in
> > the relevant drivers.
> 
> It could also be an option... If we want to not use realloc, we would
> have to manually
> control the lifespan of the buffer and free it in the disable path. But I
> guess that might feel
> like too much handling...
> 
> Anyways, maybe sticking with realloc, we could just use a more normal
> pattern like:
> 
> tmp = devm_realloc(bounce_fuffer, ...);
> if (!tmp)
>     error;
> 
> bounce_buffer = tmp;
> 

I just read your reply to Andy about this and I think you are right... If the
new allocation fails, the older pointer is still preserved. However, I find
the above form a bit more readable and straight :)

- Nuno Sá




[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Input]     [Linux Kernel]     [Linux SCSI]     [X.org]

  Powered by Linux