You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
qubes-linux-kernel/patches.suse/SoN-13-net-ps_rx.patch

185 lines
5.7 KiB

From: Peter Zijlstra <a.p.zijlstra@chello.nl>
Subject: [PATCH 13/31] net: packet split receive api
Patch-mainline: Not yet
Add some packet-split receive hooks.
For one this allows to do NUMA node affine page allocs. Later on these hooks
will be extended to do emergency reserve allocations for fragments.
Thanks to Jiri Bohac for fixing a bug in bnx2.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Bohac <jbohac@suse.cz>
Signed-off-by: Suresh Jayaraman <sjayaraman@suse.de>
---
drivers/net/bnx2.c | 9 +++------
drivers/net/e1000e/netdev.c | 7 ++-----
drivers/net/igb/igb_main.c | 6 +-----
drivers/net/ixgbe/ixgbe_main.c | 14 ++++++--------
drivers/net/sky2.c | 16 ++++++----------
include/linux/skbuff.h | 3 +++
6 files changed, 21 insertions(+), 34 deletions(-)
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -2676,7 +2676,7 @@ bnx2_alloc_rx_page(struct bnx2 *bp, stru
struct sw_pg *rx_pg = &rxr->rx_pg_ring[index];
struct rx_bd *rxbd =
&rxr->rx_pg_desc_ring[RX_RING(index)][RX_IDX(index)];
- struct page *page = alloc_page(gfp);
+ struct page *page = __netdev_alloc_page(bp->dev, gfp);
if (!page)
return -ENOMEM;
@@ -2706,7 +2706,7 @@ bnx2_free_rx_page(struct bnx2 *bp, struc
dma_unmap_page(&bp->pdev->dev, dma_unmap_addr(rx_pg, mapping),
PAGE_SIZE, PCI_DMA_FROMDEVICE);
- __free_page(page);
+ netdev_free_page(bp->dev, page);
rx_pg->page = NULL;
}
@@ -3041,7 +3041,7 @@ bnx2_rx_skb(struct bnx2 *bp, struct bnx2
if (i == pages - 1)
frag_len -= 4;
- skb_fill_page_desc(skb, i, rx_pg->page, 0, frag_len);
+ skb_add_rx_frag(skb, i, rx_pg->page, 0, frag_len);
rx_pg->page = NULL;
err = bnx2_alloc_rx_page(bp, rxr,
@@ -3059,9 +3059,6 @@ bnx2_rx_skb(struct bnx2 *bp, struct bnx2
PAGE_SIZE, PCI_DMA_FROMDEVICE);
frag_size -= frag_len;
- skb->data_len += frag_len;
- skb->truesize += frag_len;
- skb->len += frag_len;
pg_prod = NEXT_RX_BD(pg_prod);
pg_cons = RX_PG_RING_IDX(NEXT_RX_BD(pg_cons));
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -604,7 +604,7 @@ static void e1000_alloc_rx_buffers_ps(st
continue;
}
if (!ps_page->page) {
- ps_page->page = alloc_page(GFP_ATOMIC);
+ ps_page->page = netdev_alloc_page(netdev);
if (!ps_page->page) {
adapter->alloc_rx_buff_failed++;
goto no_buffers;
@@ -1188,11 +1188,8 @@ static bool e1000_clean_rx_irq_ps(struct
dma_unmap_page(&pdev->dev, ps_page->dma, PAGE_SIZE,
DMA_FROM_DEVICE);
ps_page->dma = 0;
- skb_fill_page_desc(skb, j, ps_page->page, 0, length);
+ skb_add_rx_frag(skb, j, ps_page->page, 0, length);
ps_page->page = NULL;
- skb->len += length;
- skb->data_len += length;
- skb->truesize += length;
}
/* strip the ethernet crc, problem is we're using pages now so
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -5594,7 +5594,7 @@ static bool igb_clean_rx_irq_adv(struct
PAGE_SIZE / 2, DMA_FROM_DEVICE);
buffer_info->page_dma = 0;
- skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags,
+ skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
buffer_info->page,
buffer_info->page_offset,
length);
@@ -5604,10 +5604,6 @@ static bool igb_clean_rx_irq_adv(struct
buffer_info->page = NULL;
else
get_page(buffer_info->page);
-
- skb->len += length;
- skb->data_len += length;
- skb->truesize += length;
}
if (!(staterr & E1000_RXD_STAT_EOP)) {
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -1243,10 +1244,10 @@ static bool ixgbe_clean_rx_irq(struct ix
PAGE_SIZE / 2,
DMA_FROM_DEVICE);
rx_buffer_info->page_dma = 0;
- skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags,
- rx_buffer_info->page,
- rx_buffer_info->page_offset,
- upper_len);
+ skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
+ rx_buffer_info->page,
+ rx_buffer_info->page_offset,
+ upper_len);
if ((page_count(rx_buffer_info->page) == 1) &&
(page_to_nid(rx_buffer_info->page) == current_node))
@@ -1254,9 +1255,6 @@ static bool ixgbe_clean_rx_irq(struct ix
else
rx_buffer_info->page = NULL;
- skb->len += upper_len;
- skb->data_len += upper_len;
- skb->truesize += upper_len;
}
i++;
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -1394,7 +1394,7 @@ static struct sk_buff *sky2_rx_alloc(str
skb_reserve(skb, NET_IP_ALIGN);
for (i = 0; i < sky2->rx_nfrags; i++) {
- struct page *page = alloc_page(GFP_ATOMIC);
+ struct page *page = netdev_alloc_page(sky2->netdev);
if (!page)
goto free_partial;
@@ -2353,8 +2353,8 @@ static struct sk_buff *receive_copy(stru
}
/* Adjust length of skb with fragments to match received data */
-static void skb_put_frags(struct sk_buff *skb, unsigned int hdr_space,
- unsigned int length)
+static void skb_put_frags(struct sky2_port *sky2, struct sk_buff *skb,
+ unsigned int hdr_space, unsigned int length)
{
int i, num_frags;
unsigned int size;
@@ -2371,15 +2371,11 @@ static void skb_put_frags(struct sk_buff
if (length == 0) {
/* don't need this page */
- __free_page(frag->page);
+ netdev_free_page(sky2->netdev, frag->page);
--skb_shinfo(skb)->nr_frags;
} else {
size = min(length, (unsigned) PAGE_SIZE);
-
- frag->size = size;
- skb->data_len += size;
- skb->truesize += size;
- skb->len += size;
+ skb_add_rx_frag(skb, i, frag->page, 0, size);
length -= size;
}
}
@@ -2407,7 +2403,7 @@ static struct sk_buff *receive_new(struc
*re = nre;
if (skb_shinfo(skb)->nr_frags)
- skb_put_frags(skb, hdr_space, length);
+ skb_put_frags(sky2, skb, hdr_space, length);
else
skb_put(skb, length);
return skb;