diff options
Diffstat (limited to 'drivers/net/ethernet/sfc/rx.c')
-rw-r--r-- | drivers/net/ethernet/sfc/rx.c | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c index 42488df1f4ec..48588ddf81b0 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c @@ -149,7 +149,7 @@ static struct page *efx_reuse_page(struct efx_rx_queue *rx_queue) * 0 on success. If a single page can be used for multiple buffers, * then the page will either be inserted fully, or not at all. */ -static int efx_init_rx_buffers(struct efx_rx_queue *rx_queue) +static int efx_init_rx_buffers(struct efx_rx_queue *rx_queue, bool atomic) { struct efx_nic *efx = rx_queue->efx; struct efx_rx_buffer *rx_buf; @@ -163,7 +163,8 @@ static int efx_init_rx_buffers(struct efx_rx_queue *rx_queue) do { page = efx_reuse_page(rx_queue); if (page == NULL) { - page = alloc_pages(__GFP_COLD | __GFP_COMP | GFP_ATOMIC, + page = alloc_pages(__GFP_COLD | __GFP_COMP | + (atomic ? GFP_ATOMIC : GFP_KERNEL), efx->rx_buffer_order); if (unlikely(page == NULL)) return -ENOMEM; @@ -321,7 +322,7 @@ static void efx_discard_rx_packet(struct efx_channel *channel, * this means this function must run from the NAPI handler, or be called * when NAPI is disabled. */ -void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue) +void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue, bool atomic) { struct efx_nic *efx = rx_queue->efx; unsigned int fill_level, batch_size; @@ -354,7 +355,7 @@ void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue) do { - rc = efx_init_rx_buffers(rx_queue); + rc = efx_init_rx_buffers(rx_queue, atomic); if (unlikely(rc)) { /* Ensure that we don't leave the rx queue empty */ if (rx_queue->added_count == rx_queue->removed_count) @@ -439,7 +440,8 @@ efx_rx_packet_gro(struct efx_channel *channel, struct efx_rx_buffer *rx_buf, } if (efx->net_dev->features & NETIF_F_RXHASH) - skb->rxhash = efx_rx_buf_hash(efx, eh); + skb_set_hash(skb, efx_rx_buf_hash(efx, eh), + PKT_HASH_TYPE_L3); skb->ip_summed = ((rx_buf->flags & EFX_RX_PKT_CSUMMED) ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE); @@ -475,14 +477,18 @@ static struct sk_buff *efx_rx_mk_skb(struct efx_channel *channel, struct sk_buff *skb; /* Allocate an SKB to store the headers */ - skb = netdev_alloc_skb(efx->net_dev, hdr_len + EFX_PAGE_SKB_ALIGN); + skb = netdev_alloc_skb(efx->net_dev, + efx->rx_ip_align + efx->rx_prefix_size + + hdr_len); if (unlikely(skb == NULL)) return NULL; EFX_BUG_ON_PARANOID(rx_buf->len < hdr_len); - skb_reserve(skb, EFX_PAGE_SKB_ALIGN); - memcpy(__skb_put(skb, hdr_len), eh, hdr_len); + memcpy(skb->data + efx->rx_ip_align, eh - efx->rx_prefix_size, + efx->rx_prefix_size + hdr_len); + skb_reserve(skb, efx->rx_ip_align + efx->rx_prefix_size); + __skb_put(skb, hdr_len); /* Append the remaining page(s) onto the frag list */ if (rx_buf->len > hdr_len) { @@ -619,6 +625,8 @@ static void efx_rx_deliver(struct efx_channel *channel, u8 *eh, if (likely(rx_buf->flags & EFX_RX_PKT_CSUMMED)) skb->ip_summed = CHECKSUM_UNNECESSARY; + efx_rx_skb_attach_timestamp(channel, skb); + if (channel->type->receive_skb) if (channel->type->receive_skb(channel, skb)) return; |