Date: Sat, 1 Dec 2012 00:03:58 +0000 (UTC) From: Jack F Vogel <jfv@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r243735 - head/sys/dev/ixgbe Message-ID: <201212010003.qB103xUD083978@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jfv Date: Sat Dec 1 00:03:58 2012 New Revision: 243735 URL: http://svnweb.freebsd.org/changeset/base/243735 Log: Patch #10 Performance - this changes the protocol offload interface and code in the TX path,making it tighter and hopefully more efficient. Modified: head/sys/dev/ixgbe/ixgbe.c Modified: head/sys/dev/ixgbe/ixgbe.c ============================================================================== --- head/sys/dev/ixgbe/ixgbe.c Sat Dec 1 00:02:31 2012 (r243734) +++ head/sys/dev/ixgbe/ixgbe.c Sat Dec 1 00:03:58 2012 (r243735) @@ -47,7 +47,7 @@ int ixgbe_display_debug_stat /********************************************************************* * Driver version *********************************************************************/ -char ixgbe_driver_version[] = "2.5.0 - 9"; +char ixgbe_driver_version[] = "2.5.0 - 10"; /********************************************************************* * PCI Device ID Table @@ -165,8 +165,10 @@ static int ixgbe_dma_malloc(struct adapt static void ixgbe_dma_free(struct adapter *, struct ixgbe_dma_alloc *); static void ixgbe_add_process_limit(struct adapter *, const char *, const char *, u16 *, u16); -static bool ixgbe_tx_ctx_setup(struct tx_ring *, struct mbuf *); -static bool ixgbe_tso_setup(struct tx_ring *, struct mbuf *, u32 *, u32 *); +static int ixgbe_tx_ctx_setup(struct tx_ring *, + struct mbuf *, u32 *, u32 *); +static int ixgbe_tso_setup(struct tx_ring *, + struct mbuf *, u32 *, u32 *); static void ixgbe_set_ivar(struct adapter *, u8, u8, s8); static void ixgbe_configure_ivars(struct adapter *); static u8 * ixgbe_mc_array_itr(struct ixgbe_hw *, u8 **, u32 *); @@ -1737,7 +1739,6 @@ ixgbe_xmit(struct tx_ring *txr, struct m { struct adapter *adapter = txr->adapter; u32 olinfo_status = 0, cmd_type_len; - u32 paylen = 0; int i, j, error, nsegs; int first, last = 0; bool remap = TRUE; @@ -1814,16 +1815,12 @@ retry: ** Set up the appropriate offload context ** this will consume the first descriptor */ - if (m_head->m_pkthdr.csum_flags & CSUM_TSO) { - if (ixgbe_tso_setup(txr, m_head, &paylen, &olinfo_status)) { - cmd_type_len |= IXGBE_ADVTXD_DCMD_TSE; - olinfo_status |= IXGBE_TXD_POPTS_TXSM << 8; - olinfo_status |= paylen << IXGBE_ADVTXD_PAYLEN_SHIFT; - ++txr->tso_tx; - } else - return (ENXIO); - } else if (ixgbe_tx_ctx_setup(txr, m_head)) - olinfo_status |= IXGBE_TXD_POPTS_TXSM << 8; + error = ixgbe_tx_ctx_setup(txr, m_head, &cmd_type_len, &olinfo_status); + if (__predict_false(error)) { + if (error == ENOBUFS) + *m_headp = NULL; + return (error); + } #ifdef IXGBE_FDIR /* Do the flow director magic */ @@ -1835,10 +1832,6 @@ retry: } } #endif - /* Record payload length */ - if (paylen == 0) - olinfo_status |= m_head->m_pkthdr.len << - IXGBE_ADVTXD_PAYLEN_SHIFT; i = txr->next_avail_desc; for (j = 0; j < nsegs; j++) { @@ -3218,31 +3211,37 @@ ixgbe_free_transmit_buffers(struct tx_ri /********************************************************************* * - * Advanced Context Descriptor setup for VLAN or CSUM + * Advanced Context Descriptor setup for VLAN, CSUM or TSO * **********************************************************************/ -static bool -ixgbe_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp) +static int +ixgbe_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp, + u32 *cmd_type_len, u32 *olinfo_status) { struct ixgbe_adv_tx_context_desc *TXD; - struct ixgbe_tx_buf *tx_buffer; - u32 vlan_macip_lens = 0, type_tucmd_mlhl = 0; struct ether_vlan_header *eh; struct ip *ip; struct ip6_hdr *ip6; - int ehdrlen, ip_hlen = 0; + u32 vlan_macip_lens = 0, type_tucmd_mlhl = 0; + int ehdrlen, ip_hlen = 0; u16 etype; u8 ipproto = 0; - bool offload = TRUE; - int ctxd = txr->next_avail_desc; - u16 vtag = 0; - + int offload = TRUE; + int ctxd = txr->next_avail_desc; + u16 vtag = 0; + + /* First check if TSO is to be used */ + if (mp->m_pkthdr.csum_flags & CSUM_TSO) + return (ixgbe_tso_setup(txr, mp, cmd_type_len, olinfo_status)); if ((mp->m_pkthdr.csum_flags & CSUM_OFFLOAD) == 0) offload = FALSE; - tx_buffer = &txr->tx_buffers[ctxd]; + /* Indicate the whole packet as payload when not doing TSO */ + *olinfo_status |= mp->m_pkthdr.len << IXGBE_ADVTXD_PAYLEN_SHIFT; + + /* Now ready a context descriptor */ TXD = (struct ixgbe_adv_tx_context_desc *) &txr->tx_base[ctxd]; /* @@ -3253,8 +3252,8 @@ ixgbe_tx_ctx_setup(struct tx_ring *txr, if (mp->m_flags & M_VLANTAG) { vtag = htole16(mp->m_pkthdr.ether_vtag); vlan_macip_lens |= (vtag << IXGBE_ADVTXD_VLAN_SHIFT); - } else if (offload == FALSE) - return FALSE; + } else if (offload == FALSE) /* ... no offload to do */ + return (0); /* * Determine where frame payload starts. @@ -3317,22 +3316,22 @@ ixgbe_tx_ctx_setup(struct tx_ring *txr, break; } + if (offload) /* For the TX descriptor setup */ + *olinfo_status |= IXGBE_TXD_POPTS_TXSM << 8; + /* Now copy bits into descriptor */ TXD->vlan_macip_lens |= htole32(vlan_macip_lens); TXD->type_tucmd_mlhl |= htole32(type_tucmd_mlhl); TXD->seqnum_seed = htole32(0); TXD->mss_l4len_idx = htole32(0); - tx_buffer->m_head = NULL; - tx_buffer->eop_index = -1; - /* We've consumed the first desc, adjust counters */ if (++ctxd == txr->num_desc) ctxd = 0; txr->next_avail_desc = ctxd; --txr->tx_avail; - return (offload); + return (0); } /********************************************************************** @@ -3341,14 +3340,13 @@ ixgbe_tx_ctx_setup(struct tx_ring *txr, * adapters using advanced tx descriptors * **********************************************************************/ -static bool -ixgbe_tso_setup(struct tx_ring *txr, struct mbuf *mp, u32 *paylen, - u32 *olinfo_status) +static int +ixgbe_tso_setup(struct tx_ring *txr, struct mbuf *mp, + u32 *cmd_type_len, u32 *olinfo_status) { struct ixgbe_adv_tx_context_desc *TXD; - struct ixgbe_tx_buf *tx_buffer; u32 vlan_macip_lens = 0, type_tucmd_mlhl = 0; - u32 mss_l4len_idx = 0, len; + u32 mss_l4len_idx = 0, paylen; u16 vtag = 0, eh_type; int ctxd, ehdrlen, ip_hlen, tcp_hlen; struct ether_vlan_header *eh; @@ -3374,18 +3372,15 @@ ixgbe_tso_setup(struct tx_ring *txr, str eh_type = eh->evl_encap_proto; } - /* Ensure we have at least the IP+TCP header in the first mbuf. */ - len = ehdrlen + sizeof(struct tcphdr); switch (ntohs(eh_type)) { #ifdef INET6 case ETHERTYPE_IPV6: - if (mp->m_len < len + sizeof(struct ip6_hdr)) - return FALSE; ip6 = (struct ip6_hdr *)(mp->m_data + ehdrlen); /* XXX-BZ For now we do not pretend to support ext. hdrs. */ if (ip6->ip6_nxt != IPPROTO_TCP) - return FALSE; + return (ENXIO); ip_hlen = sizeof(struct ip6_hdr); + ip6 = (struct ip6_hdr *)(mp->m_data + ehdrlen); th = (struct tcphdr *)((caddr_t)ip6 + ip_hlen); th->th_sum = in6_cksum_pseudo(ip6, 0, IPPROTO_TCP, 0); type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV6; @@ -3393,11 +3388,9 @@ ixgbe_tso_setup(struct tx_ring *txr, str #endif #ifdef INET case ETHERTYPE_IP: - if (mp->m_len < len + sizeof(struct ip)) - return FALSE; ip = (struct ip *)(mp->m_data + ehdrlen); if (ip->ip_p != IPPROTO_TCP) - return FALSE; + return (ENXIO); ip->ip_sum = 0; ip_hlen = ip->ip_hl << 2; th = (struct tcphdr *)((caddr_t)ip + ip_hlen); @@ -3415,13 +3408,12 @@ ixgbe_tso_setup(struct tx_ring *txr, str } ctxd = txr->next_avail_desc; - tx_buffer = &txr->tx_buffers[ctxd]; TXD = (struct ixgbe_adv_tx_context_desc *) &txr->tx_base[ctxd]; tcp_hlen = th->th_off << 2; /* This is used in the transmit desc in encap */ - *paylen = mp->m_pkthdr.len - ehdrlen - ip_hlen - tcp_hlen; + paylen = mp->m_pkthdr.len - ehdrlen - ip_hlen - tcp_hlen; /* VLAN MACLEN IPLEN */ if (mp->m_flags & M_VLANTAG) { @@ -3444,15 +3436,17 @@ ixgbe_tso_setup(struct tx_ring *txr, str TXD->mss_l4len_idx = htole32(mss_l4len_idx); TXD->seqnum_seed = htole32(0); - tx_buffer->m_head = NULL; - tx_buffer->eop_index = -1; if (++ctxd == txr->num_desc) ctxd = 0; txr->tx_avail--; txr->next_avail_desc = ctxd; - return TRUE; + *cmd_type_len |= IXGBE_ADVTXD_DCMD_TSE; + *olinfo_status |= IXGBE_TXD_POPTS_TXSM << 8; + *olinfo_status |= paylen << IXGBE_ADVTXD_PAYLEN_SHIFT; + ++txr->tso_tx; + return (0); } #ifdef IXGBE_FDIR
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201212010003.qB103xUD083978>