Commit 980093eb authored by Jesse Brandeburg's avatar Jesse Brandeburg Committed by Jeff Kirsher

i40e/i40evf: fix TSO accounting

The TSO logic in the transmit path had some assumptions that
have been broken now that the kernel can send as much as 32kB
in a single skb->frag[.] entry, even on a system with 4kB pages.

This fixes the assumptions and allows the kernel to operate
as efficiently as possible with both SENDFILE and SEND.

In addition, the hardware limit of data contained in a descriptor is
changed to the next power of two below where it currently is in
order to align to a power of two value, preventing a single byte
of data in a descriptor.

Change-ID: I6af1f0b87c1458e10644dbd47541591075a52651
Signed-off-by: default avatarJesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent 63158f91
...@@ -2170,9 +2170,7 @@ static int i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size) ...@@ -2170,9 +2170,7 @@ static int i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size)
static int i40e_xmit_descriptor_count(struct sk_buff *skb, static int i40e_xmit_descriptor_count(struct sk_buff *skb,
struct i40e_ring *tx_ring) struct i40e_ring *tx_ring)
{ {
#if PAGE_SIZE > I40E_MAX_DATA_PER_TXD
unsigned int f; unsigned int f;
#endif
int count = 0; int count = 0;
/* need: 1 descriptor per page * PAGE_SIZE/I40E_MAX_DATA_PER_TXD, /* need: 1 descriptor per page * PAGE_SIZE/I40E_MAX_DATA_PER_TXD,
...@@ -2181,12 +2179,9 @@ static int i40e_xmit_descriptor_count(struct sk_buff *skb, ...@@ -2181,12 +2179,9 @@ static int i40e_xmit_descriptor_count(struct sk_buff *skb,
* + 1 desc for context descriptor, * + 1 desc for context descriptor,
* otherwise try next time * otherwise try next time
*/ */
#if PAGE_SIZE > I40E_MAX_DATA_PER_TXD
for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) for (f = 0; f < skb_shinfo(skb)->nr_frags; f++)
count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size); count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size);
#else
count += skb_shinfo(skb)->nr_frags;
#endif
count += TXD_USE_COUNT(skb_headlen(skb)); count += TXD_USE_COUNT(skb_headlen(skb));
if (i40e_maybe_stop_tx(tx_ring, count + 4 + 1)) { if (i40e_maybe_stop_tx(tx_ring, count + 4 + 1)) {
tx_ring->tx_stats.tx_busy++; tx_ring->tx_stats.tx_busy++;
......
...@@ -117,11 +117,11 @@ enum i40e_dyn_idx_t { ...@@ -117,11 +117,11 @@ enum i40e_dyn_idx_t {
#define i40e_rx_desc i40e_32byte_rx_desc #define i40e_rx_desc i40e_32byte_rx_desc
#define I40E_MIN_TX_LEN 17 #define I40E_MIN_TX_LEN 17
#define I40E_MAX_DATA_PER_TXD 16383 /* aka 16kB - 1 */ #define I40E_MAX_DATA_PER_TXD 8192
/* Tx Descriptors needed, worst case */ /* Tx Descriptors needed, worst case */
#define TXD_USE_COUNT(S) DIV_ROUND_UP((S), I40E_MAX_DATA_PER_TXD) #define TXD_USE_COUNT(S) DIV_ROUND_UP((S), I40E_MAX_DATA_PER_TXD)
#define DESC_NEEDED ((MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE)) + 4) #define DESC_NEEDED (MAX_SKB_FRAGS + 4)
#define I40E_TX_FLAGS_CSUM (u32)(1) #define I40E_TX_FLAGS_CSUM (u32)(1)
#define I40E_TX_FLAGS_HW_VLAN (u32)(1 << 1) #define I40E_TX_FLAGS_HW_VLAN (u32)(1 << 1)
......
...@@ -1511,9 +1511,7 @@ static int i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size) ...@@ -1511,9 +1511,7 @@ static int i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size)
static int i40e_xmit_descriptor_count(struct sk_buff *skb, static int i40e_xmit_descriptor_count(struct sk_buff *skb,
struct i40e_ring *tx_ring) struct i40e_ring *tx_ring)
{ {
#if PAGE_SIZE > I40E_MAX_DATA_PER_TXD
unsigned int f; unsigned int f;
#endif
int count = 0; int count = 0;
/* need: 1 descriptor per page * PAGE_SIZE/I40E_MAX_DATA_PER_TXD, /* need: 1 descriptor per page * PAGE_SIZE/I40E_MAX_DATA_PER_TXD,
...@@ -1522,12 +1520,9 @@ static int i40e_xmit_descriptor_count(struct sk_buff *skb, ...@@ -1522,12 +1520,9 @@ static int i40e_xmit_descriptor_count(struct sk_buff *skb,
* + 1 desc for context descriptor, * + 1 desc for context descriptor,
* otherwise try next time * otherwise try next time
*/ */
#if PAGE_SIZE > I40E_MAX_DATA_PER_TXD
for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) for (f = 0; f < skb_shinfo(skb)->nr_frags; f++)
count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size); count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size);
#else
count += skb_shinfo(skb)->nr_frags;
#endif
count += TXD_USE_COUNT(skb_headlen(skb)); count += TXD_USE_COUNT(skb_headlen(skb));
if (i40e_maybe_stop_tx(tx_ring, count + 4 + 1)) { if (i40e_maybe_stop_tx(tx_ring, count + 4 + 1)) {
tx_ring->tx_stats.tx_busy++; tx_ring->tx_stats.tx_busy++;
......
...@@ -117,11 +117,11 @@ enum i40e_dyn_idx_t { ...@@ -117,11 +117,11 @@ enum i40e_dyn_idx_t {
#define i40e_rx_desc i40e_32byte_rx_desc #define i40e_rx_desc i40e_32byte_rx_desc
#define I40E_MIN_TX_LEN 17 #define I40E_MIN_TX_LEN 17
#define I40E_MAX_DATA_PER_TXD 16383 /* aka 16kB - 1 */ #define I40E_MAX_DATA_PER_TXD 8192
/* Tx Descriptors needed, worst case */ /* Tx Descriptors needed, worst case */
#define TXD_USE_COUNT(S) DIV_ROUND_UP((S), I40E_MAX_DATA_PER_TXD) #define TXD_USE_COUNT(S) DIV_ROUND_UP((S), I40E_MAX_DATA_PER_TXD)
#define DESC_NEEDED ((MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE)) + 4) #define DESC_NEEDED (MAX_SKB_FRAGS + 4)
#define I40E_TX_FLAGS_CSUM (u32)(1) #define I40E_TX_FLAGS_CSUM (u32)(1)
#define I40E_TX_FLAGS_HW_VLAN (u32)(1 << 1) #define I40E_TX_FLAGS_HW_VLAN (u32)(1 << 1)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment