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. Please explain.