In article <5912ca9e-b4e7-423d-a45d-f4693d1c9...@zoulas.com>,
Christos Zoulas  <chris...@zoulas.com> wrote:
>-=-=-=-=-=-

Here's the final changes

- Make ALIGNED_POINTER use __alignof(t) instead of sizeof(t). This is more
  correct because it works with non-primitive types and provides the ABI
  alignment for the type the compiler will use.
- Remove all the *_HDR_ALIGNMENT macros and asserts
- Replace POINTER_ALIGNED_P with ACCESSIBLE_POINTER which is identical to
  ALIGNED_POINTER, but returns that the pointer is always aligned if the
  CPU supports unaligned accesses.

Index: sys/mbuf.h
===================================================================
RCS file: /cvsroot/src/sys/sys/mbuf.h,v
retrieving revision 1.231
diff -u -u -r1.231 mbuf.h
--- sys/mbuf.h  17 Feb 2021 22:32:04 -0000      1.231
+++ sys/mbuf.h  17 Feb 2021 23:54:31 -0000
@@ -843,15 +843,21 @@
        m->m_pkthdr.rcvif_index = n->m_pkthdr.rcvif_index;
 }
 
+#define M_GET_ALIGNED_HDR(m, type, linkhdr) \
+    m_get_aligned_hdr((m), __alignof(type) - 1, sizeof(type), (linkhdr))
+
 static __inline int
-m_get_aligned_hdr(struct mbuf **m, int align, size_t hlen, bool linkhdr)
+m_get_aligned_hdr(struct mbuf **m, int mask, size_t hlen, bool linkhdr)
 {
-       if (POINTER_ALIGNED_P(mtod(*m, void *), align) == 0) {
-               --align;        // Turn into mask
+#ifndef __NO_STRICT_ALIGNMENT
+       if (((uintptr_t)mtod(*m, void *) & mask) != 0)
                *m = m_copyup(*m, hlen, 
-                     linkhdr ? (max_linkhdr + align) & ~align : 0);
-       } else if (__predict_false((size_t)(*m)->m_len < hlen))
+                     linkhdr ? (max_linkhdr + mask) & ~mask : 0);
+       else
+#endif
+       if (__predict_false((size_t)(*m)->m_len < hlen))
                *m = m_pullup(*m, hlen);
+
        return *m == NULL;
 }
 
Index: sys/param.h
===================================================================
RCS file: /cvsroot/src/sys/sys/param.h,v
retrieving revision 1.689
diff -u -u -r1.689 param.h
--- sys/param.h 17 Feb 2021 22:32:04 -0000      1.689
+++ sys/param.h 17 Feb 2021 23:54:31 -0000
@@ -281,16 +281,24 @@
 #define        ALIGN(p)                (((uintptr_t)(p) + ALIGNBYTES) & 
~ALIGNBYTES)
 #endif
 #ifndef ALIGNED_POINTER
-#define        ALIGNED_POINTER(p,t)    ((((uintptr_t)(p)) & (sizeof(t) - 1)) 
== 0)
+#define        ALIGNED_POINTER(p,t)    ((((uintptr_t)(p)) & (__alignof(t) - 
1)) == 0)
 #endif
 #ifndef ALIGNED_POINTER_LOAD
 #define        ALIGNED_POINTER_LOAD(q,p,t)     (*(q) = *((const t *)(p)))
 #endif
 
+/*
+ * Return if the pointer p is accessible for type t. For primitive types
+ * this means that the pointer itself can be dereferenced; for structures
+ * and unions this means that any field can be dereferenced. On CPUs
+ * that allow unaligned pointer access, we always return that the pointer
+ * is accessible to prevent unnecessary copies, although this might not be
+ * necessarily faster.
+ */
 #ifdef __NO_STRICT_ALIGNMENT
-#define        POINTER_ALIGNED_P(p, a)         1
+#define        ACCESSIBLE_POINTER(p, t)        1
 #else
