Skip to content

Commit

Permalink
ixgb: Fix early TSO completion
Browse files Browse the repository at this point in the history
This fix was already merged in commit 96f9c2e
but reverted in commit 989316d. After
stresstesting we found that the fix does not add new regressions and
works around a TX hang spotted by several users.

Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
  • Loading branch information
Jesse Brandeburg authored and Auke Kok committed Jan 6, 2007
1 parent 81f4e6c commit 5d92785
Showing 1 changed file with 16 additions and 2 deletions.
18 changes: 16 additions & 2 deletions drivers/net/ixgb/ixgb_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1287,6 +1287,7 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb,
struct ixgb_buffer *buffer_info;
int len = skb->len;
unsigned int offset = 0, size, count = 0, i;
unsigned int mss = skb_shinfo(skb)->gso_size;

unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
unsigned int f;
Expand All @@ -1298,6 +1299,11 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb,
while(len) {
buffer_info = &tx_ring->buffer_info[i];
size = min(len, IXGB_MAX_DATA_PER_TXD);
/* Workaround for premature desc write-backs
* in TSO mode. Append 4-byte sentinel desc */
if (unlikely(mss && !nr_frags && size == len && size > 8))
size -= 4;

buffer_info->length = size;
WARN_ON(buffer_info->dma != 0);
buffer_info->dma =
Expand All @@ -1324,6 +1330,13 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb,
while(len) {
buffer_info = &tx_ring->buffer_info[i];
size = min(len, IXGB_MAX_DATA_PER_TXD);

/* Workaround for premature desc write-backs
* in TSO mode. Append 4-byte sentinel desc */
if (unlikely(mss && !nr_frags && size == len
&& size > 8))
size -= 4;

buffer_info->length = size;
buffer_info->dma =
pci_map_page(adapter->pdev,
Expand Down Expand Up @@ -1401,8 +1414,9 @@ ixgb_tx_queue(struct ixgb_adapter *adapter, int count, int vlan_id,int tx_flags)
/* Tx Descriptors needed, worst case */
#define TXD_USE_COUNT(S) (((S) >> IXGB_MAX_TXD_PWR) + \
(((S) & (IXGB_MAX_DATA_PER_TXD - 1)) ? 1 : 0))
#define DESC_NEEDED TXD_USE_COUNT(IXGB_MAX_DATA_PER_TXD) + \
MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1
#define DESC_NEEDED TXD_USE_COUNT(IXGB_MAX_DATA_PER_TXD) /* skb->date */ + \
MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1 /* for context */ \
+ 1 /* one more needed for sentinel TSO workaround */

static int
ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
Expand Down

0 comments on commit 5d92785

Please sign in to comment.