svn commit: r308167 - head/sys/dev/hyperv/netvsc
Sepherosa Ziehau
sephe at FreeBSD.org
Tue Nov 1 08:20:34 UTC 2016
Author: sephe
Date: Tue Nov 1 08:20:33 2016
New Revision: 308167
URL: https://svnweb.freebsd.org/changeset/base/308167
Log:
hyperv/hn: Directly fill chimney sending buffer for small packets.
MFC after: 1 week
Sponsored by: Microsoft
Differential Revision: https://reviews.freebsd.org/D8394
Modified:
head/sys/dev/hyperv/netvsc/if_hn.c
Modified: head/sys/dev/hyperv/netvsc/if_hn.c
==============================================================================
--- head/sys/dev/hyperv/netvsc/if_hn.c Tue Nov 1 07:41:26 2016 (r308166)
+++ head/sys/dev/hyperv/netvsc/if_hn.c Tue Nov 1 08:20:33 2016 (r308167)
@@ -1394,15 +1394,28 @@ hn_encap(struct hn_tx_ring *txr, struct
struct mbuf *m_head = *m_head0;
struct rndis_packet_msg *pkt;
uint32_t *pi_data;
+ void *chim = NULL;
int pktlen;
- /*
- * extension points to the area reserved for the
- * rndis_filter_packet, which is placed just after
- * the netvsc_packet (and rppi struct, if present;
- * length is updated later).
- */
pkt = txd->rndis_pkt;
+ if (m_head->m_pkthdr.len + HN_RNDIS_PKT_LEN < txr->hn_chim_size) {
+ /*
+ * This packet is small enough to fit into a chimney sending
+ * buffer. Try allocating one chimney sending buffer now.
+ */
+ txr->hn_tx_chimney_tried++;
+ txd->chim_index = hn_chim_alloc(txr->hn_sc);
+ if (txd->chim_index != HN_NVS_CHIM_IDX_INVALID) {
+ chim = txr->hn_sc->hn_chim +
+ (txd->chim_index * txr->hn_sc->hn_chim_szmax);
+ /*
+ * Directly fill the chimney sending buffer w/ the
+ * RNDIS packet message.
+ */
+ pkt = chim;
+ }
+ }
+
pkt->rm_type = REMOTE_NDIS_PACKET_MSG;
pkt->rm_len = sizeof(*pkt) + m_head->m_pkthdr.len;
pkt->rm_dataoffset = sizeof(*pkt);
@@ -1475,26 +1488,25 @@ hn_encap(struct hn_tx_ring *txr, struct
pkt->rm_pktinfooffset = hn_rndis_pktmsg_offset(pkt->rm_pktinfooffset);
/*
- * Chimney send, if the packet could fit into one chimney buffer.
+ * Fast path: Chimney sending.
*/
- if (pkt->rm_len < txr->hn_chim_size) {
- txr->hn_tx_chimney_tried++;
- txd->chim_index = hn_chim_alloc(txr->hn_sc);
- if (txd->chim_index != HN_NVS_CHIM_IDX_INVALID) {
- uint8_t *dest = txr->hn_sc->hn_chim +
- (txd->chim_index * txr->hn_sc->hn_chim_szmax);
-
- memcpy(dest, pkt, pktlen);
- dest += pktlen;
- m_copydata(m_head, 0, m_head->m_pkthdr.len, dest);
-
- txd->chim_size = pkt->rm_len;
- txr->hn_gpa_cnt = 0;
- txr->hn_tx_chimney++;
- txr->hn_sendpkt = hn_txpkt_chim;
- goto done;
- }
- }
+ if (chim != NULL) {
+ KASSERT(txd->chim_index != HN_NVS_CHIM_IDX_INVALID,
+ ("chimney buffer is not used"));
+ KASSERT(pkt == chim, ("RNDIS pkt not in chimney buffer"));
+
+ m_copydata(m_head, 0, m_head->m_pkthdr.len,
+ ((uint8_t *)chim) + pktlen);
+
+ txd->chim_size = pkt->rm_len;
+ txr->hn_gpa_cnt = 0;
+ txr->hn_tx_chimney++;
+ txr->hn_sendpkt = hn_txpkt_chim;
+ goto done;
+ }
+ KASSERT(txd->chim_index == HN_NVS_CHIM_IDX_INVALID,
+ ("chimney buffer is used"));
+ KASSERT(pkt == txd->rndis_pkt, ("RNDIS pkt not in txdesc"));
error = hn_txdesc_dmamap_load(txr, txd, &m_head, segs, &nsegs);
if (error) {
More information about the svn-src-all
mailing list