-#define        POINTER_ALIGNED_P(p, a)         (((uintptr_t)(p) & ((a) - 1)) 
== 0)
+#define        ACCESSIBLE_POINTER(p, t)        ALIGNED_POINTER(p, t)
 #endif
 
 /*
Index: net/if_arp.h
===================================================================
RCS file: /cvsroot/src/sys/net/if_arp.h,v
retrieving revision 1.42
diff -u -u -r1.42 if_arp.h
--- net/if_arp.h        17 Feb 2021 22:32:04 -0000      1.42
+++ net/if_arp.h        17 Feb 2021 23:54:31 -0000
@@ -72,8 +72,6 @@
        uint8_t  ar_tpa[];      /* target protocol address */
 #endif
 };
-#define        ARP_HDR_ALIGNMENT       __alignof(struct arphdr)
-__CTASSERT(ARP_HDR_ALIGNMENT == 2);
 
 static __inline uint8_t *
 ar_data(struct arphdr *ap)
Index: net/if_bridge.c
===================================================================
RCS file: /cvsroot/src/sys/net/if_bridge.c,v
retrieving revision 1.178
diff -u -u -r1.178 if_bridge.c
--- net/if_bridge.c     14 Feb 2021 20:58:34 -0000      1.178
+++ net/if_bridge.c     17 Feb 2021 23:54:31 -0000
@@ -2806,7 +2806,7 @@
        if (*mp == NULL)
                return -1;
 
