On Thu, Nov 23, 2017 at 10:31:29PM -0800, Alexei Starovoitov wrote:
unfortunately 32-bit is more screwed than it seems:
$ cat align.c
#include <stdio.h>
struct S {
unsigned long long a;
} s;
struct U {
unsigned long long a;
} u;
int main()
{
printf("%d, %d\n", sizeof(unsigned long long),
__alignof__(unsigned long long));
printf("%d, %d\n", sizeof(s), __alignof__(s));
printf("%d, %d\n", sizeof(u), __alignof__(u));
}
$ gcc -m32 align.c
$ ./a.out
8, 8
8, 4
8, 4
*blink* how is that even correct? I understood the spec to say the
alignment of composite types should be the max alignment of any of its
member types (otherwise it cannot guarantee the alignment of its
members).
so we have to use __aligned_u64 in uapi.
Ideally yes, but effectively it most often doesn't matter.
Otherwise, yes, we could have used config1 and config2 to pass pointers
to the kernel, but since they're defined as __u64 already we cannot
change them and have to do this ugly dance around 'config' field.
I don't understand the reasoning why you cannot use them. Even if they
are not naturally aligned on x86_32, why would it matter?
x86_32 needs two loads in any case, but there is no concurrency, so
split loads is not a problem. Add to that that 'intptr_t' on ILP32
is in fact only a single u32 and thus the other u32 will always be 0.
So yes, alignment is screwy, but I really don't see who cares and why it
would matter in practise.