summaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2009-10-29 07:21:24 +0000
committerDavid S. Miller <davem@davemloft.net>2009-10-29 21:37:06 -0700
commit18e1d2beb6c2307d3cab7ecb44fd3d4382adcf6a (patch)
tree4d1279868352923fdf7fcf27176896f4d96d7cb0 /drivers/net/sfc
parentc7c4b3b6e976b95facbb723951bdcd554a3530a4 (diff)
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>
Diffstat (limited to 'drivers/net/sfc')
-rw-r--r--drivers/net/sfc/rx.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c
index 4b65c626a45..9277e9aaad0 100644
--- a/drivers/net/sfc/rx.c
+++ b/drivers/net/sfc/rx.c
@@ -445,6 +445,7 @@ static void efx_rx_packet_lro(struct efx_channel *channel,
bool checksummed)
{
struct napi_struct *napi = &channel->napi_str;
+ gro_result_t gro_result;
/* Pass the skb/page into the LRO engine */
if (rx_buf->page) {
@@ -452,6 +453,7 @@ static void efx_rx_packet_lro(struct efx_channel *channel,
if (!skb) {
put_page(rx_buf->page);
+ gro_result = GRO_DROP;
goto out;
}
@@ -467,7 +469,7 @@ static void efx_rx_packet_lro(struct efx_channel *channel,
skb->ip_summed =
checksummed ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE;
- napi_gro_frags(napi);
+ gro_result = napi_gro_frags(napi);
out:
EFX_BUG_ON_PARANOID(rx_buf->skb);
@@ -476,9 +478,16 @@ out:
EFX_BUG_ON_PARANOID(!rx_buf->skb);
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;
}
+
+ 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,