-       if (m_get_aligned_hdr(&m, IP_HDR_ALIGNMENT, sizeof(*ip), true) != 0) {
+       if (M_GET_ALIGNED_HDR(&m, struct ip, true) != 0) {
                /* XXXJRT new stat, please */
                ip_statinc(IP_STAT_TOOSMALL);
                goto bad;
@@ -2900,7 +2900,7 @@
         * it.  Otherwise, if it is aligned, make sure the entire base
         * IPv6 header is in the first mbuf of the chain.
         */
-       if (m_get_aligned_hdr(&m, IP6_HDR_ALIGNMENT, sizeof(*ip6), true) != 0) {
+       if (M_GET_ALIGNED_HDR(&m, struct ip6_hdr, true) != 0) {
                struct ifnet *inifp = m_get_rcvif_NOMPSAFE(m);
                /* XXXJRT new stat, please */
                ip6_statinc(IP6_STAT_TOOSMALL);
Index: netinet/if_arp.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/if_arp.c,v
retrieving revision 1.306
diff -u -u -r1.306 if_arp.c
--- netinet/if_arp.c    16 Feb 2021 10:22:52 -0000      1.306
+++ netinet/if_arp.c    17 Feb 2021 23:54:31 -0000
@@ -706,7 +706,7 @@
                                goto badlen;
                }
                ar = mtod(m, struct arphdr *);
-               KASSERT(POINTER_ALIGNED_P(ar, ARP_HDR_ALIGNMENT));
+               KASSERT(ACCESSIBLE_POINTER(ar, struct arphdr));
 
                rcvif = m_get_rcvif(m, &s);
                if (__predict_false(rcvif == NULL)) {
@@ -735,7 +735,7 @@
                        if ((m = m_pullup(m, arplen)) == NULL)
                                goto badlen;
                        ar = mtod(m, struct arphdr *);
-                       KASSERT(POINTER_ALIGNED_P(ar, ARP_HDR_ALIGNMENT));
+                       KASSERT(ACCESSIBLE_POINTER(ar, struct arphdr));
                }
 
                switch (ntohs(ar->ar_pro)) {
Index: netinet/in_l2tp.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/in_l2tp.c,v
retrieving revision 1.19
diff -u -u -r1.19 in_l2tp.c
--- netinet/in_l2tp.c   14 Feb 2021 20:58:35 -0000      1.19
+++ netinet/in_l2tp.c   17 Feb 2021 23:54:31 -0000
@@ -197,8 +197,7 @@
                error = ENOBUFS;
                goto out;
        }
-       if (m_get_aligned_hdr(&m, IP_HDR_ALIGNMENT, sizeof(iphdr), false) != 0)
-       {
+       if (M_GET_ALIGNED_HDR(&m, struct ip, false) != 0) {
                error = ENOBUFS;
                goto out;
        }
Index: netinet/ip_flow.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/ip_flow.c,v
retrieving revision 1.84
diff -u -u -r1.84 ip_flow.c
--- netinet/ip_flow.c   15 Feb 2021 03:41:01 -0000      1.84
+++ netinet/ip_flow.c   17 Feb 2021 23:54:31 -0000
@@ -231,7 +231,7 @@
         * IP header with no option and valid version and length
         */
        ip = mtod(m, struct ip *);
-       if (!POINTER_ALIGNED_P(ip, IP_HDR_ALIGNMENT)) {
+       if (!ACCESSIBLE_POINTER(ip, struct ip)) {
                memcpy(&ip_store, mtod(m, const void *), sizeof(ip_store));
                ip = &ip_store;
        }
@@ -313,7 +313,7 @@
         *
         * XXX Use m_copyback_cow(9) here? --dyoung
         */
-       if (!POINTER_ALIGNED_P(mtod(m, void *), IP_HDR_ALIGNMENT))
+       if (!ACCESSIBLE_POINTER(mtod(m, void *), struct ip))
                memcpy(mtod(m, void *), &ip_store, sizeof(ip_store));
 
        /*
Index: netinet/ip_input.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/ip_input.c,v
retrieving revision 1.398
diff -u -u -r1.398 ip_input.c
--- netinet/ip_input.c  14 Feb 2021 20:58:35 -0000      1.398
+++ netinet/ip_input.c  17 Feb 2021 23:54:31 -0000
@@ -454,7 +454,7 @@
         * it.  Otherwise, if it is aligned, make sure the entire
         * base IP header is in the first mbuf of the chain.
         */
-       if (m_get_aligned_hdr(&m, IP_HDR_ALIGNMENT, sizeof(*ip), true) != 0) {
+       if (M_GET_ALIGNED_HDR(&m, struct ip, true) != 0) {
                /* XXXJRT new stat, please */
                IP_STATINC(IP_STAT_TOOSMALL);
                goto out;
Index: netinet/ip_private.h
===================================================================
RCS file: /cvsroot/src/sys/netinet/ip_private.h,v
retrieving revision 1.5
diff -u -u -r1.5 ip_private.h
--- netinet/ip_private.h        17 Feb 2021 22:32:04 -0000      1.5
+++ netinet/ip_private.h        17 Feb 2021 23:54:31 -0000
@@ -43,8 +43,6 @@
 #define        IP_STATINC(x)           _NET_STATINC(ipstat_percpu, x)
 #define        IP_STATDEC(x)           _NET_STATDEC(ipstat_percpu, x)
 
-#define        IP_HDR_ALIGNMENT        __alignof(struct ip)
-__CTASSERT(IP_HDR_ALIGNMENT == 4);
 #endif /* _KERNEL */
 
 #endif /* !_NETINET_IP_PRIVATE_H_ */
Index: netinet/tcp_input.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/tcp_input.c,v
retrieving revision 1.425
diff -u -u -r1.425 tcp_input.c
--- netinet/tcp_input.c 14 Feb 2021 20:58:35 -0000      1.425
+++ netinet/tcp_input.c 17 Feb 2021 23:54:31 -0000
@@ -1274,7 +1274,7 @@
         * Enforce alignment requirements that are violated in
         * some cases, see kern/50766 for details.
         */
-       if (POINTER_ALIGNED_P(th, TCP_HDR_ALIGNMENT) == 0) {
+       if (ACCESSIBLE_POINTER(th, struct tcp_hdr) == 0) {
                m = m_copyup(m, off + sizeof(struct tcphdr), 0);
                if (m == NULL) {
                        TCP_STATINC(TCP_STAT_RCVSHORT);
@@ -1282,7 +1282,7 @@
                }
                th = (struct tcphdr *)(mtod(m, char *) + off);
        }
-       KASSERT(POINTER_ALIGNED_P(th, TCP_HDR_ALIGNMENT));
+       KASSERT(ACCESSIBLE_POINTER(th, struct tcp_hdr));
 
        /*
         * Get IP and TCP header.
@@ -1362,7 +1362,7 @@
                        TCP_STATINC(TCP_STAT_RCVSHORT);
                        return;
                }
-               KASSERT(POINTER_ALIGNED_P(th, TCP_HDR_ALIGNMENT));
+               KASSERT(ACCESSIBLE_POINTER(th, struct tcp_hdr));
                optlen = thlen - sizeof(struct tcphdr);
                optp = ((u_int8_t *)th) + sizeof(struct tcphdr);
 
Index: netinet/tcp_private.h
===================================================================
RCS file: /cvsroot/src/sys/netinet/tcp_private.h,v
retrieving revision 1.5
diff -u -u -r1.5 tcp_private.h
--- netinet/tcp_private.h       17 Feb 2021 22:32:04 -0000      1.5
+++ netinet/tcp_private.h       17 Feb 2021 23:54:31 -0000
@@ -43,8 +43,6 @@
 #define        TCP_STATINC(x)          _NET_STATINC(tcpstat_percpu, x)
 #define        TCP_STATADD(x, v)       _NET_STATADD(tcpstat_percpu, x, v)
 
-#define        TCP_HDR_ALIGNMENT       __alignof(struct tcphdr)
-__CTASSERT(TCP_HDR_ALIGNMENT == 4);
 #endif /* _KERNEL */
 
 #endif /* !_NETINET_TCP_PRIVATE_H_ */
Index: netinet/udp_private.h
===================================================================
RCS file: /cvsroot/src/sys/netinet/udp_private.h,v
retrieving revision 1.5
diff -u -u -r1.5 udp_private.h
--- netinet/udp_private.h       17 Feb 2021 22:32:04 -0000      1.5
+++ netinet/udp_private.h       17 Feb 2021 23:54:31 -0000
@@ -39,8 +39,6 @@
 
 #define        UDP_STATINC(x)          _NET_STATINC(udpstat_percpu, x)
 
-#define        UDP_HDR_ALIGNMENT       __alignof(struct udphdr)
-__CTASSERT(UDP_HDR_ALIGNMENT == 2);
 #endif /* _KERNEL */
 
 #endif /* !_NETINET_UDP_PRIVATE_H_ */
Index: netinet/udp_usrreq.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/udp_usrreq.c,v
retrieving revision 1.260
diff -u -u -r1.260 udp_usrreq.c
--- netinet/udp_usrreq.c        14 Feb 2021 20:58:35 -0000      1.260
+++ netinet/udp_usrreq.c        17 Feb 2021 23:54:31 -0000
@@ -335,7 +335,7 @@
         * Enforce alignment requirements that are violated in
         * some cases, see kern/50766 for details.
         */
-       if (POINTER_ALIGNED_P(uh, UDP_HDR_ALIGNMENT) == 0) {
+       if (ACCESSIBLE_POINTER(uh, struct udphdr) == 0) {
                m = m_copyup(m, iphlen + sizeof(struct udphdr), 0);
                if (m == NULL) {
                        UDP_STATINC(UDP_STAT_HDROPS);
@@ -344,7 +344,7 @@
                ip = mtod(m, struct ip *);
                uh = (struct udphdr *)(mtod(m, char *) + iphlen);
        }
-       KASSERT(POINTER_ALIGNED_P(uh, UDP_HDR_ALIGNMENT));
+       KASSERT(ACCESSIBLE_POINTER(uh, struct udphdr));
 
        /* destination port of 0 is illegal, based on RFC768. */
        if (uh->uh_dport == 0)
Index: netinet6/icmp6.c
===================================================================
RCS file: /cvsroot/src/sys/netinet6/icmp6.c,v
retrieving revision 1.249
diff -u -u -r1.249 icmp6.c
--- netinet6/icmp6.c    15 Feb 2021 10:13:45 -0000      1.249
+++ netinet6/icmp6.c    17 Feb 2021 23:54:31 -0000
@@ -538,7 +538,7 @@
         * Enforce alignment requirements that are violated in
         * some cases, see kern/50766 for details.
         */
-       if (POINTER_ALIGNED_P(icmp6, IP6_HDR_ALIGNMENT) == 0) {
+       if (ACCESSIBLE_POINTER(icmp6, struct ip6_hdr) == 0) {
                m = m_copyup(m, off + sizeof(struct icmp6_hdr), 0);
                if (m == NULL) {
                        ICMP6_STATINC(ICMP6_STAT_TOOSHORT);
@@ -548,7 +548,7 @@
                ip6 = mtod(m, struct ip6_hdr *);
                icmp6 = (struct icmp6_hdr *)(mtod(m, char *) + off);
        }
-       KASSERT(POINTER_ALIGNED_P(icmp6, IP6_HDR_ALIGNMENT));
+       KASSERT(ACCESSIBLE_POINTER(icmp6, struct ip6_hdr));
 
        /*
         * calculate the checksum
Index: netinet6/in6_l2tp.c
===================================================================
RCS file: /cvsroot/src/sys/netinet6/in6_l2tp.c,v
retrieving revision 1.20
diff -u -u -r1.20 in6_l2tp.c
--- netinet6/in6_l2tp.c 14 Feb 2021 20:58:35 -0000      1.20
+++ netinet6/in6_l2tp.c 17 Feb 2021 23:54:31 -0000
@@ -193,8 +193,7 @@
        M_PREPEND(m, sizeof(struct ip6_hdr), M_DONTWAIT);
        if (m == NULL)
                return ENOBUFS;
-       if (m_get_aligned_hdr(&m, IP6_HDR_ALIGNMENT, sizeof(ip6hdr),
-           false) != 0)
+       if (M_GET_ALIGNED_HDR(&m, struct ip6_hdr, false) != 0)
                return ENOBUFS;
        memcpy(mtod(m, struct ip6_hdr *), &ip6hdr, sizeof(struct ip6_hdr));
 
Index: netinet6/ip6_flow.c
===================================================================
RCS file: /cvsroot/src/sys/netinet6/ip6_flow.c,v
retrieving revision 1.41
diff -u -u -r1.41 ip6_flow.c
--- netinet6/ip6_flow.c 14 Feb 2021 20:58:35 -0000      1.41
+++ netinet6/ip6_flow.c 17 Feb 2021 23:54:31 -0000
@@ -283,7 +283,7 @@
        if ((m->m_flags & (M_BCAST|M_MCAST)) != 0)
                goto out;
 
-       if (POINTER_ALIGNED_P(mtod(m, const void *), IP6_HDR_ALIGNMENT) == 0) {
+       if (ACCESSIBLE_POINTER(mtod(m, const void *), struct ip6_hdr) == 0) {
                if ((m = m_copyup(m, sizeof(struct ip6_hdr),
                    (max_linkhdr + 3) & ~3)) == NULL) {
                        ret = 1;
Index: netinet6/ip6_input.c
===================================================================
RCS file: /cvsroot/src/sys/netinet6/ip6_input.c,v
retrieving revision 1.223
diff -u -u -r1.223 ip6_input.c
--- netinet6/ip6_input.c        14 Feb 2021 20:58:35 -0000      1.223
+++ netinet6/ip6_input.c        17 Feb 2021 23:54:31 -0000
@@ -301,7 +301,7 @@
         * it.  Otherwise, if it is aligned, make sure the entire base
         * IPv6 header is in the first mbuf of the chain.
         */
-       if (m_get_aligned_hdr(&m, IP6_HDR_ALIGNMENT, sizeof(*ip6), true) != 0) {
+       if (M_GET_ALIGNED_HDR(&m, struct ip6_hdr, true) != 0) {
                /* XXXJRT new stat, please */
                IP6_STATINC(IP6_STAT_TOOSMALL);
                in6_ifstat_inc(rcvif, ifs6_in_hdrerr);
@@ -602,7 +602,7 @@
                        rtcache_percpu_putref(ip6_forward_rt_percpu);
                        return;
                }
-               KASSERT(POINTER_ALIGNED_P(hbh, IP6_HDR_ALIGNMENT));
+               KASSERT(ACCESSIBLE_POINTER(hbh, struct ip6_hdr));
                nxt = hbh->ip6h_nxt;
 
                /*
@@ -875,7 +875,7 @@
                IP6_STATINC(IP6_STAT_TOOSHORT);
                return -1;
        }
-       KASSERT(POINTER_ALIGNED_P(hbh, IP6_HDR_ALIGNMENT));
+       KASSERT(ACCESSIBLE_POINTER(hbh, struct ip6_hdr));
        off += hbhlen;
        hbhlen -= sizeof(struct ip6_hbh);
 
@@ -1215,7 +1215,7 @@
                                IP6_STATINC(IP6_STAT_TOOSHORT);
                                return;
                        }
-                       KASSERT(POINTER_ALIGNED_P(ip6e, IP6_HDR_ALIGNMENT));
+                       KASSERT(ACCESSIBLE_POINTER(ip6e, struct ip6_hdr));
 
                        switch (nxt) {
                        case IPPROTO_DSTOPTS:
Index: netinet6/ip6_private.h
===================================================================
RCS file: /cvsroot/src/sys/netinet6/ip6_private.h,v
retrieving revision 1.5
diff -u -u -r1.5 ip6_private.h
--- netinet6/ip6_private.h      17 Feb 2021 22:32:04 -0000      1.5
+++ netinet6/ip6_private.h      17 Feb 2021 23:54:31 -0000
@@ -43,8 +43,6 @@
 #define        IP6_STATINC(x)          _NET_STATINC(ip6stat_percpu, x)
 #define        IP6_STATDEC(x)          _NET_STATDEC(ip6stat_percpu, x)
 
-#define        IP6_HDR_ALIGNMENT       __alignof(struct ip6_hdr)
-__CTASSERT(IP6_HDR_ALIGNMENT == 4);
 #endif /* _KERNEL */
 
 #endif /* !_NETINET_IP6_PRIVATE_H_ */
Index: netinet6/udp6_usrreq.c
===================================================================
RCS file: /cvsroot/src/sys/netinet6/udp6_usrreq.c,v
retrieving revision 1.149
diff -u -u -r1.149 udp6_usrreq.c
--- netinet6/udp6_usrreq.c      14 Feb 2021 20:58:35 -0000      1.149
+++ netinet6/udp6_usrreq.c      17 Feb 2021 23:54:31 -0000
@@ -665,7 +665,7 @@
         * Enforce alignment requirements that are violated in
         * some cases, see kern/50766 for details.
         */
-       if (POINTER_ALIGNED_P(uh, UDP_HDR_ALIGNMENT) == 0) {
+       if (ACCESSIBLE_POINTER(uh, struct udphdr) == 0) {
                m = m_copyup(m, off + sizeof(struct udphdr), 0);
                if (m == NULL) {
                        IP6_STATINC(IP6_STAT_TOOSHORT);
@@ -674,7 +674,7 @@
                ip6 = mtod(m, struct ip6_hdr *);
                uh = (struct udphdr *)(mtod(m, char *) + off);
        }
-       KASSERT(POINTER_ALIGNED_P(uh, UDP_HDR_ALIGNMENT));
+       KASSERT(ACCESSIBLE_POINTER(uh, struct udphdr));
        ulen = ntohs((u_short)uh->uh_ulen);
 
        /*

Reply via email to