[Devel] [PATCH RHEL9 COMMIT] net/skbuff: Don't waste memory reserves

Konstantin Khorenko khorenko at virtuozzo.com
Wed Oct 20 11:40:35 MSK 2021


The commit is pushed to "branch-rh9-5.14.vz9.1.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh9-5.14.0-4.vz9.10.12
------>
commit 4ef13e7ff5a8af2ea85ee125439e3b4a231279cf
Author: Andrey Ryabinin <ryabinin.a.a at gmail.com>
Date:   Wed Oct 20 11:40:34 2021 +0300

    net/skbuff: Don't waste memory reserves
    
    We were observing network performance issues due to packets
    being dropped by sk_filter_trim_cap() since the 'skb' was allocated
    from pfmemalloc reserves:
    
        /*
         * If the skb was allocated from pfmemalloc reserves, only
         * allow SOCK_MEMALLOC sockets to use it as this socket is
         * helping free memory
         */
        if (skb_pfmemalloc(skb) && !sock_flag(sk, SOCK_MEMALLOC))
            return -ENOMEM;
    
    Memalloc sockets are used for stuff like swap over NBD or NFS
    and only memalloc sockets can process memalloc skbs. Since we
    don't have any memalloc sockets in our setups we shouldn't have
    memalloc skbs either. It simply doesn't make any sense to waste
    memory reserves on skb only to drop packets later.
    
    It appears that __dev_alloc_pages() unconditionally uses
    __GFP_MEMALLOC, so unless caller added __GFP_NOMEMALLOC, the
    __dev_alloc_pages() may dive into memory reserves.
    Later build_skb() or __skb_fill_page_desc() sets skb->pfmemalloc = 1
    so this skb always dropped by sk_filter_trim_cap().
    
    Instead of wasting memory reserves we should simply avoid using
    them in case of absence memalloc sockets in the system. Do this
    by adding __GFP_MEMALLOC only when such socket is present in the
    system.
    
    https://pmc.acronis.com/browse/VSTOR-21390
    Signed-off-by: Andrey Ryabinin <aryabinin at virtuozzo.com>
    
    Cherry-picked from vz7 commit a6b8d2a78d83 ("net/skbuff: Don't waste memory
    reserves")
    
    Ported to VZ8 in scope of https://jira.sw.ru/browse/PSBM-127844.
    Signed-off-by: Evgenii Shatokhin <eshatokhin at virtuozzo.com>
    
    (cherry picked from vz8 commit 4253f1e95a73d4fcb10d56e199a0ee27b129d910)
    Signed-off-by: Andrey Zhadchenko <andrey.zhadchenko at virtuozzo.com>
---
 include/linux/skbuff.h | 19 ++++++++++++++++++-
 include/net/sock.h     | 12 ------------
 2 files changed, 18 insertions(+), 13 deletions(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index b2db9cd9a73f..03da2d239c28 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -2933,6 +2933,21 @@ void napi_consume_skb(struct sk_buff *skb, int budget);
 void napi_skb_free_stolen_head(struct sk_buff *skb);
 void __kfree_skb_defer(struct sk_buff *skb);
 
+#ifdef CONFIG_NET
+DECLARE_STATIC_KEY_FALSE(memalloc_socks_key);
+static inline int sk_memalloc_socks(void)
+{
+	return static_branch_unlikely(&memalloc_socks_key);
+}
+#else
+
+static inline int sk_memalloc_socks(void)
+{
+	return 0;
+}
+
+#endif
+
 /**
  * __dev_alloc_pages - allocate page for network Rx
  * @gfp_mask: allocation priority. Set __GFP_NOMEMALLOC if not for network Rx
@@ -2953,7 +2968,9 @@ static inline struct page *__dev_alloc_pages(gfp_t gfp_mask,
 	 * 4.  __GFP_MEMALLOC is ignored if __GFP_NOMEMALLOC is set due to
 	 *     code in gfp_to_alloc_flags that should be enforcing this.
 	 */
-	gfp_mask |= __GFP_COMP | __GFP_MEMALLOC;
+	gfp_mask |= __GFP_COMP;
+	if (sk_memalloc_socks())
+		gfp_mask |= __GFP_MEMALLOC;
 
 	return alloc_pages_node(NUMA_NO_NODE, gfp_mask, order);
 }
diff --git a/include/net/sock.h b/include/net/sock.h
index 814e7d768712..3a3ba11630ae 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -905,20 +905,8 @@ static inline bool sock_flag(const struct sock *sk, enum sock_flags flag)
 }
 
 #ifdef CONFIG_NET
-DECLARE_STATIC_KEY_FALSE(memalloc_socks_key);
-static inline int sk_memalloc_socks(void)
-{
-	return static_branch_unlikely(&memalloc_socks_key);
-}
-
 void __receive_sock(struct file *file);
 #else
-
-static inline int sk_memalloc_socks(void)
-{
-	return 0;
-}
-
 static inline void __receive_sock(struct file *file)
 { }
 #endif


More information about the Devel mailing list