Re: [PATCH 19/25] iio:adc:ti-ads1015 Fix buffer element alignment

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

 



On Tue, May 26, 2020 at 05:43:28PM +0100, Jonathan Cameron wrote:
> On Tue, 26 May 2020 12:15:56 +0300
> Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx> wrote:
> > On Tue, May 26, 2020 at 10:11:44AM +0200, Lars-Peter Clausen wrote:
> > > On 5/25/20 7:52 PM, Andy Shevchenko wrote:  
> > > > On Mon, May 25, 2020 at 06:06:22PM +0100, Jonathan Cameron wrote:  
> > > > > From: Jonathan Cameron <Jonathan.Cameron@xxxxxxxxxx>  

...

> > > > > +	struct {
> > > > > +		s16 channel;
> > > > > +		s64 ts;
> > > > > +	} scan;  
> > > > Hmm... On x86_32 and x86_64 this will give different padding. Is it okay from
> > > > iio_push_to_buffers_with_timestamp() point of view?  
> > > 
> > > No, this is terrible. IIO expects 64 bit words to be 64 bit aligned. Looks
> > > like we can't rely on implicit padding, but need to always explicitly
> > > specify it.
> > > 
> > > Or maybe we can typedef and IIO timestamp type with an explicit __aligned
> > > attribute. I wonder if that works... After having a quick look, the kernel
> > > already defines aligned_u64, so maybe using that is an option.  
> > 
> > Another way is simple to provide offset of timestamp member as a parameter.
> > Though, if it's an ABI, then alas, we need to align it properly.
> > 
> > Also, wouldn't be better to explicitly show the padding?
> > 
> > 	struct {
> > 		s16 channel;
> > 		s16 padding[3];
> > 		s64 ts;
> > 	} scan;
> > 
> > (matter of style though, just saying).
> > 
> 
> gah.  Thanks for pointing this out Andy.  I wanted to avoid explicitly
> calling out empty padding because it seemed to me to be more likely to
> be error prone than filling it in.
> 
> I was trying to avoid using __aligned on the stack as it only works for
> more recent kernels (due to gcc version changes) and some of these predate
> that point.
> 
> I guess we just do it explicitly in all these cases.
> 
> The two patches that have already gone to Greg both have sufficient
> data to ensure the structure is big enough (only 16 bytes padding in one and
> none in the other).
> 
> I think we are also fine for the original question as well as it won't
> matter if the whole structure is aligned to 4 bytes on x86_32 and
> similar as an 8 byte write will be fine.
> 
> So fun question - do we want to enforce 8 byte alignment of the whole
> structure, or simply the padding?
> 
> Maybe better to just do the padding explicitly as Andy suggested.

I have talked to colleague of mine, and we concluded (but without any
documentation proved evidence, one needs basically to read C standard followed
by ABI of all architectures supported by Linux) that the following will work.

Consider your patch, which introduces natural alignment via struct:

	struct scan {
		s16 ...;
		...
		s64 ts;
	};

When we access ts as struct member like scan->ts, compiler makes sure that
there will be no hardware exception (due to unaligned access). Now, we _assume_
that dereferencing like

	void *buf = &scan;
	(int64_t *)buf[ts_offset] = value;

will work flawlessly because above.

If it's indeed a case, what we simple need is to pass ts offset into
iio_push_to_buffers_with_timestamp().

If it's not the case, we _additionally_ will need to replace
	(int64_t *)buf[ts_offset] = value;
by
	put_unaligned(value, (int64_t *)...);

-- 
With Best Regards,
Andy Shevchenko





[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