ixgbe: fix unmap length bug
This patch addresses three WARN_ON statements from DMA-API debug code ixgbe is mapping more than it unmaps, reduce the length of the map call and remove the "used once" local variable. found by Joerg Roedel <joerg.roedel@amd.com> in 2.6.30, so is a candidate for -stable. in addition, fix missing ->dma = 0 after unmap to prevent double free with pci_unmap_single and lastly, don't unmap (half) pages that aren't mapped. Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com> CC: Joerg Roedel <joerg.roedel@amd.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
a1f25324b9
commit
4f57ca6e17
|
@ -563,7 +563,6 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter,
|
||||||
union ixgbe_adv_rx_desc *rx_desc;
|
union ixgbe_adv_rx_desc *rx_desc;
|
||||||
struct ixgbe_rx_buffer *bi;
|
struct ixgbe_rx_buffer *bi;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
unsigned int bufsz = rx_ring->rx_buf_len + NET_IP_ALIGN;
|
|
||||||
|
|
||||||
i = rx_ring->next_to_use;
|
i = rx_ring->next_to_use;
|
||||||
bi = &rx_ring->rx_buffer_info[i];
|
bi = &rx_ring->rx_buffer_info[i];
|
||||||
|
@ -593,7 +592,9 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter,
|
||||||
|
|
||||||
if (!bi->skb) {
|
if (!bi->skb) {
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
skb = netdev_alloc_skb(adapter->netdev, bufsz);
|
skb = netdev_alloc_skb(adapter->netdev,
|
||||||
|
(rx_ring->rx_buf_len +
|
||||||
|
NET_IP_ALIGN));
|
||||||
|
|
||||||
if (!skb) {
|
if (!skb) {
|
||||||
adapter->alloc_rx_buff_failed++;
|
adapter->alloc_rx_buff_failed++;
|
||||||
|
@ -608,7 +609,8 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter,
|
||||||
skb_reserve(skb, NET_IP_ALIGN);
|
skb_reserve(skb, NET_IP_ALIGN);
|
||||||
|
|
||||||
bi->skb = skb;
|
bi->skb = skb;
|
||||||
bi->dma = pci_map_single(pdev, skb->data, bufsz,
|
bi->dma = pci_map_single(pdev, skb->data,
|
||||||
|
rx_ring->rx_buf_len,
|
||||||
PCI_DMA_FROMDEVICE);
|
PCI_DMA_FROMDEVICE);
|
||||||
}
|
}
|
||||||
/* Refresh the desc even if buffer_addrs didn't change because
|
/* Refresh the desc even if buffer_addrs didn't change because
|
||||||
|
@ -732,6 +734,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
|
||||||
pci_unmap_single(pdev, rx_buffer_info->dma,
|
pci_unmap_single(pdev, rx_buffer_info->dma,
|
||||||
rx_ring->rx_buf_len,
|
rx_ring->rx_buf_len,
|
||||||
PCI_DMA_FROMDEVICE);
|
PCI_DMA_FROMDEVICE);
|
||||||
|
rx_buffer_info->dma = 0;
|
||||||
skb_put(skb, len);
|
skb_put(skb, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2815,9 +2818,11 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter,
|
||||||
}
|
}
|
||||||
if (!rx_buffer_info->page)
|
if (!rx_buffer_info->page)
|
||||||
continue;
|
continue;
|
||||||
pci_unmap_page(pdev, rx_buffer_info->page_dma, PAGE_SIZE / 2,
|
if (rx_buffer_info->page_dma) {
|
||||||
PCI_DMA_FROMDEVICE);
|
pci_unmap_page(pdev, rx_buffer_info->page_dma,
|
||||||
rx_buffer_info->page_dma = 0;
|
PAGE_SIZE / 2, PCI_DMA_FROMDEVICE);
|
||||||
|
rx_buffer_info->page_dma = 0;
|
||||||
|
}
|
||||||
put_page(rx_buffer_info->page);
|
put_page(rx_buffer_info->page);
|
||||||
rx_buffer_info->page = NULL;
|
rx_buffer_info->page = NULL;
|
||||||
rx_buffer_info->page_offset = 0;
|
rx_buffer_info->page_offset = 0;
|
||||||
|
|
Loading…
Reference in New Issue