Add another old article about special memhog for testing cgroups
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
4d5e4f3c99
commit
8e274ac6cb
124
content/post/slow-memhog.md
Normal file
124
content/post/slow-memhog.md
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
---
|
||||||
|
title: Slow memhog for testing cgroups
|
||||||
|
date: !!timestamp '2016-10-04 00:00:00'
|
||||||
|
tags:
|
||||||
|
- teaching
|
||||||
|
---
|
||||||
|
|
||||||
|
Testing the cgroup memory is not something as easy as we can think. It can't be
|
||||||
|
only question of `malloc(100000)` in a loop, as the Linux kernel overcommit
|
||||||
|
memory allocation: so even if we get effectively a 100000 bytes long memory
|
||||||
|
space, this doesn't decrease the physical available memory. To do so, this
|
||||||
|
space need to be changed pages by pages, that can be tedious to do. And quite
|
||||||
|
uncertain, because the kernel can take advantage of the swap partition...
|
||||||
|
|
||||||
|
To facilitate memory testing, there is `memhog`, part of `numactl` tools. It
|
||||||
|
aims to allocate large memory block for testing, directly in the physical
|
||||||
|
memory.
|
||||||
|
|
||||||
|
<!-- more -->
|
||||||
|
|
||||||
|
If we ask memhog to allocate 100M, 1G, 5G, 10G, ... it'll actually ask the
|
||||||
|
kernel for such amont of memory, in no time. If there is enough memory
|
||||||
|
available, we got our 100M, 1G, 5G, ... and the available memory is really
|
||||||
|
decreased by such volume.
|
||||||
|
|
||||||
|
In my demos, I need a slightly different behaviour, to demonstrate what happens
|
||||||
|
as a function of time.
|
||||||
|
|
||||||
|
I slightly modify `memhog` to introduce a timer between slice allocation.
|
||||||
|
|
||||||
|
```c
|
||||||
|
/* Derivative work of memhog.c from the numactl repository,
|
||||||
|
hosted at https://github.com/numactl/numactl.git
|
||||||
|
|
||||||
|
Copyright (C) 2016 Pierre-Olivier Mercier, EPITA.
|
||||||
|
Copyright (C) 2003,2004 Andi Kleen, SuSE Labs.
|
||||||
|
|
||||||
|
numactl is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public
|
||||||
|
License as published by the Free Software Foundation; version
|
||||||
|
2.
|
||||||
|
numactl is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
You should find a copy of v2 of the GNU General Public License somewhere
|
||||||
|
on your Linux system; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
char *
|
||||||
|
alloc_workbuf(size_t size)
|
||||||
|
{
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
|
/* allocate some memory */
|
||||||
|
ptr = malloc(size);
|
||||||
|
|
||||||
|
/* return NULL on failure */
|
||||||
|
if (ptr == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Unable to malloc %zuk: %s\n", size / 1024, strerror(errno));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* lock this buffer into RAM */
|
||||||
|
if (mlock(ptr, size)) {
|
||||||
|
free(ptr);
|
||||||
|
if (errno == ENOMEM)
|
||||||
|
fprintf(stderr, "Unable to lock memory: not enough permissions\n");
|
||||||
|
else
|
||||||
|
perror("Unable to lock memory");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
size_t size;
|
||||||
|
size_t steps = 32;
|
||||||
|
|
||||||
|
/* parse arguments */
|
||||||
|
if (argc < 2 || argc > 3) {
|
||||||
|
fprintf(stderr, "Usage: memhog <size in MB> [nb steps]\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
size = atoi(argv[1]);
|
||||||
|
if (argc > 2)
|
||||||
|
steps = atoi(argv[2]);
|
||||||
|
|
||||||
|
size = size / steps;
|
||||||
|
|
||||||
|
/* Do stuff */
|
||||||
|
for (size_t i = 0; i < steps; i++)
|
||||||
|
{
|
||||||
|
if (!alloc_workbuf(size * 1000000UL))
|
||||||
|
break;
|
||||||
|
|
||||||
|
printf(".");
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
|
usleep(80000);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
You can compile those C lines with just `make`, stating your file is named `memhog.c`:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
make memhog
|
||||||
|
```
|
Loading…
x
Reference in New Issue
Block a user