Skip to content

Commit d9b2938

Browse files
Eric Dumazetdavem330
authored andcommitted
net: attempt a single high order allocation
In commit ed98df3 ("net: use __GFP_NORETRY for high order allocations") we tried to address one issue caused by order-3 allocations. We still observe high latencies and system overhead in situations where compaction is not successful. Instead of trying order-3, order-2, and order-1, do a single order-3 best effort and immediately fallback to plain order-0. This mimics slub strategy to fallback to slab min order if the high order allocation used for performance failed. Order-3 allocations give a performance boost only if they can be done without recurring and expensive memory scan. Quoting David : The page allocator relies on synchronous (sync light) memory compaction after direct reclaim for allocations that don't retry and deferred compaction doesn't work with this strategy because the allocation order is always decreasing from the previous failed attempt. This means sync light compaction will always be encountered if memory cannot be defragmented or reclaimed several times during the skb_page_frag_refill() iteration. Signed-off-by: Eric Dumazet <edumazet@google.com> Acked-by: David Rientjes <rientjes@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent bcc7354 commit d9b2938

File tree

1 file changed

+16
-14
lines changed

1 file changed

+16
-14
lines changed

net/core/sock.c

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1822,6 +1822,9 @@ struct sk_buff *sock_alloc_send_pskb(struct sock *sk, unsigned long header_len,
18221822
order);
18231823
if (page)
18241824
goto fill_page;
1825+
/* Do not retry other high order allocations */
1826+
order = 1;
1827+
max_page_order = 0;
18251828
}
18261829
order--;
18271830
}
@@ -1869,10 +1872,8 @@ EXPORT_SYMBOL(sock_alloc_send_skb);
18691872
* no guarantee that allocations succeed. Therefore, @sz MUST be
18701873
* less or equal than PAGE_SIZE.
18711874
*/
1872-
bool skb_page_frag_refill(unsigned int sz, struct page_frag *pfrag, gfp_t prio)
1875+
bool skb_page_frag_refill(unsigned int sz, struct page_frag *pfrag, gfp_t gfp)
18731876
{
1874-
int order;
1875-
18761877
if (pfrag->page) {
18771878
if (atomic_read(&pfrag->page->_count) == 1) {
18781879
pfrag->offset = 0;
@@ -1883,20 +1884,21 @@ bool skb_page_frag_refill(unsigned int sz, struct page_frag *pfrag, gfp_t prio)
18831884
put_page(pfrag->page);
18841885
}
18851886

1886-
order = SKB_FRAG_PAGE_ORDER;
1887-
do {
1888-
gfp_t gfp = prio;
1889-
1890-
if (order)
1891-
gfp |= __GFP_COMP | __GFP_NOWARN | __GFP_NORETRY;
1892-
pfrag->page = alloc_pages(gfp, order);
1887+
pfrag->offset = 0;
1888+
if (SKB_FRAG_PAGE_ORDER) {
1889+
pfrag->page = alloc_pages(gfp | __GFP_COMP |
1890+
__GFP_NOWARN | __GFP_NORETRY,
1891+
SKB_FRAG_PAGE_ORDER);
18931892
if (likely(pfrag->page)) {
1894-
pfrag->offset = 0;
1895-
pfrag->size = PAGE_SIZE << order;
1893+
pfrag->size = PAGE_SIZE << SKB_FRAG_PAGE_ORDER;
18961894
return true;
18971895
}
1898-
} while (--order >= 0);
1899-
1896+
}
1897+
pfrag->page = alloc_page(gfp);
1898+
if (likely(pfrag->page)) {
1899+
pfrag->size = PAGE_SIZE;
1900+
return true;
1901+
}
19001902
return false;
19011903
}
19021904
EXPORT_SYMBOL(skb_page_frag_refill);

0 commit comments

Comments
 (0)