Author: kib
Date: Sat Nov  2 09:16:11 2013
New Revision: 257541
URL: http://svnweb.freebsd.org/changeset/base/257541

Log:
  Fix several issues with the busdma(9) KPI use in the e1000 drivers.
  The problems do not affect bouncing busdma in a visible way, but are
  critical for the dmar backend.
  
  - The bus_dmamap_create(9) is not documented to take BUS_DMA_NOWAIT flag.
  - Unload descriptor map after receive.
  - Do not reset descriptor map to NULL, bus_dmamap_load(9) requires
    valid map, and also this leaks the map.
  
  Reported and tested by:       pho
  Approved by:  jfv
  Sponsored by: The FreeBSD Foundation
  MFC after:    2 weeks

Modified:
  head/sys/dev/e1000/if_em.c
  head/sys/dev/e1000/if_igb.c
  head/sys/dev/e1000/if_lem.c

Modified: head/sys/dev/e1000/if_em.c
==============================================================================
--- head/sys/dev/e1000/if_em.c  Sat Nov  2 02:38:32 2013        (r257540)
+++ head/sys/dev/e1000/if_em.c  Sat Nov  2 09:16:11 2013        (r257541)
@@ -4059,8 +4059,7 @@ em_allocate_receive_buffers(struct rx_ri
        rxbuf = rxr->rx_buffers;
        for (int i = 0; i < adapter->num_rx_desc; i++, rxbuf++) {
                rxbuf = &rxr->rx_buffers[i];
-               error = bus_dmamap_create(rxr->rxtag, BUS_DMA_NOWAIT,
-                   &rxbuf->map);
+               error = bus_dmamap_create(rxr->rxtag, 0, &rxbuf->map);
                if (error) {
                        device_printf(dev, "%s: bus_dmamap_create failed: %d\n",
                            __func__, error);
@@ -4467,6 +4466,7 @@ em_rxeof(struct rx_ring *rxr, int count,
                        em_rx_discard(rxr, i);
                        goto next_desc;
                }
+               bus_dmamap_unload(rxr->rxtag, rxr->rx_buffers[i].map);
 
                /* Assign correct length to the current fragment */
                mp = rxr->rx_buffers[i].m_head;
@@ -4553,6 +4553,8 @@ em_rx_discard(struct rx_ring *rxr, int i
        struct em_buffer        *rbuf;
 
        rbuf = &rxr->rx_buffers[i];
+       bus_dmamap_unload(rxr->rxtag, rbuf->map);
+
        /* Free any previous pieces */
        if (rxr->fmp != NULL) {
                rxr->fmp->m_flags |= M_PKTHDR;

Modified: head/sys/dev/e1000/if_igb.c
==============================================================================
--- head/sys/dev/e1000/if_igb.c Sat Nov  2 02:38:32 2013        (r257540)
+++ head/sys/dev/e1000/if_igb.c Sat Nov  2 09:16:11 2013        (r257541)
@@ -3996,7 +3996,6 @@ igb_txeof(struct tx_ring *txr)
                            buf->map);
                        m_freem(buf->m_head);
                        buf->m_head = NULL;
-                       buf->map = NULL;
                }
                buf->eop = NULL;
                ++txr->tx_avail;
@@ -4022,7 +4021,6 @@ igb_txeof(struct tx_ring *txr)
                                    buf->map);
                                m_freem(buf->m_head);
                                buf->m_head = NULL;
-                               buf->map = NULL;
                        }
                        ++txr->tx_avail;
                        buf->eop = NULL;
@@ -4230,15 +4228,13 @@ igb_allocate_receive_buffers(struct rx_r
 
        for (i = 0; i < adapter->num_rx_desc; i++) {
                rxbuf = &rxr->rx_buffers[i];
-               error = bus_dmamap_create(rxr->htag,
-                   BUS_DMA_NOWAIT, &rxbuf->hmap);
+               error = bus_dmamap_create(rxr->htag, 0, &rxbuf->hmap);
                if (error) {
                        device_printf(dev,
                            "Unable to create RX head DMA maps\n");
                        goto fail;
                }
-               error = bus_dmamap_create(rxr->ptag,
-                   BUS_DMA_NOWAIT, &rxbuf->pmap);
+               error = bus_dmamap_create(rxr->ptag, 0, &rxbuf->pmap);
                if (error) {
                        device_printf(dev,
                            "Unable to create RX packet DMA maps\n");
@@ -4758,11 +4754,13 @@ igb_rx_discard(struct rx_ring *rxr, int 
        if (rbuf->m_head) {
                m_free(rbuf->m_head);
                rbuf->m_head = NULL;
+               bus_dmamap_unload(rxr->htag, rbuf->hmap);
        }
 
        if (rbuf->m_pack) {
                m_free(rbuf->m_pack);
                rbuf->m_pack = NULL;
+               bus_dmamap_unload(rxr->ptag, rbuf->pmap);
        }
 
        return;
@@ -4887,6 +4885,7 @@ igb_rxeof(struct igb_queue *que, int cou
                ** case only the first header is valid.
                */
                if (rxr->hdr_split && rxr->fmp == NULL) {
+                       bus_dmamap_unload(rxr->htag, rxbuf->hmap);
                        hlen = (hdr & E1000_RXDADV_HDRBUFLEN_MASK) >>
                            E1000_RXDADV_HDRBUFLEN_SHIFT;
                        if (hlen > IGB_HDR_BUF)
@@ -4919,6 +4918,7 @@ igb_rxeof(struct igb_queue *que, int cou
                        /* clear buf info for refresh */
                        rxbuf->m_pack = NULL;
                }
+               bus_dmamap_unload(rxr->ptag, rxbuf->pmap);
 
                ++processed; /* So we know when to refresh */
 

Modified: head/sys/dev/e1000/if_lem.c
==============================================================================
--- head/sys/dev/e1000/if_lem.c Sat Nov  2 02:38:32 2013        (r257540)
+++ head/sys/dev/e1000/if_lem.c Sat Nov  2 09:16:11 2013        (r257541)
@@ -3183,8 +3183,7 @@ lem_allocate_receive_structures(struct a
        }
 
        /* Create the spare map (used by getbuf) */
-       error = bus_dmamap_create(adapter->rxtag, BUS_DMA_NOWAIT,
-            &adapter->rx_sparemap);
+       error = bus_dmamap_create(adapter->rxtag, 0, &adapter->rx_sparemap);
        if (error) {
                device_printf(dev, "%s: bus_dmamap_create failed: %d\n",
                    __func__, error);
@@ -3193,8 +3192,7 @@ lem_allocate_receive_structures(struct a
 
        rx_buffer = adapter->rx_buffer_area;
        for (i = 0; i < adapter->num_rx_desc; i++, rx_buffer++) {
-               error = bus_dmamap_create(adapter->rxtag, BUS_DMA_NOWAIT,
-                   &rx_buffer->map);
+               error = bus_dmamap_create(adapter->rxtag, 0, &rx_buffer->map);
                if (error) {
                        device_printf(dev, "%s: bus_dmamap_create failed: %d\n",
                            __func__, error);
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to