Date: Thu, 1 Aug 2013 20:10:17 +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: r253865 - head/sys/dev/ixgbe Message-ID: <201308012010.r71KAHUf024848@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jfv Date: Thu Aug 1 20:10:16 2013 New Revision: 253865 URL: http://svnweb.freebsd.org/changeset/base/253865 Log: A number of important fixes: - mbuf reused after an RX_COPY optimized operation can sometimes have a bogus cached address, resulting in TCP hangs. Add critical save points to the cached address. Thanks to Michael and the team at Verisign for finding this problem. - A couple more spots where the rxbuf->flags member should be cleared just to be sure no incorrect RX_COPY state is left around. Thanks to Adrian for tracking these down. - Remove the rearm_queues function from the driver, this was found to be responsible for some out-of-order packets by Verisign, and was always a bandaid, with the other fixes in this delta the bandaid can finally be removed. - In the other/link interrupt handler the entire state of the EICS register was being writen back into EICR (which clears causes and thus re-enables those interrupts), this was wrong, so now mask off the queue portion of the register value, so we only clear the other/link interrupt we intend. Marc from Verisign found this. - Make the SFP+ unsupported option tuneable now, by customer request. - Finally, just a couple of minor DEBUG string fixes. I want to call out and thank all the participants in the 10G community/Intel calls for helping track down these problems and make the driver better for everyone! MFC after: 3 days, these are critical fixes for 9.2! Modified: head/sys/dev/ixgbe/ixgbe.c Modified: head/sys/dev/ixgbe/ixgbe.c ============================================================================== --- head/sys/dev/ixgbe/ixgbe.c Thu Aug 1 19:37:11 2013 (r253864) +++ head/sys/dev/ixgbe/ixgbe.c Thu Aug 1 20:10:16 2013 (r253865) @@ -45,7 +45,7 @@ int ixgbe_display_debug_stat /********************************************************************* * Driver version *********************************************************************/ -char ixgbe_driver_version[] = "2.5.13"; +char ixgbe_driver_version[] = "2.5.15"; /********************************************************************* * PCI Device ID Table @@ -297,6 +297,7 @@ TUNABLE_INT("hw.ixgbe.rxd", &ixgbe_rxd); ** doing so you are on your own :) */ static int allow_unsupported_sfp = FALSE; +TUNABLE_INT("hw.ixgbe.unsupported_sfp", &allow_unsupported_sfp); /* ** HW RSC control: @@ -1071,7 +1072,7 @@ ixgbe_init_locked(struct adapter *adapte u32 rxdctl, rxctrl; mtx_assert(&adapter->core_mtx, MA_OWNED); - INIT_DEBUGOUT("ixgbe_init: begin"); + INIT_DEBUGOUT("ixgbe_init_locked: begin"); hw->adapter_stopped = FALSE; ixgbe_stop_adapter(hw); callout_stop(&adapter->timer); @@ -1382,23 +1383,6 @@ ixgbe_disable_queue(struct adapter *adap } } -static inline void -ixgbe_rearm_queues(struct adapter *adapter, u64 queues) -{ - u32 mask; - - if (adapter->hw.mac.type == ixgbe_mac_82598EB) { - mask = (IXGBE_EIMS_RTX_QUEUE & queues); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, mask); - } else { - mask = (queues & 0xFFFFFFFF); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS_EX(0), mask); - mask = (queues >> 32); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS_EX(1), mask); - } -} - - static void ixgbe_handle_que(void *context, int pending) { @@ -1506,6 +1490,10 @@ ixgbe_msix_que(void *arg) bool more; u32 newitr = 0; + /* Protect against spurious interrupts */ + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + return; + ixgbe_disable_queue(adapter, que->msix); ++que->irqs; @@ -1592,6 +1580,8 @@ ixgbe_msix_link(void *arg) /* First get the cause */ reg_eicr = IXGBE_READ_REG(hw, IXGBE_EICS); + /* Be sure the queue bits are not cleared */ + reg_eicr = ~IXGBE_EICR_RTX_QUEUE; /* Clear interrupt with write */ IXGBE_WRITE_REG(hw, IXGBE_EICR, reg_eicr); @@ -2067,7 +2057,6 @@ ixgbe_local_timer(void *arg) goto watchdog; out: - ixgbe_rearm_queues(adapter, adapter->que_mask); callout_reset(&adapter->timer, hz, ixgbe_local_timer, adapter); return; @@ -3201,7 +3190,7 @@ ixgbe_free_transmit_buffers(struct tx_ri struct ixgbe_tx_buf *tx_buffer; int i; - INIT_DEBUGOUT("free_transmit_ring: begin"); + INIT_DEBUGOUT("ixgbe_free_transmit_ring: begin"); if (txr->tx_buffers == NULL) return; @@ -4005,11 +3994,13 @@ ixgbe_setup_receive_ring(struct rx_ring addr = PNMB(slot + sj, &paddr); netmap_load_map(rxr->ptag, rxbuf->pmap, addr); - /* Update descriptor */ + /* Update descriptor and the cached value */ rxr->rx_base[j].read.pkt_addr = htole64(paddr); + rxbuf->addr = htole64(paddr); continue; } #endif /* DEV_NETMAP */ + rxbuf->flags = 0; rxbuf->buf = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, adapter->rx_mbuf_sz); if (rxbuf->buf == NULL) { @@ -4026,8 +4017,9 @@ ixgbe_setup_receive_ring(struct rx_ring goto fail; bus_dmamap_sync(rxr->ptag, rxbuf->pmap, BUS_DMASYNC_PREREAD); - /* Update descriptor */ + /* Update the descriptor and the cached value */ rxr->rx_base[j].read.pkt_addr = htole64(seg[0].ds_addr); + rxbuf->addr = htole64(seg[0].ds_addr); } @@ -4244,6 +4236,8 @@ ixgbe_free_receive_structures(struct ada { struct rx_ring *rxr = adapter->rx_rings; + INIT_DEBUGOUT("ixgbe_free_receive_structures: begin"); + for (int i = 0; i < adapter->num_queues; i++, rxr++) { struct lro_ctrl *lro = &rxr->lro; ixgbe_free_receive_buffers(rxr); @@ -4268,7 +4262,7 @@ ixgbe_free_receive_buffers(struct rx_rin struct adapter *adapter = rxr->adapter; struct ixgbe_rx_buf *rxbuf; - INIT_DEBUGOUT("free_receive_structures: begin"); + INIT_DEBUGOUT("ixgbe_free_receive_buffers: begin"); /* Cleanup any existing buffers */ if (rxr->rx_buffers != NULL) { @@ -4358,6 +4352,8 @@ ixgbe_rx_discard(struct rx_ring *rxr, in m_free(rbuf->buf); rbuf->buf = NULL; } + + rbuf->flags = 0; return; }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201308012010.r71KAHUf024848>