mirror of https://gitee.com/openkylin/linux.git
e1000e: save skb counts in TX to avoid cache misses
In e1000_tx_map, precompute number of segements and bytecounts which are derived from fields in skb; these are stored in buffer_info. When cleaning tx in e1000_clean_tx_irq use the values in the associated buffer_info for statistics counting, this eliminates cache misses on skb fields. Signed-off-by: Tom Herbert <therbert@google.com> Acked-by: Bruce Allan <bruce.w.allan@intel.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
4447957a82
commit
9ed318d546
|
@ -189,6 +189,8 @@ struct e1000_buffer {
|
||||||
unsigned long time_stamp;
|
unsigned long time_stamp;
|
||||||
u16 length;
|
u16 length;
|
||||||
u16 next_to_watch;
|
u16 next_to_watch;
|
||||||
|
unsigned int segs;
|
||||||
|
unsigned int bytecount;
|
||||||
u16 mapped_as_page;
|
u16 mapped_as_page;
|
||||||
};
|
};
|
||||||
/* Rx */
|
/* Rx */
|
||||||
|
|
|
@ -1001,14 +1001,8 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
|
||||||
cleaned = (i == eop);
|
cleaned = (i == eop);
|
||||||
|
|
||||||
if (cleaned) {
|
if (cleaned) {
|
||||||
struct sk_buff *skb = buffer_info->skb;
|
total_tx_packets += buffer_info->segs;
|
||||||
unsigned int segs, bytecount;
|
total_tx_bytes += buffer_info->bytecount;
|
||||||
segs = skb_shinfo(skb)->gso_segs ?: 1;
|
|
||||||
/* multiply data chunks by size of headers */
|
|
||||||
bytecount = ((segs - 1) * skb_headlen(skb)) +
|
|
||||||
skb->len;
|
|
||||||
total_tx_packets += segs;
|
|
||||||
total_tx_bytes += bytecount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
e1000_put_txbuf(adapter, buffer_info);
|
e1000_put_txbuf(adapter, buffer_info);
|
||||||
|
@ -4261,7 +4255,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
|
||||||
struct e1000_buffer *buffer_info;
|
struct e1000_buffer *buffer_info;
|
||||||
unsigned int len = skb_headlen(skb);
|
unsigned int len = skb_headlen(skb);
|
||||||
unsigned int offset = 0, size, count = 0, i;
|
unsigned int offset = 0, size, count = 0, i;
|
||||||
unsigned int f;
|
unsigned int f, bytecount, segs;
|
||||||
|
|
||||||
i = tx_ring->next_to_use;
|
i = tx_ring->next_to_use;
|
||||||
|
|
||||||
|
@ -4321,7 +4315,13 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
segs = skb_shinfo(skb)->gso_segs ?: 1;
|
||||||
|
/* multiply data chunks by size of headers */
|
||||||
|
bytecount = ((segs - 1) * skb_headlen(skb)) + skb->len;
|
||||||
|
|
||||||
tx_ring->buffer_info[i].skb = skb;
|
tx_ring->buffer_info[i].skb = skb;
|
||||||
|
tx_ring->buffer_info[i].segs = segs;
|
||||||
|
tx_ring->buffer_info[i].bytecount = bytecount;
|
||||||
tx_ring->buffer_info[first].next_to_watch = i;
|
tx_ring->buffer_info[first].next_to_watch = i;
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
|
|
Loading…
Reference in New Issue