Re: [PATCH 0/8][for -mm] mem_notify v6

!MAILaRCHIVE_VOTE_RePLACE
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
To: KOSAKI Motohiro <kosaki.motohiro@...>
Cc: <linux-mm@...>, <linux-kernel@...>
Date: Monday, April 14, 2008 - 8:16 pm

On Wed, Apr 2, 2008 at 12:31 AM, KOSAKI Motohiro
<kosaki.motohiro@jp.fujitsu.com> wrote:

Here's a test program that allocates memory and frees on notification.
 It takes an argument which is the number of pages to use; use a
number considerably higher than the amount of memory in the system.
I'm running this on a system without swap.  Each time it gets a
notification, it frees memory and writes out the /proc/meminfo
contents.  What I see is that Cached gradually decreases, then Mapped
decreases, and eventually the kernel invokes the oom killer.  It may
be necessary to tune some of the constants that control the allocation
and free rates and latency; these values work for my system.

#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <poll.h>
#include <sched.h>
#include <time.h>

#define PAGESIZE 4096

/* How many pages we've mmap'd. */
static int pages;

/* Pointer to mmap'd memory used as a circular buffer.  One thread
   touches pages, another thread releases them on notification. */
static char *p;

/* How many pages to touch each 5ms.  This makes at most 2000
   pages/sec. */
#define TOUCH_CHUNK 10

/* How many pages to free when we're notified.  With a 100ms FREE_DELAY,
   we can free ~9110 pages/sec, or perhaps only 5*911 = 4555 pages/sec if we're
   notified only 5 times/sec. */
#define FREE_CHUNK 911

/* Delay in milliseconds before freeing pages, to simulate latency while finding
   pages to free. */
#define FREE_DELAY 100

static void touch(void);
static int release(void *arg);
static void release_pages(void);
static void show_meminfo(void);

/* Stack for the release thread. */
static char stack[8192];

int
main (int argc, char **argv)
{
    pages = atoi(argv[1]);
    p = mmap(NULL, pages * PAGESIZE, PROT_READ | PROT_WRITE,
                   MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, 0, 0);
    if (p == MAP_FAILED) {
        perror("mmap");
        exit(1);
    }

    if (clone(release, stack + sizeof(stack) - 4,
              CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_THREAD,
              NULL) == -1) {
        perror("clone failed");
        exit(1);
    }

    touch();
}

static void
touch (void)
{
    int page = 0;

    while (1) {
        int i;
        struct timespec t;
        for (i = 0; i < TOUCH_CHUNK; i++) {
            p[page * PAGESIZE] = 1;
            if (++page >= pages) {
                page = 0;
            }
        }

        t.tv_sec = 0;
        t.tv_nsec = 5000000;
        if (nanosleep(&t, NULL) == -1) {
            perror("nanosleep");
        }
    }
}

static int
release (void *arg)
{
    int fd = open("/dev/mem_notify", O_RDONLY);
    if (fd == -1) {
        perror("open(/dev/mem_notify)");
        exit(1);
    }

    while (1) {
        struct pollfd pfd;
        int nfds;

        pfd.fd = fd;
        pfd.events = POLLIN;

        nfds = poll(&pfd, 1, -1);
        if (nfds == -1) {
            perror("poll");
            exit(1);
        }
        if (nfds == 1) {
            struct timespec t;
            t.tv_sec = 0;
            t.tv_nsec = FREE_DELAY * 1000000;
            if (nanosleep(&t, NULL) == -1) {
                perror("nanosleep");
            }
            release_pages();
            printf("time: %d\n", time(NULL));
            show_meminfo();
        }
    }
}

static void
release_pages (void)
{
    /* Index of the next page to free. */
    static int page = 0;
    int i;

    /* Release FREE_CHUNK pages. */

    for (i = 0; i < FREE_CHUNK; i++) {
        int r = madvise(p + page*PAGESIZE, PAGESIZE, MADV_DONTNEED);
        if (r == -1) {
            perror("madvise");
            exit(1);
        }
        if (++page >= pages) {
            page = 0;
        }
    }
}

static void
show_meminfo (void)
{
    char buffer[2000];
    int fd;
    ssize_t n;

    fd = open("/proc/meminfo", O_RDONLY);
    if (fd == -1) {
        perror("open(/proc/meminfo)");
        exit(1);
    }

    n = read(fd, buffer, sizeof(buffer));
    if (n == -1) {
        perror("read(/proc/meminfo)");
        exit(1);
    }

    n = write(1, buffer, n);
    if (n == -1) {
        perror("write(stdout)");
        exit(1);
    }

    if (close(fd) == -1) {
        perror("close(/proc/meminfo)");
        exit(1);
    }
}

