Author: sephe
Date: Wed Sep  7 06:02:29 2016
New Revision: 305525
URL: https://svnweb.freebsd.org/changeset/base/305525

Log:
  hyperv/hn: Simplify per-packet-info construction.
  
  MFC after:    1 week
  Sponsored by: Microsoft
  Differential Revision:        https://reviews.freebsd.org/D7794

Modified:
  head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
  head/sys/dev/hyperv/netvsc/hv_rndis.h
  head/sys/dev/hyperv/netvsc/hv_rndis_filter.c
  head/sys/dev/hyperv/netvsc/if_hnreg.h
  head/sys/dev/hyperv/netvsc/if_hnvar.h

Modified: head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
==============================================================================
--- head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c  Wed Sep  7 05:41:01 
2016        (r305524)
+++ head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c  Wed Sep  7 06:02:29 
2016        (r305525)
@@ -142,12 +142,12 @@ __FBSDID("$FreeBSD$");
 
 #define HN_RING_CNT_DEF_MAX            8
 
-#define HN_RNDIS_PKT_LEN               \
-    (sizeof(struct rndis_packet_msg) + \
-     RNDIS_HASHVAL_PPI_SIZE +          \
-     RNDIS_VLAN_PPI_SIZE +             \
-     RNDIS_TSO_PPI_SIZE +              \
-     RNDIS_CSUM_PPI_SIZE)
+#define HN_RNDIS_PKT_LEN                                       \
+       (sizeof(struct rndis_packet_msg) +                      \
+        HN_RNDIS_PKTINFO_SIZE(HN_NDIS_HASH_VALUE_SIZE) +       \
+        HN_RNDIS_PKTINFO_SIZE(NDIS_VLAN_INFO_SIZE) +           \
+        HN_RNDIS_PKTINFO_SIZE(NDIS_LSO2_INFO_SIZE) +           \
+        HN_RNDIS_PKTINFO_SIZE(NDIS_TXCSUM_INFO_SIZE))
 #define HN_RNDIS_PKT_BOUNDARY          PAGE_SIZE
 #define HN_RNDIS_PKT_ALIGN             CACHE_LINE_SIZE
 
