On Mon, Jan 9, 2023 at 10:29 AM Peter Zijlstra <peterz@xxxxxxxxxxxxx> wrote: > > I ran into a ton of casting trouble when compiling kernel/fork.c which > uses this_cpu_cmpxchg() on a pointer type and the compiler hates casting > pointers to an integer that is not the exact same size. Ahh. Yeah - not because that code needs or wants the 128-bit case, but because the macro expands to all sizes in a switch statement, so the compiler sees all the cases even if only one is then statically picked. So the silly casts are for all the cases that never matter. Annoying. I wonder if the "this_cpu_cmpxchg()" macro could be made to use _Generic() to pick out the pointer case first, and then only use 'sizeof()' for the integer types, so that we don't have this kind of "every architecture needs to deal with the nasty situation" code. Ok, it's not actually the this_cpu_cmpxchg() macro, it's __pcpu_size_call_return() and friends, but whatever. Another alternative is to try to avoid casting to "u64" as long as humanly possible, and use only "typeof((*ptr))" everywhere. Then when the type actually *is* 128-bit, it all works out fine, because it won't be a pointer. That's the approach the uaccess macros tend to take, and then they hit the reverse issue on clang, where using the "byte register" constraints would cause warnings for non-byte accesses, and we had to do unsigned char x_u8__; __get_user_asm(x_u8__, ptr, "b", "=q", label); (x) = x_u8__; because using '(x)' directly would then warn when 'x' wasn't a char-sized thing - even if that asm case never actually was _used_ for that case, since it was all inside a "switch (sizeof) case 1:" statement. Linus