.tom
--
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
[PATCH 0/8][for -mm] mem_notify v6, KOSAKI Motohiro, (Sat Feb 9, 11:19 am)
Re: [PATCH 0/8][for -mm] mem_notify v6, Tom May, (Tue Apr 1, 7:35 pm)
Re: [PATCH 0/8][for -mm] mem_notify v6, KOSAKI Motohiro, (Wed Apr 2, 3:31 am)
Re: [PATCH 0/8][for -mm] mem_notify v6, Tom May, (Mon Apr 14, 8:16 pm)
Re: [PATCH 0/8][for -mm] mem_notify v6, KOSAKI Motohiro, (Thu Apr 17, 5:30 am)
Re: [PATCH 0/8][for -mm] mem_notify v6, Tom May, (Thu Apr 17, 3:23 pm)
Re: [PATCH 0/8][for -mm] mem_notify v6, Daniel Spång, (Wed Apr 23, 4:27 am)
Re: [PATCH 0/8][for -mm] mem_notify v6, Tom May, (Wed Apr 30, 10:07 pm)
Re: [PATCH 0/8][for -mm] mem_notify v6, KOSAKI Motohiro, (Thu May 1, 11:06 am)
Re: [PATCH 0/8][for -mm] mem_notify v6, Tom May, (Fri May 2, 6:21 pm)
Re: [PATCH 0/8][for -mm] mem_notify v6, KOSAKI Motohiro, (Sat May 3, 8:26 am)
Re: [PATCH 0/8][for -mm] mem_notify v6, Tom May, (Tue May 6, 1:22 am)
Re: [PATCH 0/8][for -mm] mem_notify v6, KOSAKI Motohiro, (Fri Apr 18, 6:07 am)
Re: [PATCH 0/8][for -mm] mem_notify v6, Tom May, (Mon Apr 21, 4:32 pm)
Re: [PATCH 0/8][for -mm] mem_notify v6, KOSAKI Motohiro, (Tue Apr 15, 10:30 pm)
Re: [PATCH 0/8][for -mm] mem_notify v6, Tom May, (Wed Apr 2, 1:45 pm)
Re: [PATCH 0/8][for -mm] mem_notify v6, Paul Jackson, (Sun Feb 17, 10:49 am)
Re: [PATCH 0/8][for -mm] mem_notify v6, KOSAKI Motohiro, (Tue Feb 19, 3:36 am)
Re: [PATCH 0/8][for -mm] mem_notify v6, Paul Jackson, (Tue Feb 19, 11:00 am)
Re: [PATCH 0/8][for -mm] mem_notify v6, Pavel Machek, (Tue Feb 19, 6:28 pm)
Re: [PATCH 0/8][for -mm] mem_notify v6, Rik van Riel, (Tue Feb 19, 10:07 pm)
Re: [PATCH 0/8][for -mm] mem_notify v6, Paul Jackson, (Wed Feb 20, 12:36 am)
Re: [PATCH 0/8][for -mm] mem_notify v6, KOSAKI Motohiro, (Tue Feb 19, 10:48 pm)
Re: [PATCH 0/8][for -mm] mem_notify v6, Paul Jackson, (Wed Feb 20, 12:57 am)
Re: [PATCH 0/8][for -mm] mem_notify v6, KOSAKI Motohiro, (Wed Feb 20, 1:21 am)
Re: [PATCH 0/8][for -mm] mem_notify v6, Paul Jackson, (Tue Feb 19, 9:54 pm)
Re: [PATCH 0/8][for -mm] mem_notify v6, Rik van Riel, (Tue Feb 19, 3:02 pm)
Re: [PATCH 0/8][for -mm] mem_notify v6, Paul Jackson, (Tue Feb 19, 4:18 pm)
Re: [PATCH 0/8][for -mm] mem_notify v6, Paul Jackson, (Tue Feb 19, 4:43 pm)
[PATCH 0/8][for -mm] mem_notify v6, Jonathan Corbet, (Mon Feb 11, 11:36 am)
Re: [PATCH 0/8][for -mm] mem_notify v6, KOSAKI Motohiro, (Mon Feb 11, 11:46 am)
Re: [PATCH 0/8][for -mm] mem_notify v6, Jon Masters, (Sat Feb 9, 12:02 pm)
Re: [PATCH 0/8][for -mm] mem_notify v6, KOSAKI Motohiro, (Sat Feb 9, 12:33 pm)
Re: [PATCH 0/8][for -mm] mem_notify v6, Rik van Riel, (Sat Feb 9, 12:43 pm)
Re: [PATCH 0/8][for -mm] mem_notify v6, KOSAKI Motohiro, (Sat Feb 9, 12:49 pm)