]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/suse-2.6.27.39/patches.suse/SoN-17-net-ps_rx.patch
Imported linux-2.6.27.39 suse/xen patches.
[ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.suse / SoN-17-net-ps_rx.patch
CommitLineData
2cb7cef9
BS
1From: Peter Zijlstra <a.p.zijlstra@chello.nl>
2Subject: net: packet split receive api
3Patch-mainline: No
4References: FATE#303834, bnc#484306
5
6Add some packet-split receive hooks.
7
8For one this allows to do NUMA node affine page allocs. Later on these hooks
9will be extended to do emergency reserve allocations for fragments.
10
11Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
12Acked-by: Neil Brown <neilb@suse.de>
13Acked-by: Suresh Jayaraman <sjayaraman@suse.de>
14
15bnx2.c part fixed by Jiri Bohac <jbohac@suse.cz> (bnc#484306)
16
17
18
19---
20 drivers/net/bnx2.c | 9 +++------
21 drivers/net/e1000/e1000_main.c | 8 ++------
22 drivers/net/e1000e/netdev.c | 7 ++-----
23 drivers/net/igb/igb_main.c | 9 ++-------
24 drivers/net/ixgbe/ixgbe_main.c | 14 ++++++--------
25 drivers/net/sky2.c | 16 ++++++----------
26 include/linux/skbuff.h | 23 +++++++++++++++++++++++
27 net/core/skbuff.c | 20 ++++++++++++++++++++
28 8 files changed, 64 insertions(+), 42 deletions(-)
29
30--- a/drivers/net/bnx2.c
31+++ b/drivers/net/bnx2.c
32@@ -2476,7 +2476,7 @@ bnx2_alloc_rx_page(struct bnx2 *bp, stru
33 struct sw_pg *rx_pg = &rxr->rx_pg_ring[index];
34 struct rx_bd *rxbd =
35 &rxr->rx_pg_desc_ring[RX_RING(index)][RX_IDX(index)];
36- struct page *page = alloc_page(GFP_ATOMIC);
37+ struct page *page = netdev_alloc_page(bp->dev);
38
39 if (!page)
40 return -ENOMEM;
41@@ -2501,7 +2501,7 @@ bnx2_free_rx_page(struct bnx2 *bp, struc
42 pci_unmap_page(bp->pdev, pci_unmap_addr(rx_pg, mapping), PAGE_SIZE,
43 PCI_DMA_FROMDEVICE);
44
45- __free_page(page);
46+ netdev_free_page(bp->dev, page);
47 rx_pg->page = NULL;
48 }
49
50@@ -2819,7 +2819,7 @@ bnx2_rx_skb(struct bnx2 *bp, struct bnx2
51 if (i == pages - 1)
52 frag_len -= 4;
53
54- skb_fill_page_desc(skb, i, rx_pg->page, 0, frag_len);
55+ skb_add_rx_frag(skb, i, rx_pg->page, 0, frag_len);
56 rx_pg->page = NULL;
57
58 err = bnx2_alloc_rx_page(bp, rxr,
59@@ -2833,9 +2833,6 @@ bnx2_rx_skb(struct bnx2 *bp, struct bnx2
60 }
61
62 frag_size -= frag_len;
63- skb->data_len += frag_len;
64- skb->truesize += frag_len;
65- skb->len += frag_len;
66
67 pg_prod = NEXT_RX_BD(pg_prod);
68 pg_cons = RX_PG_RING_IDX(NEXT_RX_BD(pg_cons));
69--- a/drivers/net/e1000/e1000_main.c
70+++ b/drivers/net/e1000/e1000_main.c
71@@ -4349,12 +4349,8 @@ static bool e1000_clean_rx_irq_ps(struct
72 pci_unmap_page(pdev, ps_page_dma->ps_page_dma[j],
73 PAGE_SIZE, PCI_DMA_FROMDEVICE);
74 ps_page_dma->ps_page_dma[j] = 0;
75- skb_fill_page_desc(skb, j, ps_page->ps_page[j], 0,
76- length);
77+ skb_add_rx_frag(skb, j, ps_page->ps_page[j], 0, length);
78 ps_page->ps_page[j] = NULL;
79- skb->len += length;
80- skb->data_len += length;
81- skb->truesize += length;
82 }
83
84 /* strip the ethernet crc, problem is we're using pages now so
85@@ -4553,7 +4549,7 @@ static void e1000_alloc_rx_buffers_ps(st
86 if (j < adapter->rx_ps_pages) {
87 if (likely(!ps_page->ps_page[j])) {
88 ps_page->ps_page[j] =
89- alloc_page(GFP_ATOMIC);
90+ netdev_alloc_page(netdev);
91 if (unlikely(!ps_page->ps_page[j])) {
92 adapter->alloc_rx_buff_failed++;
93 goto no_buffers;
94--- a/drivers/net/e1000e/netdev.c
95+++ b/drivers/net/e1000e/netdev.c
96@@ -258,7 +258,7 @@ static void e1000_alloc_rx_buffers_ps(st
97 continue;
98 }
99 if (!ps_page->page) {
100- ps_page->page = alloc_page(GFP_ATOMIC);
101+ ps_page->page = netdev_alloc_page(netdev);
102 if (!ps_page->page) {
103 adapter->alloc_rx_buff_failed++;
104 goto no_buffers;
105@@ -826,11 +826,8 @@ static bool e1000_clean_rx_irq_ps(struct
106 pci_unmap_page(pdev, ps_page->dma, PAGE_SIZE,
107 PCI_DMA_FROMDEVICE);
108 ps_page->dma = 0;
109- skb_fill_page_desc(skb, j, ps_page->page, 0, length);
110+ skb_add_rx_frag(skb, j, ps_page->page, 0, length);
111 ps_page->page = NULL;
112- skb->len += length;
113- skb->data_len += length;
114- skb->truesize += length;
115 }
116
117 /* strip the ethernet crc, problem is we're using pages now so
118--- a/drivers/net/igb/igb_main.c
119+++ b/drivers/net/igb/igb_main.c
120@@ -3885,7 +3885,7 @@ static bool igb_clean_rx_irq_adv(struct
121 PAGE_SIZE / 2, PCI_DMA_FROMDEVICE);
122 buffer_info->page_dma = 0;
123
124- skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags++,
125+ skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags++,
126 buffer_info->page,
127 buffer_info->page_offset,
128 length);
129@@ -3895,11 +3895,6 @@ static bool igb_clean_rx_irq_adv(struct
130 buffer_info->page = NULL;
131 else
132 get_page(buffer_info->page);
133-
134- skb->len += length;
135- skb->data_len += length;
136-
137- skb->truesize += length;
138 }
139 send_up:
140 i++;
141@@ -3993,7 +3988,7 @@ static void igb_alloc_rx_buffers_adv(str
142
143 if (adapter->rx_ps_hdr_size && !buffer_info->page_dma) {
144 if (!buffer_info->page) {
145- buffer_info->page = alloc_page(GFP_ATOMIC);
146+ buffer_info->page = netdev_alloc_page(netdev);
147 if (!buffer_info->page) {
148 adapter->alloc_rx_buff_failed++;
149 goto no_buffers;
150--- a/drivers/net/ixgbe/ixgbe_main.c
151+++ b/drivers/net/ixgbe/ixgbe_main.c
152@@ -480,6 +480,7 @@ static void ixgbe_alloc_rx_buffers(struc
153 int cleaned_count)
154 {
155 struct pci_dev *pdev = adapter->pdev;
156+ struct net_device *netdev = adapter->netdev;
157 union ixgbe_adv_rx_desc *rx_desc;
158 struct ixgbe_rx_buffer *bi;
159 unsigned int i;
160@@ -494,7 +495,7 @@ static void ixgbe_alloc_rx_buffers(struc
161 if (!bi->page_dma &&
162 (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED)) {
163 if (!bi->page) {
164- bi->page = alloc_page(GFP_ATOMIC);
165+ bi->page = netdev_alloc_page(netdev);
166 if (!bi->page) {
167 adapter->alloc_rx_page_failed++;
168 goto no_buffers;
169@@ -628,10 +629,10 @@ static bool ixgbe_clean_rx_irq(struct ix
170 pci_unmap_page(pdev, rx_buffer_info->page_dma,
171 PAGE_SIZE / 2, PCI_DMA_FROMDEVICE);
172 rx_buffer_info->page_dma = 0;
173- skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags,
174- rx_buffer_info->page,
175- rx_buffer_info->page_offset,
176- upper_len);
177+ skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
178+ rx_buffer_info->page,
179+ rx_buffer_info->page_offset,
180+ upper_len);
181
182 if ((rx_ring->rx_buf_len > (PAGE_SIZE / 2)) ||
183 (page_count(rx_buffer_info->page) != 1))
184@@ -639,9 +640,6 @@ static bool ixgbe_clean_rx_irq(struct ix
185 else
186 get_page(rx_buffer_info->page);
187
188- skb->len += upper_len;
189- skb->data_len += upper_len;
190- skb->truesize += upper_len;
191 }
192
193 i++;
194--- a/drivers/net/sky2.c
195+++ b/drivers/net/sky2.c
196@@ -1272,7 +1272,7 @@ static struct sk_buff *sky2_rx_alloc(str
197 }
198
199 for (i = 0; i < sky2->rx_nfrags; i++) {
200- struct page *page = alloc_page(GFP_ATOMIC);
201+ struct page *page = netdev_alloc_page(sky2->netdev);
202
203 if (!page)
204 goto free_partial;
205@@ -2141,8 +2141,8 @@ static struct sk_buff *receive_copy(stru
206 }
207
208 /* Adjust length of skb with fragments to match received data */
209-static void skb_put_frags(struct sk_buff *skb, unsigned int hdr_space,
210- unsigned int length)
211+static void skb_put_frags(struct sky2_port *sky2, struct sk_buff *skb,
212+ unsigned int hdr_space, unsigned int length)
213 {
214 int i, num_frags;
215 unsigned int size;
216@@ -2159,15 +2159,11 @@ static void skb_put_frags(struct sk_buff
217
218 if (length == 0) {
219 /* don't need this page */
220- __free_page(frag->page);
221+ netdev_free_page(sky2->netdev, frag->page);
222 --skb_shinfo(skb)->nr_frags;
223 } else {
224 size = min(length, (unsigned) PAGE_SIZE);
225-
226- frag->size = size;
227- skb->data_len += size;
228- skb->truesize += size;
229- skb->len += size;
230+ skb_add_rx_frag(skb, i, frag->page, 0, size);
231 length -= size;
232 }
233 }
234@@ -2194,7 +2190,7 @@ static struct sk_buff *receive_new(struc
235 sky2_rx_map_skb(sky2->hw->pdev, re, hdr_space);
236
237 if (skb_shinfo(skb)->nr_frags)
238- skb_put_frags(skb, hdr_space, length);
239+ skb_put_frags(sky2, skb, hdr_space, length);
240 else
241 skb_put(skb, length);
242 return skb;
243--- a/include/linux/skbuff.h
244+++ b/include/linux/skbuff.h
245@@ -829,6 +829,9 @@ static inline void skb_fill_page_desc(st
246 skb_shinfo(skb)->nr_frags = i + 1;
247 }
248
249+extern void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page,
250+ int off, int size);
251+
252 #define SKB_PAGE_ASSERT(skb) BUG_ON(skb_shinfo(skb)->nr_frags)
253 #define SKB_FRAG_ASSERT(skb) BUG_ON(skb_shinfo(skb)->frag_list)
254 #define SKB_LINEAR_ASSERT(skb) BUG_ON(skb_is_nonlinear(skb))
255@@ -1243,6 +1246,26 @@ static inline struct sk_buff *netdev_all
256 return __netdev_alloc_skb(dev, length, GFP_ATOMIC);
257 }
258
259+extern struct page *__netdev_alloc_page(struct net_device *dev, gfp_t gfp_mask);
260+
261+/**
262+ * netdev_alloc_page - allocate a page for ps-rx on a specific device
263+ * @dev: network device to receive on
264+ *
265+ * Allocate a new page node local to the specified device.
266+ *
267+ * %NULL is returned if there is no free memory.
268+ */
269+static inline struct page *netdev_alloc_page(struct net_device *dev)
270+{
271+ return __netdev_alloc_page(dev, GFP_ATOMIC);
272+}
273+
274+static inline void netdev_free_page(struct net_device *dev, struct page *page)
275+{
276+ __free_page(page);
277+}
278+
279 /**
280 * skb_clone_writable - is the header of a clone writable
281 * @skb: buffer to check
282--- a/net/core/skbuff.c
283+++ b/net/core/skbuff.c
284@@ -259,6 +259,26 @@ struct sk_buff *__netdev_alloc_skb(struc
285 return skb;
286 }
287
288+struct page *__netdev_alloc_page(struct net_device *dev, gfp_t gfp_mask)
289+{
290+ int node = dev->dev.parent ? dev_to_node(dev->dev.parent) : -1;
291+ struct page *page;
292+
293+ page = alloc_pages_node(node, gfp_mask, 0);
294+ return page;
295+}
296+EXPORT_SYMBOL(__netdev_alloc_page);
297+
298+void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, int off,
299+ int size)
300+{
301+ skb_fill_page_desc(skb, i, page, off, size);
302+ skb->len += size;
303+ skb->data_len += size;
304+ skb->truesize += size;
305+}
306+EXPORT_SYMBOL(skb_add_rx_frag);
307+
308 /**
309 * dev_alloc_skb - allocate an skbuff for receiving
310 * @length: length to allocate