Tue Jun 13 09:37:22 2017 UTC ()
Sync with FreeBSD r316541:

 > Fix a double free in ixgbe_rxeof()
 >
 > Submitted by:	rstone
 > MFC after:	1 week
 > Differential Revision:	https://reviews.freebsd.org/D10255


(msaitoh)
diff -r1.26 -r1.27 src/sys/dev/pci/ixgbe/ix_txrx.c

cvs diff -r1.26 -r1.27 src/sys/dev/pci/ixgbe/ix_txrx.c (expand / switch to unified diff)

--- src/sys/dev/pci/ixgbe/ix_txrx.c 2017/06/13 09:35:12 1.26
+++ src/sys/dev/pci/ixgbe/ix_txrx.c 2017/06/13 09:37:22 1.27
@@ -49,27 +49,27 @@ @@ -49,27 +49,27 @@
49 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 49 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
50 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 50 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
51 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 51 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
52 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 52 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
53 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 53 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
54 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 54 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
55 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 55 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
56 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 56 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
57 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 57 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
58 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 58 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
59 * POSSIBILITY OF SUCH DAMAGE. 59 * POSSIBILITY OF SUCH DAMAGE.
60 */ 60 */
61/*$FreeBSD: head/sys/dev/ixgbe/ix_txrx.c 301538 2016-06-07 04:51:50Z sephe $*/ 61/*$FreeBSD: head/sys/dev/ixgbe/ix_txrx.c 301538 2016-06-07 04:51:50Z sephe $*/
62/*$NetBSD: ix_txrx.c,v 1.26 2017/06/13 09:35:12 msaitoh Exp $*/ 62/*$NetBSD: ix_txrx.c,v 1.27 2017/06/13 09:37:22 msaitoh Exp $*/
63 63
64#include "opt_inet.h" 64#include "opt_inet.h"
65#include "opt_inet6.h" 65#include "opt_inet6.h"
66 66
67#include "ixgbe.h" 67#include "ixgbe.h"
68 68
69#ifdef DEV_NETMAP 69#ifdef DEV_NETMAP
70#include <net/netmap.h> 70#include <net/netmap.h>
71#include <sys/selinfo.h> 71#include <sys/selinfo.h>
72#include <dev/netmap/netmap_kern.h> 72#include <dev/netmap/netmap_kern.h>
73 73
74extern int ix_crcstrip; 74extern int ix_crcstrip;
75#endif 75#endif
@@ -1436,41 +1436,30 @@ ixgbe_allocate_receive_buffers(struct rx @@ -1436,41 +1436,30 @@ ixgbe_allocate_receive_buffers(struct rx
1436 } 1436 }
1437 } 1437 }
1438 1438
1439 return (0); 1439 return (0);
1440 1440
1441fail: 1441fail:
1442 /* Frees all, but can handle partial completion */ 1442 /* Frees all, but can handle partial completion */
1443 ixgbe_free_receive_structures(adapter); 1443 ixgbe_free_receive_structures(adapter);
1444 return (error); 1444 return (error);
1445} 1445}
1446 1446
1447static void  1447static void
1448ixgbe_free_receive_ring(struct rx_ring *rxr) 1448ixgbe_free_receive_ring(struct rx_ring *rxr)
1449{  1449{
1450 struct ixgbe_rx_buf *rxbuf; 
1451 1450
1452 for (int i = 0; i < rxr->num_desc; i++) { 1451 for (int i = 0; i < rxr->num_desc; i++) {
1453 rxbuf = &rxr->rx_buffers[i]; 1452 ixgbe_rx_discard(rxr, i);
1454 if (rxbuf->buf != NULL) { 
1455 bus_dmamap_sync(rxr->ptag->dt_dmat, rxbuf->pmap, 
1456 0, rxbuf->buf->m_pkthdr.len, 
1457 BUS_DMASYNC_POSTREAD); 
1458 ixgbe_dmamap_unload(rxr->ptag, rxbuf->pmap); 
1459 rxbuf->buf->m_flags |= M_PKTHDR; 
1460 m_freem(rxbuf->buf); 
1461 rxbuf->buf = NULL; 
1462 rxbuf->flags = 0; 
1463 } 
1464 } 1453 }
1465} 1454}
1466 1455
1467/********************************************************************* 1456/*********************************************************************
1468 * 1457 *
1469 * Initialize a receive ring and its buffers. 1458 * Initialize a receive ring and its buffers.
1470 * 1459 *
1471 **********************************************************************/ 1460 **********************************************************************/
1472static int 1461static int
1473ixgbe_setup_receive_ring(struct rx_ring *rxr) 1462ixgbe_setup_receive_ring(struct rx_ring *rxr)
1474{ 1463{
1475 struct adapter *adapter; 1464 struct adapter *adapter;
1476 struct ixgbe_rx_buf *rxbuf; 1465 struct ixgbe_rx_buf *rxbuf;
@@ -1622,27 +1611,29 @@ ixgbe_setup_receive_structures(struct ad @@ -1622,27 +1611,29 @@ ixgbe_setup_receive_structures(struct ad
1622 for (j = 0; j < adapter->num_queues; j++, rxr++) 1611 for (j = 0; j < adapter->num_queues; j++, rxr++)
1623 if (ixgbe_setup_receive_ring(rxr)) 1612 if (ixgbe_setup_receive_ring(rxr))
1624 goto fail; 1613 goto fail;
1625 1614
1626 return (0); 1615 return (0);
1627fail: 1616fail:
1628 /* 1617 /*
1629 * Free RX buffers allocated so far, we will only handle 1618 * Free RX buffers allocated so far, we will only handle
1630 * the rings that completed, the failing case will have 1619 * the rings that completed, the failing case will have
1631 * cleaned up for itself. 'j' failed, so its the terminus. 1620 * cleaned up for itself. 'j' failed, so its the terminus.
1632 */ 1621 */
1633 for (int i = 0; i < j; ++i) { 1622 for (int i = 0; i < j; ++i) {
1634 rxr = &adapter->rx_rings[i]; 1623 rxr = &adapter->rx_rings[i];
 1624 IXGBE_RX_LOCK(rxr);
1635 ixgbe_free_receive_ring(rxr); 1625 ixgbe_free_receive_ring(rxr);
 1626 IXGBE_RX_UNLOCK(rxr);
1636 } 1627 }
1637 1628
1638 return (ENOBUFS); 1629 return (ENOBUFS);
1639} 1630}
1640 1631
1641 1632
1642/********************************************************************* 1633/*********************************************************************
1643 * 1634 *
1644 * Free all receive rings. 1635 * Free all receive rings.
1645 * 1636 *
1646 **********************************************************************/ 1637 **********************************************************************/
1647void 1638void
1648ixgbe_free_receive_structures(struct adapter *adapter) 1639ixgbe_free_receive_structures(struct adapter *adapter)
@@ -1676,35 +1667,27 @@ ixgbe_free_receive_structures(struct ada @@ -1676,35 +1667,27 @@ ixgbe_free_receive_structures(struct ada
1676 **********************************************************************/ 1667 **********************************************************************/
1677static void 1668static void
1678ixgbe_free_receive_buffers(struct rx_ring *rxr) 1669ixgbe_free_receive_buffers(struct rx_ring *rxr)
1679{ 1670{
1680 struct adapter *adapter = rxr->adapter; 1671 struct adapter *adapter = rxr->adapter;
1681 struct ixgbe_rx_buf *rxbuf; 1672 struct ixgbe_rx_buf *rxbuf;
1682 1673
1683 INIT_DEBUGOUT("ixgbe_free_receive_buffers: begin"); 1674 INIT_DEBUGOUT("ixgbe_free_receive_buffers: begin");
1684 1675
1685 /* Cleanup any existing buffers */ 1676 /* Cleanup any existing buffers */
1686 if (rxr->rx_buffers != NULL) { 1677 if (rxr->rx_buffers != NULL) {
1687 for (int i = 0; i < adapter->num_rx_desc; i++) { 1678 for (int i = 0; i < adapter->num_rx_desc; i++) {
1688 rxbuf = &rxr->rx_buffers[i]; 1679 rxbuf = &rxr->rx_buffers[i];
1689 if (rxbuf->buf != NULL) { 1680 ixgbe_rx_discard(rxr, i);
1690 bus_dmamap_sync(rxr->ptag->dt_dmat, 
1691 rxbuf->pmap, 0, rxbuf->buf->m_pkthdr.len, 
1692 BUS_DMASYNC_POSTREAD); 
1693 ixgbe_dmamap_unload(rxr->ptag, rxbuf->pmap); 
1694 rxbuf->buf->m_flags |= M_PKTHDR; 
1695 m_freem(rxbuf->buf); 
1696 } 
1697 rxbuf->buf = NULL; 
1698 if (rxbuf->pmap != NULL) { 1681 if (rxbuf->pmap != NULL) {
1699 ixgbe_dmamap_destroy(rxr->ptag, rxbuf->pmap); 1682 ixgbe_dmamap_destroy(rxr->ptag, rxbuf->pmap);
1700 rxbuf->pmap = NULL; 1683 rxbuf->pmap = NULL;
1701 } 1684 }
1702 } 1685 }
1703 if (rxr->rx_buffers != NULL) { 1686 if (rxr->rx_buffers != NULL) {
1704 free(rxr->rx_buffers, M_DEVBUF); 1687 free(rxr->rx_buffers, M_DEVBUF);
1705 rxr->rx_buffers = NULL; 1688 rxr->rx_buffers = NULL;
1706 } 1689 }
1707 } 1690 }
1708 1691
1709 if (rxr->ptag != NULL) { 1692 if (rxr->ptag != NULL) {
1710 ixgbe_dma_tag_destroy(rxr->ptag); 1693 ixgbe_dma_tag_destroy(rxr->ptag);
@@ -1762,31 +1745,34 @@ ixgbe_rx_discard(struct rx_ring *rxr, in @@ -1762,31 +1745,34 @@ ixgbe_rx_discard(struct rx_ring *rxr, in
1762 1745
1763 rbuf = &rxr->rx_buffers[i]; 1746 rbuf = &rxr->rx_buffers[i];
1764 1747
1765 1748
1766 /* 1749 /*
1767 ** With advanced descriptors the writeback 1750 ** With advanced descriptors the writeback
1768 ** clobbers the buffer addrs, so its easier 1751 ** clobbers the buffer addrs, so its easier
1769 ** to just free the existing mbufs and take 1752 ** to just free the existing mbufs and take
1770 ** the normal refresh path to get new buffers 1753 ** the normal refresh path to get new buffers
1771 ** and mapping. 1754 ** and mapping.
1772 */ 1755 */
1773 1756
1774 if (rbuf->fmp != NULL) {/* Partial chain ? */ 1757 if (rbuf->fmp != NULL) {/* Partial chain ? */
1775 rbuf->fmp->m_flags |= M_PKTHDR; 1758 bus_dmamap_sync(rxr->ptag->dt_dmat, rbuf->pmap, 0,
 1759 rbuf->buf->m_pkthdr.len, BUS_DMASYNC_POSTREAD);
1776 m_freem(rbuf->fmp); 1760 m_freem(rbuf->fmp);
1777 rbuf->fmp = NULL; 1761 rbuf->fmp = NULL;
1778 rbuf->buf = NULL; /* rbuf->buf is part of fmp's chain */ 1762 rbuf->buf = NULL; /* rbuf->buf is part of fmp's chain */
1779 } else if (rbuf->buf) { 1763 } else if (rbuf->buf) {
 1764 bus_dmamap_sync(rxr->ptag->dt_dmat, rbuf->pmap, 0,
 1765 rbuf->buf->m_pkthdr.len, BUS_DMASYNC_POSTREAD);
1780 m_free(rbuf->buf); 1766 m_free(rbuf->buf);
1781 rbuf->buf = NULL; 1767 rbuf->buf = NULL;
1782 } 1768 }
1783 ixgbe_dmamap_unload(rxr->ptag, rbuf->pmap); 1769 ixgbe_dmamap_unload(rxr->ptag, rbuf->pmap);
1784 1770
1785 rbuf->flags = 0; 1771 rbuf->flags = 0;
1786 1772
1787 return; 1773 return;
1788} 1774}
1789 1775
1790 1776
1791/********************************************************************* 1777/*********************************************************************
1792 * 1778 *
@@ -1860,26 +1846,29 @@ ixgbe_rxeof(struct ix_queue *que) @@ -1860,26 +1846,29 @@ ixgbe_rxeof(struct ix_queue *que)
1860 eop = ((staterr & IXGBE_RXD_STAT_EOP) != 0); 1846 eop = ((staterr & IXGBE_RXD_STAT_EOP) != 0);
1861 1847
1862 /* Make sure bad packets are discarded */ 1848 /* Make sure bad packets are discarded */
1863 if (eop && (staterr & IXGBE_RXDADV_ERR_FRAME_ERR_MASK) != 0) { 1849 if (eop && (staterr & IXGBE_RXDADV_ERR_FRAME_ERR_MASK) != 0) {
1864#if __FreeBSD_version >= 1100036 1850#if __FreeBSD_version >= 1100036
1865 if (IXGBE_IS_VF(adapter)) 1851 if (IXGBE_IS_VF(adapter))
1866 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); 1852 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
1867#endif 1853#endif
1868 rxr->rx_discarded.ev_count++; 1854 rxr->rx_discarded.ev_count++;
1869 ixgbe_rx_discard(rxr, i); 1855 ixgbe_rx_discard(rxr, i);
1870 goto next_desc; 1856 goto next_desc;
1871 } 1857 }
1872 1858
 1859 bus_dmamap_sync(rxr->ptag->dt_dmat, rbuf->pmap, 0,
 1860 rbuf->buf->m_pkthdr.len, BUS_DMASYNC_POSTREAD);
 1861
1873 /* 1862 /*
1874 ** On 82599 which supports a hardware 1863 ** On 82599 which supports a hardware
1875 ** LRO (called HW RSC), packets need 1864 ** LRO (called HW RSC), packets need
1876 ** not be fragmented across sequential 1865 ** not be fragmented across sequential
1877 ** descriptors, rather the next descriptor 1866 ** descriptors, rather the next descriptor
1878 ** is indicated in bits of the descriptor. 1867 ** is indicated in bits of the descriptor.
1879 ** This also means that we might proceses 1868 ** This also means that we might proceses
1880 ** more than one packet at a time, something 1869 ** more than one packet at a time, something
1881 ** that has never been true before, it 1870 ** that has never been true before, it
1882 ** required eliminating global chain pointers 1871 ** required eliminating global chain pointers
1883 ** in favor of what we are doing here. -jfv 1872 ** in favor of what we are doing here. -jfv
1884 */ 1873 */
1885 if (!eop) { 1874 if (!eop) {