[BUG] fadvise POSIX_FADV_NOREUSE does nothing

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Related to my other bug report today, calling posix_fadvise (which uses
fadvise64) with the POSIX_FADV_NOREUSE flag does nothing.  The pages are
not dropped behind.

I also tried call fadvise with POSIX_FADV_SEQUENTIAL first.

This is expected as the POSIX_FADV_NOREUSE is a no-op in the recent
kernels.

Also, POSIX_FADV_SEQUENTIAL only does the readahead window. It doesn't
hint the VM in any way to possibly drop-behind the pages.

(See the previous bug report for more details of the test case)

Relevant numbers:

Copying (using fadvise_cp) a large file test:

1st run: 0m9.018s
2nd run: 0m3.444s
Copying large file...
3rd run: 0m14.024s    <<< page cache trashed
4th run: 0m3.449s

Test programs and batch files are attached.


- Eric

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
	int in;
	int out;
	int pagesize; 
	void *buf;
	off_t pos;

	if (argc != 3) {
		printf("Usage: %s <src> <dest>\n", argv[0]); 
		return EXIT_FAILURE;
	}

	in = open(argv[1], O_RDONLY, 0);
	out = open(argv[2], O_CREAT | O_WRONLY | O_TRUNC, 0666);

	posix_fadvise(in, 0, 0, POSIX_FADV_SEQUENTIAL);
	posix_fadvise(out, 0, 0, POSIX_FADV_SEQUENTIAL);

	pagesize = getpagesize();
	buf = malloc(pagesize);

	pos = 0;

	for (;;) {
		ssize_t count;

		count = read(in, buf, pagesize);
		if (!count || count == -1)
			break;

		write(out, buf, count);

		/* right usage pattern? */
		posix_fadvise(in, pos, count, POSIX_FADV_NOREUSE);
		posix_fadvise(out, pos, count, POSIX_FADV_NOREUSE);

		pos += count;
	}

	free(buf);
	close(in);
	close(out);

	return EXIT_SUCCESS;
}
all:
	gcc fadvise_cp.c -o fadvise_cp
	gcc working_set_simul.c -o working_set_simul

Attachment: use-once-test.sh
Description: application/shellscript

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

int main(int argc, char *argv[])
{
	int fd;
	off_t size;
	char *mapping;
	unsigned r;
	unsigned i;

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

	fd = open(argv[1], O_RDONLY, 0);
	size = lseek(fd, 0, SEEK_END); 

	mapping = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);

	/* access (read) the file a couple of times*/
	for (r = 0; r < 4; r++) {
		for (i = 0; i < size; i++) {
			char t = mapping[i];
		}
	}

	munmap(mapping, size);
	close(fd);

	return EXIT_SUCCESS;
}

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux