]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/patches/suse-2.6.27.31/patches.suse/SoN-17-net-ps_rx.patch
Merge branch 'master' of git://git.ipfire.org/ipfire-2.x
[people/teissler/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.suse / SoN-17-net-ps_rx.patch
1 From: Peter Zijlstra <a.p.zijlstra@chello.nl>
2 Subject: net: packet split receive api
3 Patch-mainline: No
4 References: FATE#303834, bnc#484306
5
6 Add some packet-split receive hooks.
7
8 For one this allows to do NUMA node affine page allocs. Later on these hooks
9 will be extended to do emergency reserve allocations for fragments.
10
11 Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
12 Acked-by: Neil Brown <neilb@suse.de>
13 Acked-by: Suresh Jayaraman <sjayaraman@suse.de>
14
15 bnx2.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