Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 042a53a9 authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller
Browse files

net: skb_shared_info optimization



skb_dma_unmap() is quite expensive for small packets,
because we use two different cache lines from skb_shared_info.

One to access nr_frags, one to access dma_maps[0]

Instead of dma_maps being an array of MAX_SKB_FRAGS + 1 elements,
let dma_head alone in a new dma_head field, close to nr_frags,
to reduce cache lines misses.

Tested on my dev machine (bnx2 & tg3 adapters), nice speedup !

Signed-off-by: default avatarEric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent eae3f29c
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -5487,7 +5487,7 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode)
		dev_kfree_skb(skb);
		return -EIO;
	}
	map = skb_shinfo(skb)->dma_maps[0];
	map = skb_shinfo(skb)->dma_head;

	REG_WR(bp, BNX2_HC_COMMAND,
	       bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT);
@@ -6167,7 +6167,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
	}

	sp = skb_shinfo(skb);
	mapping = sp->dma_maps[0];
	mapping = sp->dma_head;

	tx_buf = &txr->tx_buf_ring[ring_prod];
	tx_buf->skb = skb;
@@ -6191,7 +6191,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
		txbd = &txr->tx_desc_ring[ring_prod];

		len = frag->size;
		mapping = sp->dma_maps[i + 1];
		mapping = sp->dma_maps[i];

		txbd->tx_bd_haddr_hi = (u64) mapping >> 32;
		txbd->tx_bd_haddr_lo = (u64) mapping & 0xffffffff;
+2 −2
Original line number Diff line number Diff line
@@ -2998,7 +2998,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
			size -= 4;

		buffer_info->length = size;
		buffer_info->dma = map[0] + offset;
		buffer_info->dma = skb_shinfo(skb)->dma_head + offset;
		buffer_info->time_stamp = jiffies;
		buffer_info->next_to_watch = i;

@@ -3039,7 +3039,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
				size -= 4;

			buffer_info->length = size;
			buffer_info->dma = map[f + 1] + offset;
			buffer_info->dma = map[f] + offset;
			buffer_info->time_stamp = jiffies;
			buffer_info->next_to_watch = i;

+2 −2
Original line number Diff line number Diff line
@@ -3916,7 +3916,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
		buffer_info->length = size;
		buffer_info->time_stamp = jiffies;
		buffer_info->next_to_watch = i;
		buffer_info->dma = map[0] + offset;
		buffer_info->dma = skb_shinfo(skb)->dma_head + offset;
		count++;

		len -= size;
@@ -3947,7 +3947,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
			buffer_info->length = size;
			buffer_info->time_stamp = jiffies;
			buffer_info->next_to_watch = i;
			buffer_info->dma = map[f + 1] + offset;
			buffer_info->dma = map[f] + offset;

			len -= size;
			offset += size;
+2 −3
Original line number Diff line number Diff line
@@ -3139,8 +3139,7 @@ static inline int igb_tx_map_adv(struct igb_adapter *adapter,
	/* set time_stamp *before* dma to help avoid a possible race */
	buffer_info->time_stamp = jiffies;
	buffer_info->next_to_watch = i;
	buffer_info->dma = map[count];
	count++;
	buffer_info->dma = skb_shinfo(skb)->dma_head;

	for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) {
		struct skb_frag_struct *frag;
@@ -3164,7 +3163,7 @@ static inline int igb_tx_map_adv(struct igb_adapter *adapter,
	tx_ring->buffer_info[i].skb = skb;
	tx_ring->buffer_info[first].next_to_watch = i;

	return count;
	return count + 1;
}

static inline void igb_tx_queue_adv(struct igb_adapter *adapter,
+2 −3
Original line number Diff line number Diff line
@@ -2119,8 +2119,7 @@ static inline int igbvf_tx_map_adv(struct igbvf_adapter *adapter,
	/* set time_stamp *before* dma to help avoid a possible race */
	buffer_info->time_stamp = jiffies;
	buffer_info->next_to_watch = i;
	buffer_info->dma = map[count];
	count++;
	buffer_info->dma = skb_shinfo(skb)->dma_head;

	for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) {
		struct skb_frag_struct *frag;
@@ -2144,7 +2143,7 @@ static inline int igbvf_tx_map_adv(struct igbvf_adapter *adapter,
	tx_ring->buffer_info[i].skb = skb;
	tx_ring->buffer_info[first].next_to_watch = i;

	return count;
	return count + 1;
}

static inline void igbvf_tx_queue_adv(struct igbvf_adapter *adapter,
Loading