diff options
author | Alexander Duyck <alexander.h.duyck@intel.com> | 2012-09-24 20:30:52 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2012-10-19 07:27:30 -0400 |
commit | 1a1c225b9463038ac68b369ef05e4ee7fd9c82a5 (patch) | |
tree | dc79d408e1e8bdc756315b3ded1d2097e298015e /drivers/net/ethernet/intel/igb/igb_ethtool.c | |
parent | b534550a17cda69a1d62acc18fff33370b5eee5b (diff) |
igb: Do not use header split, instead receive all frames into a single buffer
This change makes it so that we no longer use header split. The idea is to
reduce partial cache line writes by hardware when handling frames larger
then header size. We can compensate for the extra overhead of having to
memcpy the header buffer by avoiding the cache misses seen by leaving an
full skb allocated and sitting on the ring.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/igb/igb_ethtool.c')
-rw-r--r-- | drivers/net/ethernet/intel/igb/igb_ethtool.c | 31 |
1 files changed, 20 insertions, 11 deletions
diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c index 2ea012849825..0faac423bd5b 100644 --- a/drivers/net/ethernet/intel/igb/igb_ethtool.c +++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/sched.h> | 37 | #include <linux/sched.h> |
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | #include <linux/pm_runtime.h> | 39 | #include <linux/pm_runtime.h> |
40 | #include <linux/highmem.h> | ||
40 | 41 | ||
41 | #include "igb.h" | 42 | #include "igb.h" |
42 | 43 | ||
@@ -1685,16 +1686,24 @@ static void igb_create_lbtest_frame(struct sk_buff *skb, | |||
1685 | memset(&skb->data[frame_size + 12], 0xAF, 1); | 1686 | memset(&skb->data[frame_size + 12], 0xAF, 1); |
1686 | } | 1687 | } |
1687 | 1688 | ||
1688 | static int igb_check_lbtest_frame(struct sk_buff *skb, unsigned int frame_size) | 1689 | static int igb_check_lbtest_frame(struct igb_rx_buffer *rx_buffer, |
1690 | unsigned int frame_size) | ||
1689 | { | 1691 | { |
1690 | frame_size /= 2; | 1692 | unsigned char *data; |
1691 | if (*(skb->data + 3) == 0xFF) { | 1693 | bool match = true; |
1692 | if ((*(skb->data + frame_size + 10) == 0xBE) && | 1694 | |
1693 | (*(skb->data + frame_size + 12) == 0xAF)) { | 1695 | frame_size >>= 1; |
1694 | return 0; | 1696 | |
1695 | } | 1697 | data = kmap(rx_buffer->page) + rx_buffer->page_offset; |
1696 | } | 1698 | |
1697 | return 13; | 1699 | if (data[3] != 0xFF || |
1700 | data[frame_size + 10] != 0xBE || | ||
1701 | data[frame_size + 12] != 0xAF) | ||
1702 | match = false; | ||
1703 | |||
1704 | kunmap(rx_buffer->page); | ||
1705 | |||
1706 | return match; | ||
1698 | } | 1707 | } |
1699 | 1708 | ||
1700 | static int igb_clean_test_rings(struct igb_ring *rx_ring, | 1709 | static int igb_clean_test_rings(struct igb_ring *rx_ring, |
@@ -1720,12 +1729,12 @@ static int igb_clean_test_rings(struct igb_ring *rx_ring, | |||
1720 | /* unmap rx buffer, will be remapped by alloc_rx_buffers */ | 1729 | /* unmap rx buffer, will be remapped by alloc_rx_buffers */ |
1721 | dma_unmap_single(rx_ring->dev, | 1730 | dma_unmap_single(rx_ring->dev, |
1722 | rx_buffer_info->dma, | 1731 | rx_buffer_info->dma, |
1723 | IGB_RX_HDR_LEN, | 1732 | PAGE_SIZE / 2, |
1724 | DMA_FROM_DEVICE); | 1733 | DMA_FROM_DEVICE); |
1725 | rx_buffer_info->dma = 0; | 1734 | rx_buffer_info->dma = 0; |
1726 | 1735 | ||
1727 | /* verify contents of skb */ | 1736 | /* verify contents of skb */ |
1728 | if (!igb_check_lbtest_frame(rx_buffer_info->skb, size)) | 1737 | if (igb_check_lbtest_frame(rx_buffer_info, size)) |
1729 | count++; | 1738 | count++; |
1730 | 1739 | ||
1731 | /* unmap buffer on tx side */ | 1740 | /* unmap buffer on tx side */ |