Hi Arnd, On Sat, May 8, 2021 at 12:12 AM Arnd Bergmann <arnd@xxxxxxxxxx> wrote: > The get_unaligned()/put_unaligned() implementations are much more complex > than necessary, now that all architectures use the same code. > > Move everything into one file and use a much more compact way to express > the same logic. > > I've compared the binary output using gcc-11 across defconfig builds for > all architectures and found this patch to make no difference, except for > a single function on powerpc that needs two additional register moves > because of random differences in register allocation. > > There are a handful of callers of the low-level __get_unaligned_cpu32, > so leave that in place for the time being even though the common code > no longer uses it. > > This adds a warning for any caller of get_unaligned()/put_unaligned() > that passes in a single-byte pointer, but I've sent patches for all > instances that show up in x86 and randconfig builds. It would be nice > to change the arguments of the endian-specific accessors to take the > matching __be16/__be32/__be64/__le16/__le32/__le64 arguments instead of > a void pointer, but that requires more changes to the rest of the kernel. > > Signed-off-by: Arnd Bergmann <arnd@xxxxxxxx> Thanks for your patch! > @@ -6,20 +6,132 @@ > * This is the most generic implementation of unaligned accesses > * and should work almost anywhere. > */ > +#include <linux/unaligned/packed_struct.h> > #include <asm/byteorder.h> > > -#if defined(__LITTLE_ENDIAN) > -# include <linux/unaligned/le_struct.h> > -# include <linux/unaligned/generic.h> > -# define get_unaligned __get_unaligned_le > -# define put_unaligned __put_unaligned_le > -#elif defined(__BIG_ENDIAN) > -# include <linux/unaligned/be_struct.h> > -# include <linux/unaligned/generic.h> > -# define get_unaligned __get_unaligned_be > -# define put_unaligned __put_unaligned_be > -#else > -# error need to define endianess > -#endif > +#define __get_unaligned_t(type, ptr) ({ \ > + const struct { type x; } __packed *__pptr = (typeof(__pptr))(ptr); \ > + __pptr->x; \ Space before tab (cfr. checkpatch). > +}) > + > +#define get_unaligned(ptr) ({ \ > + __auto_type __ptr = (ptr); \ > + __get_unaligned_t(typeof(*__ptr), __ptr); \ > +}) > + > +#define __put_unaligned_t(type, val, ptr) ({ \ > + struct { type x; } __packed *__pptr = (typeof(__pptr))(ptr); \ > + __pptr->x = (val); \ Likewise > +}) > Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@xxxxxxxxxxxxxx In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds