浏览代码

sfc: Feed GRO result into RX allocation policy and interrupt moderation

When GRO is successfully merging received packets, we should allocate
raw page buffers rather than skbs that will be discarded by GRO.
Otherwise, we should allocate skbs.

GRO also benefits from higher interrupt moderation, so increase the
score for mergeable RX packets.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Ben Hutchings 16 年之前
父节点
当前提交
18e1d2beb6
共有 1 个文件被更改,包括 11 次插入2 次删除
  1. 11 2
      drivers/net/sfc/rx.c

+ 11 - 2
drivers/net/sfc/rx.c

@@ -445,6 +445,7 @@ static void efx_rx_packet_lro(struct efx_channel *channel,
 			      bool checksummed)
 			      bool checksummed)
 {
 {
 	struct napi_struct *napi = &channel->napi_str;
 	struct napi_struct *napi = &channel->napi_str;
+	gro_result_t gro_result;
 
 
 	/* Pass the skb/page into the LRO engine */
 	/* Pass the skb/page into the LRO engine */
 	if (rx_buf->page) {
 	if (rx_buf->page) {
@@ -452,6 +453,7 @@ static void efx_rx_packet_lro(struct efx_channel *channel,
 
 
 		if (!skb) {
 		if (!skb) {
 			put_page(rx_buf->page);
 			put_page(rx_buf->page);
+			gro_result = GRO_DROP;
 			goto out;
 			goto out;
 		}
 		}
 
 
@@ -467,7 +469,7 @@ static void efx_rx_packet_lro(struct efx_channel *channel,
 		skb->ip_summed =
 		skb->ip_summed =
 			checksummed ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE;
 			checksummed ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE;
 
 
-		napi_gro_frags(napi);
+		gro_result = napi_gro_frags(napi);
 
 
 out:
 out:
 		EFX_BUG_ON_PARANOID(rx_buf->skb);
 		EFX_BUG_ON_PARANOID(rx_buf->skb);
@@ -476,9 +478,16 @@ out:
 		EFX_BUG_ON_PARANOID(!rx_buf->skb);
 		EFX_BUG_ON_PARANOID(!rx_buf->skb);
 		EFX_BUG_ON_PARANOID(!checksummed);
 		EFX_BUG_ON_PARANOID(!checksummed);
 
 
-		napi_gro_receive(napi, rx_buf->skb);
+		gro_result = napi_gro_receive(napi, rx_buf->skb);
 		rx_buf->skb = NULL;
 		rx_buf->skb = NULL;
 	}
 	}
+
+	if (gro_result == GRO_NORMAL) {
+		channel->rx_alloc_level += RX_ALLOC_FACTOR_SKB;
+	} else if (gro_result != GRO_DROP) {
+		channel->rx_alloc_level += RX_ALLOC_FACTOR_LRO;
+		channel->irq_mod_score += 2;
+	}
 }
 }
 
 
 void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
 void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,