* 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).