[LTP] [PATCH v1] mmapstress06: Rate limit page-dirtying loop to prevent MemCG OOM-kills

Wei Gao wegao@suse.com
Tue Sep 1 10:22:14 CEST 2026


On Tue, Sep 01, 2026 at 07:38:01AM +0000, Andrea Cervesato wrote:
> Hi Wei,
> 
> > > Something as:
> > > 
> > > diff --git a/testcases/kernel/mem/mmapstress/mmapstress06.c b/testcases/kernel/mem/mmapstress/mmapstress06.c
> > > index 4e6023399..2c0c6fb02 100644
> > > --- a/testcases/kernel/mem/mmapstress/mmapstress06.c
> > > +++ b/testcases/kernel/mem/mmapstress/mmapstress06.c
> > > @@ -59,8 +59,9 @@ static void run_test(void)
> > >  
> > >                 for (size_t i = 0; i < map_size; i += page_size) {
> > >                         mmapaddr[i] = 'a';
> > > -                       if ((i % (2 * 1024 * 1024)) == 0)
> > > -                               usleep(1000);
> > > +
> > > +                       if (i >= mem_limit && !(i % (2 * 1024 * 1024)))
> > > +                               usleep(100000);
> > >                 }
> > > 
> > > The testrun increses to 6s from 1s but it makes the OOM very unlikely to
> > > happen.
> > Thanks for your suggestion.
> > I have tested above solution in our openqa setup but still encounter failure, 3 test cases
> > still failure with oom after run 100 cases. Maybe slow down dirty loop
> > is still too late?
> 
> I still believe there's no way to avoid this, unless we re-implement the
> OOM-killer or memory.reclaim mechanism increasing the amount of attempts
> per request. We will always encounter hardware that is too slow that
> won't swap memory fast enough for the test.

@Andrea @Cyril
As my former email suggestion "protect task with oom_score_adj set to -1000", and this can work
after 100 runs. If you agree this solution then i will create v2 new patch.


--- a/testcases/kernel/mem/mmapstress/mmapstress06.c
+++ b/testcases/kernel/mem/mmapstress/mmapstress06.c
@@ -23,6 +23,7 @@
 #include <errno.h>
 #include <stdlib.h>
 #include "tst_test.h"
+#include "tst_memutils.h"

 static struct tst_cg_group *cg_child;
 static int page_size;
@@ -47,6 +48,8 @@ static void run_test(void)
                char *mmapaddr;
                unsigned long cg_swap_before = 0, cg_swap_after = 0;

+               tst_enable_oom_protection(0);
+
                /* Move child to the constrained cgroup */
                SAFE_CG_PRINTF(cg_child, "cgroup.procs", "%d", getpid());

@@ -57,11 +60,12 @@ static void run_test(void)

                tst_res(TINFO, "Dirtying %zu bytes in child", map_size);

-               for (size_t i = 0; i < map_size; i += page_size) {
+               /*
+                * Tasks with the OOM protection (oom_score_adj set to -1000)
+                * are treated as an exception and are never killed.
+                */
+               for (size_t i = 0; i < map_size; i += page_size)
                        mmapaddr[i] = 'a';
-                       if ((i % (2 * 1024 * 1024)) == 0)
-                               usleep(1000);
-               }

                SAFE_CG_SCANF(cg_child, "memory.swap.current", "%lu", &cg_swap_after);




> 
> --
> Andrea Cervesato
> SUSE QE Automation Engineer Linux
> andrea.cervesato@suse.com


More information about the ltp mailing list