From owner-svn-src-all@freebsd.org Wed Sep 7 05:41:03 2016 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 58192BC78E8; Wed, 7 Sep 2016 05:41:03 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 32A15FCE; Wed, 7 Sep 2016 05:41:03 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u875f2LP020575; Wed, 7 Sep 2016 05:41:02 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u875f2dw020572; Wed, 7 Sep 2016 05:41:02 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201609070541.u875f2dw020572@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Wed, 7 Sep 2016 05:41:02 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r305524 - head/sys/dev/hyperv/netvsc X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 07 Sep 2016 05:41:03 -0000 Author: sephe Date: Wed Sep 7 05:41:01 2016 New Revision: 305524 URL: https://svnweb.freebsd.org/changeset/base/305524 Log: hyperv/hn: Cleanup RNDIS packet message encapsulation. MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7793 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 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:36:55 2016 (r305523) +++ head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Wed Sep 7 05:41:01 2016 (r305524) @@ -142,14 +142,14 @@ __FBSDID("$FreeBSD$"); #define HN_RING_CNT_DEF_MAX 8 -#define HN_RNDIS_MSG_LEN \ - (sizeof(rndis_msg) + \ +#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_MSG_BOUNDARY PAGE_SIZE -#define HN_RNDIS_MSG_ALIGN CACHE_LINE_SIZE +#define HN_RNDIS_PKT_BOUNDARY PAGE_SIZE +#define HN_RNDIS_PKT_ALIGN CACHE_LINE_SIZE #define HN_TX_DATA_BOUNDARY PAGE_SIZE #define HN_TX_DATA_MAXSIZE IP_MAXPACKET @@ -173,9 +173,9 @@ struct hn_txdesc { bus_dmamap_t data_dmap; - bus_addr_t rndis_msg_paddr; - rndis_msg *rndis_msg; - bus_dmamap_t rndis_msg_dmap; + bus_addr_t rndis_pkt_paddr; + struct rndis_packet_msg *rndis_pkt; + bus_dmamap_t rndis_pkt_dmap; }; #define HN_TXD_FLAG_ONLIST 0x1 @@ -845,6 +845,15 @@ netvsc_channel_rollup(struct hn_rx_ring hn_txeof(txr); } +static __inline uint32_t +hn_rndis_pktmsg_offset(uint32_t ofs) +{ + + KASSERT(ofs >= sizeof(struct rndis_packet_msg), + ("invalid RNDIS packet msg offset %u", ofs)); + return (ofs - __offsetof(struct rndis_packet_msg, rm_dataoffset)); +} + /* * NOTE: * If this function fails, then both txd and m_head0 will be freed. @@ -855,14 +864,11 @@ hn_encap(struct hn_tx_ring *txr, struct bus_dma_segment_t segs[HN_TX_DATA_SEGCNT_MAX]; int error, nsegs, i; struct mbuf *m_head = *m_head0; - rndis_msg *rndis_mesg; - rndis_packet *rndis_pkt; + struct rndis_packet_msg *pkt; rndis_per_packet_info *rppi; struct rndis_hash_value *hash_value; - uint32_t rndis_msg_size, tot_data_buf_len, send_buf_section_idx; - int send_buf_section_size; - - tot_data_buf_len = m_head->m_pkthdr.len; + uint32_t send_buf_section_idx; + int send_buf_section_size, pktlen; /* * extension points to the area reserved for the @@ -870,25 +876,20 @@ hn_encap(struct hn_tx_ring *txr, struct * the netvsc_packet (and rppi struct, if present; * length is updated later). */ - rndis_mesg = txd->rndis_msg; - /* XXX not necessary */ - memset(rndis_mesg, 0, HN_RNDIS_MSG_LEN); - rndis_mesg->ndis_msg_type = REMOTE_NDIS_PACKET_MSG; - - rndis_pkt = &rndis_mesg->msg.packet; - rndis_pkt->data_offset = sizeof(rndis_packet); - rndis_pkt->data_length = tot_data_buf_len; - rndis_pkt->per_pkt_info_offset = sizeof(rndis_packet); - - rndis_msg_size = RNDIS_MESSAGE_SIZE(rndis_packet); + pkt = txd->rndis_pkt; + pkt->rm_type = REMOTE_NDIS_PACKET_MSG; + pkt->rm_len = sizeof(*pkt) + m_head->m_pkthdr.len; + pkt->rm_dataoffset = sizeof(*pkt); + pkt->rm_datalen = m_head->m_pkthdr.len; + pkt->rm_pktinfooffset = sizeof(*pkt); + pkt->rm_pktinfolen = 0; /* * Set the hash value for this packet, so that the host could * dispatch the TX done event for this packet back to this TX * ring's channel. */ - rndis_msg_size += RNDIS_HASHVAL_PPI_SIZE; - rppi = hv_set_rppi_data(rndis_mesg, RNDIS_HASHVAL_PPI_SIZE, + 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); @@ -897,8 +898,7 @@ hn_encap(struct hn_tx_ring *txr, struct if (m_head->m_flags & M_VLANTAG) { ndis_8021q_info *rppi_vlan_info; - rndis_msg_size += RNDIS_VLAN_PPI_SIZE; - rppi = hv_set_rppi_data(rndis_mesg, RNDIS_VLAN_PPI_SIZE, + rppi = hv_set_rppi_data(pkt, RNDIS_VLAN_PPI_SIZE, ieee_8021q_info); rppi_vlan_info = (ndis_8021q_info *)((uint8_t *)rppi + @@ -924,8 +924,7 @@ hn_encap(struct hn_tx_ring *txr, struct else ether_len = ETHER_HDR_LEN; - rndis_msg_size += RNDIS_TSO_PPI_SIZE; - rppi = hv_set_rppi_data(rndis_mesg, RNDIS_TSO_PPI_SIZE, + rppi = hv_set_rppi_data(pkt, RNDIS_TSO_PPI_SIZE, tcp_large_send_info); tso_info = (rndis_tcp_tso_info *)((uint8_t *)rppi + @@ -966,8 +965,7 @@ hn_encap(struct hn_tx_ring *txr, struct } else if (m_head->m_pkthdr.csum_flags & txr->hn_csum_assist) { rndis_tcp_ip_csum_info *csum_info; - rndis_msg_size += RNDIS_CSUM_PPI_SIZE; - rppi = hv_set_rppi_data(rndis_mesg, RNDIS_CSUM_PPI_SIZE, + 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); @@ -982,24 +980,26 @@ hn_encap(struct hn_tx_ring *txr, struct csum_info->value |= NDIS_TXCSUM_INFO_UDPCS; } - rndis_mesg->msg_len = tot_data_buf_len + rndis_msg_size; - tot_data_buf_len = rndis_mesg->msg_len; + pktlen = pkt->rm_pktinfooffset + pkt->rm_pktinfolen; + /* Convert RNDIS packet message offsets */ + pkt->rm_dataoffset = hn_rndis_pktmsg_offset(pkt->rm_dataoffset); + pkt->rm_pktinfooffset = hn_rndis_pktmsg_offset(pkt->rm_pktinfooffset); /* * Chimney send, if the packet could fit into one chimney buffer. */ - if (tot_data_buf_len < txr->hn_chim_size) { + if (pkt->rm_len < txr->hn_chim_size) { txr->hn_tx_chimney_tried++; send_buf_section_idx = hn_chim_alloc(txr->hn_sc); if (send_buf_section_idx != HN_NVS_CHIM_IDX_INVALID) { uint8_t *dest = txr->hn_sc->hn_chim + (send_buf_section_idx * txr->hn_sc->hn_chim_szmax); - memcpy(dest, rndis_mesg, rndis_msg_size); - dest += rndis_msg_size; + memcpy(dest, pkt, pktlen); + dest += pktlen; m_copydata(m_head, 0, m_head->m_pkthdr.len, dest); - send_buf_section_size = tot_data_buf_len; + send_buf_section_size = pkt->rm_len; txr->hn_gpa_cnt = 0; txr->hn_tx_chimney++; goto done; @@ -1030,9 +1030,9 @@ hn_encap(struct hn_tx_ring *txr, struct txr->hn_gpa_cnt = nsegs + 1; /* send packet with page buffer */ - txr->hn_gpa[0].gpa_page = atop(txd->rndis_msg_paddr); - txr->hn_gpa[0].gpa_ofs = txd->rndis_msg_paddr & PAGE_MASK; - txr->hn_gpa[0].gpa_len = rndis_msg_size; + txr->hn_gpa[0].gpa_page = atop(txd->rndis_pkt_paddr); + txr->hn_gpa[0].gpa_ofs = txd->rndis_pkt_paddr & PAGE_MASK; + txr->hn_gpa[0].gpa_len = pktlen; /* * Fill the page buffers with mbuf info after the page @@ -2457,16 +2457,16 @@ hn_create_tx_ring(struct hn_softc *sc, i parent_dtag = bus_get_dma_tag(dev); - /* DMA tag for RNDIS messages. */ + /* DMA tag for RNDIS packet messages. */ error = bus_dma_tag_create(parent_dtag, /* parent */ - HN_RNDIS_MSG_ALIGN, /* alignment */ - HN_RNDIS_MSG_BOUNDARY, /* boundary */ + HN_RNDIS_PKT_ALIGN, /* alignment */ + HN_RNDIS_PKT_BOUNDARY, /* boundary */ BUS_SPACE_MAXADDR, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filter, filterarg */ - HN_RNDIS_MSG_LEN, /* maxsize */ + HN_RNDIS_PKT_LEN, /* maxsize */ 1, /* nsegments */ - HN_RNDIS_MSG_LEN, /* maxsegsize */ + HN_RNDIS_PKT_LEN, /* maxsegsize */ 0, /* flags */ NULL, /* lockfunc */ NULL, /* lockfuncarg */ @@ -2501,28 +2501,28 @@ hn_create_tx_ring(struct hn_softc *sc, i txd->txr = txr; /* - * Allocate and load RNDIS messages. + * Allocate and load RNDIS packet message. */ error = bus_dmamem_alloc(txr->hn_tx_rndis_dtag, - (void **)&txd->rndis_msg, - BUS_DMA_WAITOK | BUS_DMA_COHERENT, - &txd->rndis_msg_dmap); + (void **)&txd->rndis_pkt, + BUS_DMA_WAITOK | BUS_DMA_COHERENT | BUS_DMA_ZERO, + &txd->rndis_pkt_dmap); if (error) { device_printf(dev, - "failed to allocate rndis_msg, %d\n", i); + "failed to allocate rndis_packet_msg, %d\n", i); return error; } error = bus_dmamap_load(txr->hn_tx_rndis_dtag, - txd->rndis_msg_dmap, - txd->rndis_msg, HN_RNDIS_MSG_LEN, - hyperv_dma_map_paddr, &txd->rndis_msg_paddr, + txd->rndis_pkt_dmap, + txd->rndis_pkt, HN_RNDIS_PKT_LEN, + hyperv_dma_map_paddr, &txd->rndis_pkt_paddr, BUS_DMA_NOWAIT); if (error) { device_printf(dev, - "failed to load rndis_msg, %d\n", i); + "failed to load rndis_packet_msg, %d\n", i); bus_dmamem_free(txr->hn_tx_rndis_dtag, - txd->rndis_msg, txd->rndis_msg_dmap); + txd->rndis_pkt, txd->rndis_pkt_dmap); return error; } @@ -2533,9 +2533,9 @@ hn_create_tx_ring(struct hn_softc *sc, i device_printf(dev, "failed to allocate tx data dmamap\n"); bus_dmamap_unload(txr->hn_tx_rndis_dtag, - txd->rndis_msg_dmap); + txd->rndis_pkt_dmap); bus_dmamem_free(txr->hn_tx_rndis_dtag, - txd->rndis_msg, txd->rndis_msg_dmap); + txd->rndis_pkt, txd->rndis_pkt_dmap); return error; } @@ -2593,9 +2593,9 @@ hn_txdesc_dmamap_destroy(struct hn_txdes KASSERT(txd->m == NULL, ("still has mbuf installed")); KASSERT((txd->flags & HN_TXD_FLAG_DMAMAP) == 0, ("still dma mapped")); - bus_dmamap_unload(txr->hn_tx_rndis_dtag, txd->rndis_msg_dmap); - bus_dmamem_free(txr->hn_tx_rndis_dtag, txd->rndis_msg, - txd->rndis_msg_dmap); + bus_dmamap_unload(txr->hn_tx_rndis_dtag, txd->rndis_pkt_dmap); + bus_dmamem_free(txr->hn_tx_rndis_dtag, txd->rndis_pkt, + txd->rndis_pkt_dmap); bus_dmamap_destroy(txr->hn_tx_data_dtag, txd->data_dmap); } Modified: head/sys/dev/hyperv/netvsc/hv_rndis.h ============================================================================== --- head/sys/dev/hyperv/netvsc/hv_rndis.h Wed Sep 7 05:36:55 2016 (r305523) +++ head/sys/dev/hyperv/netvsc/hv_rndis.h Wed Sep 7 05:41:01 2016 (r305524) @@ -900,8 +900,7 @@ 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(rndis_msg *rndis_mesg, - uint32_t rppi_size, +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:36:55 2016 (r305523) +++ head/sys/dev/hyperv/netvsc/hv_rndis_filter.c Wed Sep 7 05:41:01 2016 (r305524) @@ -106,24 +106,31 @@ again: * Set the Per-Packet-Info with the specified type */ void * -hv_set_rppi_data(rndis_msg *rndis_mesg, uint32_t rppi_size, - int pkt_type) +hv_set_rppi_data(struct rndis_packet_msg *pkt, uint32_t rppi_size, int pkt_type) { - rndis_packet *rndis_pkt; rndis_per_packet_info *rppi; - rndis_pkt = &rndis_mesg->msg.packet; - rndis_pkt->data_offset += rppi_size; + /* Data immediately follow per-packet-info. */ + pkt->rm_dataoffset += rppi_size; - rppi = (rndis_per_packet_info *)((char *)rndis_pkt + - rndis_pkt->per_pkt_info_offset + rndis_pkt->per_pkt_info_length); + /* Update RNDIS packet msg length */ + pkt->rm_len += rppi_size; + + /* + * Per-packet-info does not move; it only grows. + * + * NOTE: + * 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); - rndis_pkt->per_pkt_info_length += rppi_size; - return (rppi); }