[Devel] [PATCH RHEL7 COMMIT] slub: ignore memcg limits during slub allocations
Konstantin Khorenko
khorenko at virtuozzo.com
Thu Jul 11 15:24:03 MSK 2024
The commit is pushed to "branch-rh7-3.10.0-1160.105.1.vz7.220.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-1160.105.1.vz7.220.7
------>
commit f56d551bddbc90ca3b0dfb2cafd778bec0e5fd15
Author: Konstantin Khorenko <khorenko at virtuozzo.com>
Date: Tue Jul 2 21:01:51 2024 +0300
slub: ignore memcg limits during slub allocations
Pretend slubs are always allocated by a PF_MEMALLOC process to bypass
memory cgroup limits.
Added per-slab "pf_memalloc" attribute to disable/enable the logic on
the fly.
This is debug patch for sure.
https://virtuozzo.atlassian.net/browse/PSBM-155867
Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
---
include/linux/slab.h | 1 +
mm/slub.c | 39 +++++++++++++++++++++++++++++++++++++--
2 files changed, 38 insertions(+), 2 deletions(-)
diff --git a/include/linux/slab.h b/include/linux/slab.h
index 8722dc8864be..263f10a436f6 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -24,6 +24,7 @@
#define SLAB_CONSISTENCY_CHECKS 0x00000100UL /* DEBUG: Perform (expensive) checks on alloc/free */
#define SLAB_RED_ZONE 0x00000400UL /* DEBUG: Red zone objs in a cache */
#define SLAB_POISON 0x00000800UL /* DEBUG: Poison objects */
+#define SLAB_PF_MEMALLOC 0x00001000UL /* DEBUG: Ignore memcg limits */
#define SLAB_HWCACHE_ALIGN 0x00002000UL /* Align objs on cache lines */
#define SLAB_CACHE_DMA 0x00004000UL /* Use GFP_DMA memory */
#define SLAB_STORE_USER 0x00010000UL /* DEBUG: Store the last owner for bug hunting */
diff --git a/mm/slub.c b/mm/slub.c
index d4392708a014..7ec3f8b37701 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1273,6 +1273,9 @@ static int __init setup_slub_debug(char *str)
case 'a':
slub_debug |= SLAB_FAILSLAB;
break;
+ case 'm':
+ slub_debug |= SLAB_PF_MEMALLOC;
+ break;
default:
printk(KERN_ERR "slub_debug option '%c' "
"unknown. skipped\n", *str);
@@ -2460,6 +2463,16 @@ static void *___slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node,
{
void *freelist;
struct page *page;
+ unsigned long pflags = current->flags;
+
+ if (s->flags & SLAB_PF_MEMALLOC) {
+ /*
+ * A big crutch for debug purposes: we suspect some slub allocation
+ * failure leads to a memory corruption, so for now we want to make
+ * them all always succeed to check the theory.
+ */
+ current->flags |= PF_MEMALLOC;
+ }
page = c->page;
if (!page)
@@ -2519,7 +2532,7 @@ static void *___slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node,
VM_BUG_ON(!c->page->frozen);
c->freelist = get_freepointer(s, freelist);
c->tid = next_tid(c->tid);
- return freelist;
+ goto restore_pfmemalloc;
new_slab:
@@ -2536,7 +2549,7 @@ static void *___slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node,
if (unlikely(!freelist)) {
if (!(gfpflags & __GFP_NOWARN) && printk_ratelimit())
slab_out_of_memory(s, gfpflags, node);
- return NULL;
+ goto restore_pfmemalloc;
}
page = c->page;
@@ -2550,6 +2563,11 @@ static void *___slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node,
deactivate_slab(s, page, get_freepointer(s, freelist));
c->page = NULL;
c->freelist = NULL;
+
+restore_pfmemalloc:
+ if (s->flags & SLAB_PF_MEMALLOC)
+ tsk_restore_flags(current, pflags, PF_MEMALLOC);
+
return freelist;
}
@@ -5217,6 +5235,22 @@ static ssize_t poison_store(struct kmem_cache *s,
}
SLAB_ATTR(poison);
+static ssize_t pf_memalloc_show(struct kmem_cache *s, char *buf)
+{
+ return sprintf(buf, "%d\n", !!(s->flags & SLAB_PF_MEMALLOC));
+}
+
+static ssize_t pf_memalloc_store(struct kmem_cache *s,
+ const char *buf, size_t length)
+{
+ s->flags &= ~SLAB_PF_MEMALLOC;
+ if (buf[0] == '1') {
+ s->flags |= SLAB_PF_MEMALLOC;
+ }
+ return length;
+}
+SLAB_ATTR(pf_memalloc);
+
static ssize_t store_user_show(struct kmem_cache *s, char *buf)
{
return sprintf(buf, "%d\n", !!(s->flags & SLAB_STORE_USER));
@@ -5439,6 +5473,7 @@ static struct attribute *slab_attrs[] = {
&trace_attr.attr,
&red_zone_attr.attr,
&poison_attr.attr,
+ &pf_memalloc_attr.attr,
&store_user_attr.attr,
&validate_attr.attr,
&alloc_calls_attr.attr,
More information about the Devel
mailing list