[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20120322224429.GA12980@obsidianresearch.com>
Date: Thu, 22 Mar 2012 16:44:29 -0600
From: Jason Gunthorpe <jgunthorpe@...idianresearch.com>
To: Parav.Pandit@...lex.Com
Cc: David.Laight@...LAB.COM, roland@...estorage.com,
linux-rdma@...r.kernel.org, netdev@...r.kernel.org
Subject: Re: [PATCH 2/9] ocrdma: Driver for Emulex OneConnect RDMA adapter
On Thu, Mar 22, 2012 at 02:20:28PM -0700, Parav.Pandit@...lex.Com wrote:
> I got a question here lately.
>
> aligned directive will ensure that it will fall on boundary. Say
> aligned(4) ensures that structure is aligned to 4 byte boundary.
> Compiler can (at least theoretically) still have 4 byte structure
> aligned to 8 byte boundary on 64-bit platform (which is 4 byte
> aligned too).
There are very specific rules defined in the platform's ABI for how C
structures are layed out in memory, each ABI (ie CPU) has its own
specific quirks, but broadly in Linux land you can boil it down to:
1) The alignment of a structure is the greatest alignment of all the
members
2) Each member is aligned to its alignment.
The alignment of the structure drives the total size of the structure,
and specifically the padding added at the end to reach that alignment.
So, no, a compiler that increased the alignment of a struct with one
u32 to 8 would violate the various ABIs and not be usuable for
Linux. It is important to bear in mind that Linux targets a particular
set of ABI conventions, and it is not 'anything goes'.
> struct {
> u32 field;
> };
So in this case: the u32 is aligned to 4, the structure is aligned to
4 and the total size of the structure is 4 on everything linux
supports.
> struct {
> u64 fielda
> u32 field;
> };
In this case: On 64 bit: the u64 is aligned to 8 and the u32 is aligned to 4. So
the structure is aligned to 8. A pad is inserted at the end of the
struct to bring it out. On 32 bit, the u64 is aligned to 4, so the
struct is aligned to 4, so no pad is added.
> struct {
> __float128 fielda
> u32 field;
> };
In this case the float128 is aligned to 16 and thus the structure is
aligned to 16 and 12 pad bytes are added.
> However requirement is to have this structure only 4 byte size(
> because adapter excepts it to be 4B sise) and therefor packed is
> used. I don't know the way to ensure size of 4 byte and alignment
> too. Or I am misunderstanding?
Yes, you are mis-understanding the rules for padding.. Structures are
only padded out to their alignment, which depends on their constituent
types. This is so arrays of structures have each array element
starting on its natural alignment.
The aligned attribute overrides the automatic determination of the
alignment based on the contents and just forces it.
So, as an example, if you have this hardware layout:
struct {
u32 fielda;
u64 fieldb;
} attribute ((aligned(4));
David is saying you will get a 12 byte struct and fieldb will be
unaligned. Since 12 is aligned to 4 no padding is added.
For hardware facing structures I'd combine this with a static assert
to verify structure size at compile time.
So..
1) Avoid using attributes unless the structure has unaligned members.
2) Avoid creating structures with unaligned members (eg for userspace
communication)
3) Frown at hardware/firmware developers who make communication
structures with unaligned members :)
4) Be explicit about padding in your layout for 64/32
compatibility.
Jason
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists