Re: [1/2] i2c: ismt: 16-byte align the DMA buffer address

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

 



On Thu, 2018-01-04 at 20:47 -0500, Neil Horman wrote:
> On Thu, Jan 04, 2018 at 05:01:16PM +0000, Radu Rendec wrote:
> > On Thu, 2018-01-04 at 11:22 -0500, Neil Horman wrote:
> > > On Thu, Jan 04, 2018 at 03:42:09PM +0000, Radu Rendec wrote:
> > > > I believe the aligned() attribute cannot be used here because the whole
> > > > ismt_priv structure is dynamically allocated (the allocation is done at
> > > > the beginning of the ismt_probe() function).
> > > > 
> > > > Even with a statically allocated structure, aligning the whole
> > > > structure does not guarantee the alignment of the dma_buffer field,
> > > > because the field offset within the structure can change (e.g. if other
> > > > fields are added, removed, moved around etc.).
> > > 
> > > For reference, you can do it like this:
> > > 
> > > #include <stdlib.h>
> > > #include <stdio.h>
> > > 
> > > 
> > > struct buffer_type { char b[3]; };
> > > struct ubuffer_type { char b[3]; } __attribute__((aligned(16)));
> > > 
> > > struct s1 {
> > >         char foo;
> > >         struct buffer_type bar;
> > > };
> > > 
> > > struct s2 {
> > >         char foo;
> > >         struct ubuffer_type bar;
> > > };
> > > 
> > > int main(int argc, char **argv)
> > > {
> > >         struct s1 *p1;
> > >         struct s2 *p2;
> > > 
> > >         p1 = malloc(sizeof(struct s1));
> > >         p2 = malloc(sizeof(struct s2));
> > > 
> > >         printf("addr of p1->bar = %p\n", &p1->bar);
> > >         printf("addr of p2->bar = %p\n", &p2->bar);
> > > 
> > >         free(p1);
> > >         free(p2);
> > > 
> > >         return 0;
> > > }
> > 
> > Hmm... I just tried this on my workstation (x86, 32bit):
> > 
> > [rrendec@rrendec ~]$ gcc -o align align.c
> > [rrendec@rrendec ~]$ ./align 
> > addr of p1->bar = 0x9358009
> > addr of p2->bar = 0x9358028
> > [rrendec@rrendec ~]$ ./align 
> > addr of p1->bar = 0x856b009
> > addr of p2->bar = 0x856b028
> > 
> > The most significant 4 digits are always different (probably due to
> > address randomization), but the least significant 3 are consistently
> > 0x009 and 0x028, neither of which is 16 byte aligned.
> > 
> > But I think this is normal, because malloc() gets just a size parameter
> > and has no knowledge of the intended data type of the memory area that
> > it allocates. It's probably the same with kmalloc() and friends.
> > 
> 
> Yeah, I was under the impression that malloc provided memory in blocks aligned
> to a maximum arch specific alignment, and then gcc could just pad the struct
> size to guarantee a more granular alignment, but on doing some more reading,
> alignment support only applies to bss and data storage, at least for the gcc
> linker.  PTR_ALIGN is the way to go here.
> 
> > > Though as I look at that, you're probably right, using PTR_ALIGN would probably
> > > be prettier.  I'd be ok with that approach
> > 

Glad that we sorted this out.

> > That's great. I'll prepare an updated patch with PTR_ALIGN and post it
> > shortly.
> > 
> 
> Thanks!

I sent the updated patch with PTR_ALIGN on Jan/4. Have you had a chance
to look at it? Is there anything that can be further improved?

Thanks,
Radu




[Index of Archives]     [Linux GPIO]     [Linux SPI]     [Linux Hardward Monitoring]     [LM Sensors]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux