Skip to content

RSS controller based on process containers (v3.1)

Pavel Emelianov lkml 1 version In review

Get series with b4
b4 am [email protected]

Versions newest first

  1. v1 Latest8 patches 5 repliesIn review

Changes from v3 from the cover letter

- comments across the code
- git-bisect safe split
- lost places to move the page between active/inactive lists

Patches in v1 No applies recorded yet

#Subject and filesSizeRepliesApplied
1/8Resource countersinclude/linux/res_counter.h init/Kconfig kernel/Makefile +1 more+228 -00 replies
2/8Add container pointer on struct pageinclude/linux/mm.h include/linux/mm_types.h+27 -00 replies
3/8Add container pointer on mm_structinclude/linux/rss_container.h include/linux/sched.h kernel/fork.c+32 -30 replies
4/8Scanner changes needed to implement per-container scannerinclude/linux/swap.h mm/vmscan.c+81 -280 replies
5/8RSS container coreinclude/linux/container_subsys.h include/linux/rss_container.h init/Kconfig +2 more+427 -00 replies
6/8Per container OOM killerinclude/linux/rss_container.h mm/oom_kill.c+40 -40 replies
7/8Per-container pages reclamationinclude/linux/rss_container.h mm/rss_container.c mm/swap.c +1 more+153 -40 replies
8/8RSS accounting hooks over the codefs/exec.c include/linux/rmap.h mm/memory.c +4 more+134 -280 replies

Reviews trailers per patch

No Reviewed-by, Acked-by or Tested-by trailers for v1 yet.

Read the v1 thread

Cover letter [PATCH 0/8] RSS controller based on process containers (v3.1)

Adds RSS accounting and control within a container.

Changes from v3
- comments across the code
- git-bisect safe split
- lost places to move the page between active/inactive lists

Ported above Paul's containers V10 with fixes from Balbir.

RSS container includes the per-container RSS accounting and reclamation, and out-of-memory killer.

Each mapped page has an owning container and is linked into its LRU lists just like in the global LRU ones. The owner of the page is the container that touched the page first. As long as the page stays mapped it holds the container, is accounted into its usage and lives in its LRU list. When page is unmapped for the last time it releases the container. The RSS usage is exactly the number of pages in its booth LRU lists, i.e. the nu,ber of pages used by this container. When this usage exceeds the limit set some pages are reclaimed from the owning container. In case no reclamation possible the OOM killer starts thinning out the container.

Thus the container behaves like a standalone machine - when it runs out of resources, it tries to reclaim some pages, and if it doesn't succeed, kills some task.

The testing scenario may look like this:

1. Prepare the containers

# mkdir -p /containers/rss
# mount -t container none /containers/rss -o rss

2. Make the new group and move bash into it

# mkdir /containers/rss/0
# echo $$ >  /containers/rss/0/tasks

Since now we're in the 0 container.
We can alter the RSS limit

# echo -n 6000 > /containers/rss/0/rss_limit

We can check the usage

# cat /containers/rss/0/rss_usage 
25

And do other stuff. To check the reclamation to work we need a simple program that touches many pages of memory, like this:

#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>
#include <fcntl.h>

#ifndef PGSIZE
#define PGSIZE 4096
#endif

int main(int argc, char **argv)

{
        unsigned long pages;
        int i;
        char *mem;

        if (argc < 2) {
                printf("Usage: %s <number_of_pages>\n", argv[0]);
                return 1;
        }

        pages = strtol(argv[1], &mem, 10);
        if (*mem != '\0') {
                printf("Bad number %s\n", argv[1]);
                return 1;
        }

        mem = mmap(NULL, pages * PGSIZE, PROT_READ | PROT_WRITE,
                        MAP_PRIVATE | MAP_ANON, 0, 0);
        if (mem == MAP_FAILED) {
                perror("map");
                return 2;
        }

        for (i = 0; i < pages; i++)
                mem[i * PGSIZE] = 0;

        printf("OK\n");
        return 0;
}