On Tue, Mar 10, 2009 at 09:14:13AM +0100, Enrik Berkhan wrote:
> I've just noticed that it is possible to evict ramfs pages from the page
> cache using 'echo 3 > /proc/sys/vm/drop_caches', when these pages have
> been used to provide shared memory via shmget(2) on NOMMU systems.
Just some additional info:
Kernel 2.6.28.7/Blackfin ADI SVN r6135
How to reproduce:
Use attached simple shm server/client. Server permanently attaches to
the shm segment and polls every second the single integer value located
in it. When the value changes, it is printed. Client attaches,
increments the said integer by one and detaches. Should be called from a
shell loop.
Then produce some pagecache load by reading a huge file (I use a 1GB file,
having about 60MB of RAM used by Linux). After a few seconds, the client
fails to attach to the shm segment returning ENOMEM. The server starts
to return arbitrary values as soon the shm page will be reused.
Log 1, running the client from a loop:
# while ./shmtest -c ; sleep 1; done
[runs for a while without error ...]
shmat: Cannot allocate memory
shmat: Cannot allocate memory
shmat: Cannot allocate memory
shmat: Cannot allocate memory
shmat: Cannot allocate memory
Log 2, running the server:
# ./shmtest -s
0
1
2
3
-1857476680
-609863449
247294934
-1243221036
402112011
1906906884
...
shmtest.c:
/opt/uClinux/bfin-linux-uclibc/bin/bfin-linux-uclibc-gcc -Wall -g -std=c99
shmtest.c -o shmtest
--- 8< ---
#define _GNU_SOURCE
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int
usage(int retval)
{
fprintf(stderr, "usage: shmtest {-c|-s}\n");
return retval;
}
int
main(int argc, char **argv)
{
int opt, opt_s = -1;
key_t key;
int id;
void *data;
int *count;
while (-1 != (opt = getopt(argc, argv, "csh"))) {
switch(opt) {
case 'c':
opt_s = 0;
break;
case 's':
opt_s = 1;
break;
case 'h':
return usage(0);
default:
return 1;
}
}
if (opt_s == -1)
return usage(1);
key = ftok("/dev/null", 0);
if (-1 == key) {
perror("ftok");
return 1;
}
id = shmget(key, sizeof(int), IPC_CREAT|0666);
if (-1 == id) {
perror("shmget");
return 1;
}
data = shmat(id, 0, opt_s?0:SHM_RDONLY);
if ((void *)(-1) == data) {
perror("shmat");
return 1;
}
count = data;
if (opt_s) {
int last = -1;
for (;;) {
if (last != *count)
printf("%d\n", *count);
last = *count;
sleep(1);
}
} else {
(*count)++;
}
return 0;
}
--- >8 ---
Enrik
_______________________________________________
uClinux-dev mailing list
[email protected]
http://mailman.uclinux.org/mailman/listinfo/uclinux-dev
This message was resent by [email protected]
To unsubscribe see:
http://mailman.uclinux.org/mailman/options/uclinux-dev