public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* in6_addr struct union with uint64_t
@ 2024-01-26 14:57 James Hanley
  2024-01-26 19:38 ` Florian Weimer
  0 siblings, 1 reply; 4+ messages in thread
From: James Hanley @ 2024-01-26 14:57 UTC (permalink / raw)
  To: libc-alpha

[-- Attachment #1: Type: text/plain, Size: 1533 bytes --]

In a local experiment, I added the union fields __u6_addr64 and
__u6_addr128 for in the in6_addr structure to allow the compiler to
optimize access for the Interface ID of an IPv6 address as applicable using
the EUI-48/64 in IPv6 in the case of the uint64_t and to allow the compiler
to optimize access when comparing, setting, manipulating IPv6 addresses as
a whole with the GCC specific unsigned __int128. Code below modified
from inet/netinet/in.h:

#if !__USE_KERNEL_IPV6_DEFS
/* IPv6 address */
struct in6_addr
  {
    union
      {
        uint8_t __u6_addr8[16];
        uint16_t __u6_addr16[8];
        uint32_t __u6_addr32[4];
        uint64_t __u6_addr64[2]; // new
        unsigned __int128 __u6_addr128; // new
      } __in6_u;
#define s6_addr                 __in6_u.__u6_addr8
#ifdef __USE_MISC
# define s6_addr16              __in6_u.__u6_addr16
# define s6_addr32              __in6_u.__u6_addr32
# define s6_addr64              __in6_u.__u6_addr64
# define s6_addr128             __in6_u.__u6_addr128
#endif
  };
#endif /* !__USE_KERNEL_IPV6_DEFS */

First, is this useful, and is there a standard that prohibits defining
additional union members?

Second, when building, I hit an alignment issue in an assertion check in
resolv/resolv_conf.c comparing sockaddr_in and sockaddr_in6 with the
change.  I assumed I should add "__attribute__((aligned(128)))" ahead of
the struct sockaddr_in definition to force sockaddr_in to align to 128bit,
however, this did not resolve the issue. Any suggestions?

Thanks much,
-Jim

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: in6_addr struct union with uint64_t
  2024-01-26 14:57 in6_addr struct union with uint64_t James Hanley
@ 2024-01-26 19:38 ` Florian Weimer
  2024-01-29 18:02   ` James Hanley
  0 siblings, 1 reply; 4+ messages in thread
From: Florian Weimer @ 2024-01-26 19:38 UTC (permalink / raw)
  To: James Hanley; +Cc: libc-alpha

* James Hanley:

> #if !__USE_KERNEL_IPV6_DEFS
> /* IPv6 address */
> struct in6_addr
>   {
>     union
>       {
>         uint8_t __u6_addr8[16];
>         uint16_t __u6_addr16[8];
>         uint32_t __u6_addr32[4];
>         uint64_t __u6_addr64[2]; // new
>         unsigned __int128 __u6_addr128; // new
>       } __in6_u;
> #define s6_addr                 __in6_u.__u6_addr8
> #ifdef __USE_MISC
> # define s6_addr16              __in6_u.__u6_addr16
> # define s6_addr32              __in6_u.__u6_addr32
> # define s6_addr64              __in6_u.__u6_addr64
> # define s6_addr128             __in6_u.__u6_addr128
> #endif
>   };
> #endif /* !__USE_KERNEL_IPV6_DEFS */ 
>
> First, is this useful, and is there a standard that prohibits defining
> additional union members?

It changes alignment from 4 bytes to 16 bytes on some architectures,
which is an ABI-breaking change.  For example, if a member of type
struct in6_addr is embedded in a struct, it may require additional
padding in front of it as a result of this change.

Compilers should be able to use wider instructions if beneficial.

Thanks,
Florian


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: in6_addr struct union with uint64_t
  2024-01-26 19:38 ` Florian Weimer
@ 2024-01-29 18:02   ` James Hanley
  2024-01-29 19:08     ` Florian Weimer
  0 siblings, 1 reply; 4+ messages in thread
From: James Hanley @ 2024-01-29 18:02 UTC (permalink / raw)
  To: Florian Weimer; +Cc: libc-alpha

[-- Attachment #1: Type: text/plain, Size: 1762 bytes --]

I believe I understand your point - is the concern that the alignment issue
would be manifested with an already compiled legacy application utilizing
this newly built library and would require the in6_addr to be 16-byte
aligned or hit a runtime exception if the address passed in isn't aligned -
correct?

Is that why the definition has never gone beyond 4-byte words for the
in6_addr union to stay alignment compatible with in_addr IPv4 address?

On Fri, Jan 26, 2024 at 2:38 PM Florian Weimer <fweimer@redhat.com> wrote:

> * James Hanley:
>
> > #if !__USE_KERNEL_IPV6_DEFS
> > /* IPv6 address */
> > struct in6_addr
> >   {
> >     union
> >       {
> >         uint8_t __u6_addr8[16];
> >         uint16_t __u6_addr16[8];
> >         uint32_t __u6_addr32[4];
> >         uint64_t __u6_addr64[2]; // new
> >         unsigned __int128 __u6_addr128; // new
> >       } __in6_u;
> > #define s6_addr                 __in6_u.__u6_addr8
> > #ifdef __USE_MISC
> > # define s6_addr16              __in6_u.__u6_addr16
> > # define s6_addr32              __in6_u.__u6_addr32
> > # define s6_addr64              __in6_u.__u6_addr64
> > # define s6_addr128             __in6_u.__u6_addr128
> > #endif
> >   };
> > #endif /* !__USE_KERNEL_IPV6_DEFS */
> >
> > First, is this useful, and is there a standard that prohibits defining
> > additional union members?
>
> It changes alignment from 4 bytes to 16 bytes on some architectures,
> which is an ABI-breaking change.  For example, if a member of type
> struct in6_addr is embedded in a struct, it may require additional
> padding in front of it as a result of this change.
>
> Compilers should be able to use wider instructions if beneficial.
>
> Thanks,
> Florian
>
>

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: in6_addr struct union with uint64_t
  2024-01-29 18:02   ` James Hanley
@ 2024-01-29 19:08     ` Florian Weimer
  0 siblings, 0 replies; 4+ messages in thread
From: Florian Weimer @ 2024-01-29 19:08 UTC (permalink / raw)
  To: James Hanley; +Cc: libc-alpha

* James Hanley:

> I believe I understand your point - is the concern that the alignment
> issue would be manifested with an already compiled legacy application
> utilizing this newly built library and would require the in6_addr to
> be 16-byte aligned or hit a runtime exception if the address passed in
> isn't aligned - correct?

It's not so much the run-time exception/trap, but that struct offsets
may change as a result of the increased alignment.

If the compiler supports decreasing alignment, we could add the
additional arrays, but I'm not sure if that's worth it.

Thanks,
Florian


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2024-01-29 19:08 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-01-26 14:57 in6_addr struct union with uint64_t James Hanley
2024-01-26 19:38 ` Florian Weimer
2024-01-29 18:02   ` James Hanley
2024-01-29 19:08     ` Florian Weimer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).