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 Wed, May 27, 2020 at 12:41:07PM +0100, Jonathan Cameron wrote:
> On Wed, 27 May 2020 00:03:13 +0300
> Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx> wrote:
> > On Tue, May 26, 2020 at 08:17:11PM +0100, Jonathan Cameron wrote:
> > > On 26 May 2020 18:06:12 BST, Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx> wrote:  

> > > Might be easier to just align it though than explain this subtlety.   
> > 
> > The easiest one seems to move ts to be first member of the struct / buffer. Problem solved.
> 
> Sort of, but it brings other problems.
> 
> 1) Breaks userspace ABI.  Yes, no one should be relying on the ordering of
>    elements from a given sensor, but we all know someone will be.   As
>    things currently stand note we only have one actual report of there
>    being a case where the alignment stuff breaks down (before I broke it
>    much more significantly with this patch set!)
> 
> 2) We have to rework all the drivers, including the majority that use a suitably
>    aligned buffer anyway (typically ____cacheline_aligned for DMA safety).
>    The structure thing doesn't work any more because the timestamp is optional,
>    so we have to have the drivers do their alignment differently depending on whether
>    it is there or not, so we are back to use using __aligned(8) for all the buffers. 
>    At the end of the day, the iio_push_to_buffers_with_timestamp is only workable
>    because the timestamp is at the end of the buffer.

I see.

> At this point I'm thinking we just stick to u8, u16 etc arrays.  At that point
> we either decide that we are happy to not backport past (IIRC) 4.19 where the minimum gcc
> version was increased such that __aligned(8) works on the stack, or we move them into
> the iio_priv() structure where __aligned(8) always worked and hence squash the issue
> of kernel data leaking without a memset on each scan. The only remaining question is
> whether we get extra clarity by using
> 
> struct {
> 	s16 channels[2];
> 	// I think we can actually drop the padding if marking the timestamp as
> 	// __aligned(8)
> 	u8 padding[4];
> 	s64 timestamp __aligned(8);
> } scan;
> 
> or 
> 
> s16 scan[8] __aligned(8);
> 
> 
> For the __aligned part this from the gcc docs looks helpful:
> 
> https://gcc.gnu.org/onlinedocs/gcc-4.6.4/gcc/Type-Attributes.html
> 
> "Note that the alignment of any given struct or union type is
> required by the ISO C standard to be at least a perfect multiple
> of the lowest common multiple of the alignments of all of the
> members of the struct or union in question. This means that you
> can effectively adjust the alignment of a struct or union type by
> attaching an aligned attribute to any one of the members of such a
> type, but the notation illustrated in the example above is a more
> obvious, intuitive, and readable way to request the compiler to
> adjust the alignment of an entire struct or union type. "

This means that

struct sx {
	u8 channel;
	s64 ts;
};

struct sx y, *py = &y;

py will be always aligned to at least 8 bytes (per s64 type).
It has no effect on the members themselves.

> So I think that means we can safely do
> 
> struct {
> 	u8 channel;
> 	s64 ts __aligned(8);
> };

I don't know how this attribute will affect *a member* of the struct. Perhaps
it's straightforward and GCC simple apply it to POD.

> and be guaranteed correct padding and alignment in what I think is
> a fairly readable form.  It's also self documenting so I can
> probably drop some of the explanatory comments.

If it is documented, then I fully agree, otherwise will look
like a (fragile) hack.

-- 
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