@@ -865,10 +865,9 @@ hn_encap(struct hn_tx_ring *txr, struct 
        int error, nsegs, i;
        struct mbuf *m_head = *m_head0;
        struct rndis_packet_msg *pkt;
-       rndis_per_packet_info *rppi;
-       struct rndis_hash_value *hash_value;
        uint32_t send_buf_section_idx;
        int send_buf_section_size, pktlen;
+       uint32_t *pi_data;
 
        /*
         * extension points to the area reserved for the
@@ -889,21 +888,14 @@ hn_encap(struct hn_tx_ring *txr, struct 
         * dispatch the TX done event for this packet back to this TX
         * ring's channel.
         */
-       rppi = hv_set_rppi_data(pkt, RNDIS_HASHVAL_PPI_SIZE,
-           nbl_hash_value);
-       hash_value = (struct rndis_hash_value *)((uint8_t *)rppi +
-           rppi->per_packet_info_offset);
-       hash_value->hash_value = txr->hn_tx_idx;
+       pi_data = hn_rndis_pktinfo_append(pkt, HN_RNDIS_PKT_LEN,
+           HN_NDIS_HASH_VALUE_SIZE, HN_NDIS_PKTINFO_TYPE_HASHVAL);
+       *pi_data = txr->hn_tx_idx;
 
        if (m_head->m_flags & M_VLANTAG) {
-               ndis_8021q_info *rppi_vlan_info;
-
-               rppi = hv_set_rppi_data(pkt, RNDIS_VLAN_PPI_SIZE,
-                   ieee_8021q_info);
-
-               rppi_vlan_info = (ndis_8021q_info *)((uint8_t *)rppi +
-                   rppi->per_packet_info_offset);
-               rppi_vlan_info->u1.value = NDIS_VLAN_INFO_MAKE(
+               pi_data = hn_rndis_pktinfo_append(pkt, HN_RNDIS_PKT_LEN,
+                   NDIS_VLAN_INFO_SIZE, NDIS_PKTINFO_TYPE_VLAN);
+               *pi_data = NDIS_VLAN_INFO_MAKE(
                    EVL_VLANOFTAG(m_head->m_pkthdr.ether_vtag),
                    EVL_PRIOFTAG(m_head->m_pkthdr.ether_vtag),
                    EVL_CFIOFTAG(m_head->m_pkthdr.ether_vtag));
@@ -911,7 +903,6 @@ hn_encap(struct hn_tx_ring *txr, struct 
 
        if (m_head->m_pkthdr.csum_flags & CSUM_TSO) {
 #if defined(INET6) || defined(INET)
-               rndis_tcp_tso_info *tso_info;   
                struct ether_vlan_header *eh;
                int ether_len;
 
@@ -924,12 +915,8 @@ hn_encap(struct hn_tx_ring *txr, struct 
                else
                        ether_len = ETHER_HDR_LEN;
 
-               rppi = hv_set_rppi_data(pkt, RNDIS_TSO_PPI_SIZE,
-                   tcp_large_send_info);
-
-               tso_info = (rndis_tcp_tso_info *)((uint8_t *)rppi +
-                   rppi->per_packet_info_offset);
-
+               pi_data = hn_rndis_pktinfo_append(pkt, HN_RNDIS_PKT_LEN,
+                   NDIS_LSO2_INFO_SIZE, NDIS_PKTINFO_TYPE_LSO);
 #ifdef INET
                if (m_head->m_pkthdr.csum_flags & CSUM_IP_TSO) {
                        struct ip *ip =
@@ -942,7 +929,7 @@ hn_encap(struct hn_tx_ring *txr, struct 
                        ip->ip_sum = 0;
                        th->th_sum = in_pseudo(ip->ip_src.s_addr,
                            ip->ip_dst.s_addr, htons(IPPROTO_TCP));
-                       tso_info->value = NDIS_LSO2_INFO_MAKEIPV4(0,
+                       *pi_data = NDIS_LSO2_INFO_MAKEIPV4(0,
                            m_head->m_pkthdr.tso_segsz);
                }
 #endif
@@ -957,27 +944,23 @@ hn_encap(struct hn_tx_ring *txr, struct 
 
                        ip6->ip6_plen = 0;
                        th->th_sum = in6_cksum_pseudo(ip6, 0, IPPROTO_TCP, 0);
-                       tso_info->value = NDIS_LSO2_INFO_MAKEIPV6(0,
+                       *pi_data = NDIS_LSO2_INFO_MAKEIPV6(0,
                            m_head->m_pkthdr.tso_segsz);
                }
 #endif
 #endif /* INET6 || INET */
        } else if (m_head->m_pkthdr.csum_flags & txr->hn_csum_assist) {
-               rndis_tcp_ip_csum_info *csum_info;
-
-               rppi = hv_set_rppi_data(pkt, RNDIS_CSUM_PPI_SIZE,
-                   tcpip_chksum_info);
-               csum_info = (rndis_tcp_ip_csum_info *)((uint8_t *)rppi +
-                   rppi->per_packet_info_offset);
+               pi_data = hn_rndis_pktinfo_append(pkt, HN_RNDIS_PKT_LEN,
+                   NDIS_TXCSUM_INFO_SIZE, NDIS_PKTINFO_TYPE_CSUM);
+               *pi_data = NDIS_TXCSUM_INFO_IPV4;
 
-               csum_info->value = NDIS_TXCSUM_INFO_IPV4;
                if (m_head->m_pkthdr.csum_flags & CSUM_IP)
-                       csum_info->value |= NDIS_TXCSUM_INFO_IPCS;
+                       *pi_data |= NDIS_TXCSUM_INFO_IPCS;
 
                if (m_head->m_pkthdr.csum_flags & CSUM_TCP)
-                       csum_info->value |= NDIS_TXCSUM_INFO_TCPCS;
+                       *pi_data |= NDIS_TXCSUM_INFO_TCPCS;
                else if (m_head->m_pkthdr.csum_flags & CSUM_UDP)
-                       csum_info->value |= NDIS_TXCSUM_INFO_UDPCS;
+                       *pi_data |= NDIS_TXCSUM_INFO_UDPCS;
        }
 
        pktlen = pkt->rm_pktinfooffset + pkt->rm_pktinfolen;

Modified: head/sys/dev/hyperv/netvsc/hv_rndis.h
==============================================================================
--- head/sys/dev/hyperv/netvsc/hv_rndis.h       Wed Sep  7 05:41:01 2016        
(r305524)
+++ head/sys/dev/hyperv/netvsc/hv_rndis.h       Wed Sep  7 06:02:29 2016        
(r305525)
@@ -569,18 +569,6 @@ typedef struct rndis_tcp_tso_info_ {
        };
 } rndis_tcp_tso_info;
 
-#define RNDIS_HASHVAL_PPI_SIZE (sizeof(rndis_per_packet_info) + \
-                               sizeof(struct rndis_hash_value))
-
-#define RNDIS_VLAN_PPI_SIZE    (sizeof(rndis_per_packet_info) + \
-                               sizeof(ndis_8021q_info))
-
-#define RNDIS_CSUM_PPI_SIZE    (sizeof(rndis_per_packet_info) + \
-                               sizeof(rndis_tcp_ip_csum_info))
-
-#define RNDIS_TSO_PPI_SIZE     (sizeof(rndis_per_packet_info) + \
-                               sizeof(rndis_tcp_tso_info))
-
 /*
  * Format of Information buffer passed in a SetRequest for the OID
  * OID_GEN_RNDIS_CONFIG_PARAMETER.
@@ -900,8 +888,5 @@ int netvsc_recv(struct hn_rx_ring *rxr, 
     const struct hn_recvinfo *info);
 void netvsc_channel_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr);
 
-void* hv_set_rppi_data(struct rndis_packet_msg *pkt, uint32_t rppi_size,
-    int pkt_type);
-
 #endif  /* __HV_RNDIS_H__ */
 

Modified: head/sys/dev/hyperv/netvsc/hv_rndis_filter.c
==============================================================================
--- head/sys/dev/hyperv/netvsc/hv_rndis_filter.c        Wed Sep  7 05:41:01 
2016        (r305524)
+++ head/sys/dev/hyperv/netvsc/hv_rndis_filter.c        Wed Sep  7 06:02:29 
2016        (r305525)
@@ -102,19 +102,15 @@ again:
        return ((rid & 0xffff) << 16);
 }
 
-/*
- * Set the Per-Packet-Info with the specified type
- */
 void *
-hv_set_rppi_data(struct rndis_packet_msg *pkt, uint32_t rppi_size, int 
pkt_type)
+hn_rndis_pktinfo_append(struct rndis_packet_msg *pkt, size_t pktsize,
+    size_t pi_dlen, uint32_t pi_type)
 {
-       rndis_per_packet_info *rppi;
+       const size_t pi_size = HN_RNDIS_PKTINFO_SIZE(pi_dlen);
+       struct rndis_pktinfo *pi;
 
-       /* Data immediately follow per-packet-info. */
-       pkt->rm_dataoffset += rppi_size;
-
-       /* Update RNDIS packet msg length */
-       pkt->rm_len += rppi_size;
+       KASSERT((pi_size & RNDIS_PACKET_MSG_OFFSET_ALIGNMASK) == 0,
+           ("unaligned pktinfo size %zu, pktinfo dlen %zu", pi_size, pi_dlen));
 
        /*
         * Per-packet-info does not move; it only grows.
@@ -123,15 +119,23 @@ hv_set_rppi_data(struct rndis_packet_msg
         * rm_pktinfooffset in this phase counts from the beginning
         * of rndis_packet_msg.
         */
-       rppi = (rndis_per_packet_info *)((uint8_t *)pkt +
-           pkt->rm_pktinfooffset + pkt->rm_pktinfolen);
-       pkt->rm_pktinfolen += rppi_size;
-
-       rppi->size = rppi_size;
-       rppi->type = pkt_type;
-       rppi->per_packet_info_offset = sizeof(rndis_per_packet_info);
+       KASSERT(pkt->rm_pktinfooffset + pkt->rm_pktinfolen + pi_size <= pktsize,
+           ("%u pktinfo overflows RNDIS packet msg", pi_type));
+       pi = (struct rndis_pktinfo *)((uint8_t *)pkt + pkt->rm_pktinfooffset +
+           pkt->rm_pktinfolen);
+       pkt->rm_pktinfolen += pi_size;
+
+       pi->rm_size = pi_size;
+       pi->rm_type = pi_type;
+       pi->rm_pktinfooffset = RNDIS_PKTINFO_OFFSET;
+
+       /* Data immediately follow per-packet-info. */
+       pkt->rm_dataoffset += pi_size;
+
+       /* Update RNDIS packet msg length */
+       pkt->rm_len += pi_size;
 
-       return (rppi);
+       return (pi->rm_data);
 }
 
 /*

Modified: head/sys/dev/hyperv/netvsc/if_hnreg.h
==============================================================================
--- head/sys/dev/hyperv/netvsc/if_hnreg.h       Wed Sep  7 05:41:01 2016        
(r305524)
+++ head/sys/dev/hyperv/netvsc/if_hnreg.h       Wed Sep  7 06:02:29 2016        
(r305525)
@@ -221,4 +221,8 @@ CTASSERT(sizeof(struct hn_nvs_rndis_ack)
 #define HN_NDIS_HASH_VALUE_SIZE                sizeof(uint32_t)
 #define HN_NDIS_PKTINFO_TYPE_HASHVAL   NDIS_PKTINFO_TYPE_PKT_CANCELID
 
+/* Per-packet-info size */
+#define HN_RNDIS_PKTINFO_SIZE(dlen)    \
+       __offsetof(struct rndis_pktinfo, rm_data[dlen])
+
 #endif /* !_IF_HNREG_H_ */

Modified: head/sys/dev/hyperv/netvsc/if_hnvar.h
==============================================================================
--- head/sys/dev/hyperv/netvsc/if_hnvar.h       Wed Sep  7 05:41:01 2016        
(r305524)
+++ head/sys/dev/hyperv/netvsc/if_hnvar.h       Wed Sep  7 06:02:29 2016        
(r305525)
@@ -121,6 +121,9 @@ void                hn_nvs_sent_xact(struct hn_send_ct
 uint32_t       hn_chim_alloc(struct hn_softc *sc);
 void           hn_chim_free(struct hn_softc *sc, uint32_t chim_idx);
 
+void           *hn_rndis_pktinfo_append(struct rndis_packet_msg *,
+                   size_t pktsize, size_t pi_dlen, uint32_t pi_type);
+
 extern struct hn_send_ctx      hn_send_ctx_none;
 
 #endif /* !_IF_HNVAR_H_ */
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to