User: Password:
|
|
Subscribe / Log in / New account

Fixing the unfixable autofs ABI

Fixing the unfixable autofs ABI

Posted May 3, 2012 15:12 UTC (Thu) by jzbiciak (subscriber, #5246)
In reply to: Fixing the unfixable autofs ABI by stevem
Parent article: Fixing the unfixable autofs ABI

The twist here is that the i386 ABI only requires 4-byte alignment for 64-bit types, which is why the structure size differs. Since i386 only supported accesses up to 32 bits, this seemed "natural" at the time.

So, what do you define as natural alignment?


(Log in to post comments)

Fixing the unfixable autofs ABI

Posted May 3, 2012 15:28 UTC (Thu) by stevem (subscriber, #1512) [Link]

I've always tried to arrange structs in decreasing order of size to do that:

64-bit types
32-bit types
16
8

and it's worked for me. It *might* not be the best layout for caching performance, but for API structures like ioctls I think it's a clean way to go.

Alternatively, add explicit padding in the structures to make them alignment-neutral. Much less clean, but better than having differently-sized structs depending on architecture.

Fixing the unfixable autofs ABI

Posted May 3, 2012 15:41 UTC (Thu) by jzbiciak (subscriber, #5246) [Link]

That doesn't fix this structure, as I understand it. The total size of the elements is 300 bytes, but the whole struct must be aligned to 8 bytes on 64 byte architectures, but only needs alignment 4 on the i386 ABI.

Consider this much simpler structure:

struct broken
{
    __u64 f1;
    __u32 f2;
};

On the i386 ABI, sizeof(struct broken) is 12. On the x86-64 ABI, it's 16.

Fixing the unfixable autofs ABI

Posted May 3, 2012 15:50 UTC (Thu) by stevem (subscriber, #1512) [Link]

Ah, yes. :-(

Fixing the unfixable autofs ABI

Posted May 3, 2012 18:46 UTC (Thu) by nybble41 (subscriber, #55106) [Link]

Yes, but if you add padding fields you can ensure the same alignment on all reasonable architectures:

struct fixed
{
    __u64 f1;
    __u32 f2;
    __u32 pad1;
};

This way sizeof(struct fixed) is 16 bytes on i386 and x86-64. Of course, that doesn't help with the structure from this article, because the smaller i386 alignment was written into the ABI. IMHO, any structures exposed through the ABI should be naturally aligned and marked as "packed", with explicit padding fields where necessary; alignment should not be left to the compiler where ABI compatibility is a concern.

Fixing the unfixable autofs ABI

Posted May 3, 2012 19:10 UTC (Thu) by jzbiciak (subscriber, #5246) [Link]

That would generally be the best idea, but as you stated, it doesn't fix this structure, because the i386 ABI doesn't require natural alignment for 64-bit types, as per the definition you gave in your other comment. The reason I asked is that i386's ABI is perverse in requiring natural alignment for some, but not all data types. So, I wasn't sure if the concept of "natural" had different meaning in the context of i386's ABI.

IMHO, any structures exposed through the ABI should be naturally aligned and marked as "packed", with explicit padding fields where necessary; alignment should not be left to the compiler where ABI compatibility is a concern.

I tend to agree, and do this myself when I care about the actual layout of a struct. Ok, I usually forego 'packed' since it isn't portable. I instead make the struct a multiple of the largest data type, and force fields onto natural boundaries for their types.

This practice is especially necessary when you have any "wire formats" or "on disk format." You can almost think of packets crossing the kernel/user-space boundary as having "wire format" semantics in this case, with the minor difference that pointers are more meaningful in user-space exchanges than they usually are over, say, a TCP link.

Fixing the unfixable autofs ABI

Posted May 3, 2012 18:30 UTC (Thu) by nybble41 (subscriber, #55106) [Link]

> So, what do you define as natural alignment?

"Natural alignment" is a term of art meaning that the address (or in this case, offset) of the data is a multiple of its size. It can be used independently of the target, and for any size, though it's usually applied to powers of two. For example, on most platforms with multiple page sizes, pages must be naturally aligned; you can't construct a 1MB hugepage from an arbitrary span of 256 4kB pages, but instead have to use a region aligned to a multiple of 1MB.

In this case it would mean aligning 64-bit fields to an offset which is a multiple of eight bytes, even on i386 where only 32-bit alignment is required.


Copyright © 2017, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds