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