]>
Commit | Line | Data |
---|---|---|
745b9103 GKH |
1 | From foo@baz Wed Apr 29 12:00:18 CEST 2015 |
2 | From: Eric Dumazet <edumazet@google.com> | |
3 | Date: Wed, 22 Apr 2015 07:33:36 -0700 | |
4 | Subject: net: do not deplete pfmemalloc reserve | |
5 | ||
6 | From: Eric Dumazet <edumazet@google.com> | |
7 | ||
8 | [ Upstream commit 79930f5892e134c6da1254389577fffb8bd72c66 ] | |
9 | ||
10 | build_skb() should look at the page pfmemalloc status. | |
11 | If set, this means page allocator allocated this page in the | |
12 | expectation it would help to free other pages. Networking | |
13 | stack can do that only if skb->pfmemalloc is also set. | |
14 | ||
15 | Also, we must refrain using high order pages from the pfmemalloc | |
16 | reserve, so __page_frag_refill() must also use __GFP_NOMEMALLOC for | |
17 | them. Under memory pressure, using order-0 pages is probably the best | |
18 | strategy. | |
19 | ||
20 | Signed-off-by: Eric Dumazet <edumazet@google.com> | |
21 | Signed-off-by: David S. Miller <davem@davemloft.net> | |
22 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
23 | --- | |
24 | net/core/skbuff.c | 9 +++++++-- | |
25 | 1 file changed, 7 insertions(+), 2 deletions(-) | |
26 | ||
27 | --- a/net/core/skbuff.c | |
28 | +++ b/net/core/skbuff.c | |
29 | @@ -309,7 +309,11 @@ struct sk_buff *build_skb(void *data, un | |
30 | ||
31 | memset(skb, 0, offsetof(struct sk_buff, tail)); | |
32 | skb->truesize = SKB_TRUESIZE(size); | |
33 | - skb->head_frag = frag_size != 0; | |
34 | + if (frag_size) { | |
35 | + skb->head_frag = 1; | |
36 | + if (virt_to_head_page(data)->pfmemalloc) | |
37 | + skb->pfmemalloc = 1; | |
38 | + } | |
39 | atomic_set(&skb->users, 1); | |
40 | skb->head = data; | |
41 | skb->data = data; | |
42 | @@ -346,7 +350,8 @@ static struct page *__page_frag_refill(s | |
43 | gfp_t gfp = gfp_mask; | |
44 | ||
45 | if (order) { | |
46 | - gfp_mask |= __GFP_COMP | __GFP_NOWARN | __GFP_NORETRY; | |
47 | + gfp_mask |= __GFP_COMP | __GFP_NOWARN | __GFP_NORETRY | | |
48 | + __GFP_NOMEMALLOC; | |
49 | page = alloc_pages_node(NUMA_NO_NODE, gfp_mask, order); | |
50 | nc->frag.size = PAGE_SIZE << (page ? order : 0); | |
51 | } |