Ejemplo n.º 1
0
/* read_testfile - mmap testfile and read every page.
 * This functions measures how many I/O and time it takes to fully
 * read contents of test file.
 *
 * @do_readahead: call readahead prior to reading file content?
 * @fname: name of file to test
 * @fsize: how many bytes to read/mmap
 * @read_bytes: returns difference of bytes read, parsed from /proc/<pid>/io
 * @usec: returns how many microsecond it took to go over fsize bytes
 * @cached: returns cached kB from /proc/meminfo
 */
static void read_testfile(int do_readahead, const char *fname, size_t fsize,
			  unsigned long *read_bytes, long *usec,
			  unsigned long *cached)
{
	int fd;
	size_t i = 0;
	long read_bytes_start;
	unsigned char *p, tmp;
	unsigned long time_start_usec, time_end_usec;
	unsigned long cached_start, max_ra_estimate = 0;
	off_t offset = 0;
	struct timeval now;

	fd = SAFE_OPEN(cleanup, fname, O_RDONLY);

	if (do_readahead) {
		cached_start = get_cached_size();
		do {
			TEST(readahead(fd, offset, fsize - offset));
			if (TEST_RETURN != 0) {
				check_ret(0);
				break;
			}

			/* estimate max readahead size based on first call */
			if (!max_ra_estimate) {
				*cached = get_cached_size();
				if (*cached > cached_start) {
					max_ra_estimate = (1024 *
						(*cached - cached_start));
					tst_resm(TINFO, "max ra estimate: %lu",
						max_ra_estimate);
				}
				max_ra_estimate = MAX(max_ra_estimate,
					MIN_SANE_READAHEAD);
			}

			i++;
			offset += max_ra_estimate;
		} while ((size_t)offset < fsize);
		tst_resm(TINFO, "readahead calls made: %zu", i);
		*cached = get_cached_size();

		/* offset of file shouldn't change after readahead */
		offset = lseek(fd, 0, SEEK_CUR);
		if (offset == (off_t) - 1)
			tst_brkm(TBROK | TERRNO, cleanup, "lseek failed");
		if (offset == 0)
			tst_resm(TPASS, "offset is still at 0 as expected");
		else
			tst_resm(TFAIL, "offset has changed to: %lu", offset);
	}

	if (gettimeofday(&now, NULL) == -1)
		tst_brkm(TBROK | TERRNO, cleanup, "gettimeofday failed");
	time_start_usec = now.tv_sec * 1000000 + now.tv_usec;
	read_bytes_start = get_bytes_read();

	p = mmap(NULL, fsize, PROT_READ, MAP_SHARED | MAP_POPULATE, fd, 0);
	if (p == MAP_FAILED)
		tst_brkm(TBROK | TERRNO, cleanup, "mmap failed");

	/* for old kernels, where MAP_POPULATE doesn't work, touch each page */
	tmp = 0;
	for (i = 0; i < fsize; i += pagesize)
		tmp = tmp ^ p[i];
	/* prevent gcc from optimizing out loop above */
	if (tmp != 0)
		tst_brkm(TBROK, NULL, "This line should not be reached");

	if (!do_readahead)
		*cached = get_cached_size();

	SAFE_MUNMAP(cleanup, p, fsize);

	*read_bytes = get_bytes_read() - read_bytes_start;
	if (gettimeofday(&now, NULL) == -1)
		tst_brkm(TBROK | TERRNO, cleanup, "gettimeofday failed");
	time_end_usec = now.tv_sec * 1000000 + now.tv_usec;
	*usec = time_end_usec - time_start_usec;

	SAFE_CLOSE(cleanup, fd);
}
Ejemplo n.º 2
0
/* read_testfile - mmap testfile and read every page.
 * This functions measures how many I/O and time it takes to fully
 * read contents of test file.
 *
 * @do_readahead: call readahead prior to reading file content?
 * @fname: name of file to test
 * @fsize: how many bytes to read/mmap
 * @read_bytes: returns difference of bytes read, parsed from /proc/<pid>/io
 * @usec: returns how many microsecond it took to go over fsize bytes
 * @cached: returns cached kB from /proc/meminfo
 */
static void read_testfile(int do_readahead, const char *fname, size_t fsize,
			  unsigned long *read_bytes, long *usec,
			  unsigned long *cached)
{
	int fd;
	size_t i;
	long read_bytes_start;
	unsigned char *p, tmp;
	unsigned long time_start_usec, time_end_usec;
	off_t offset;
	struct timeval now;

	fd = open(fname, O_RDONLY);
	if (fd < 0)
		tst_brkm(TBROK | TERRNO, cleanup, "Failed to open %s", fname);

	if (do_readahead) {
		/* read ahead in chunks, 2MB is maximum since 3.15-rc1 */
		for (i = 0; i < fsize; i += 2*1024*1024) {
			TEST(ltp_syscall(__NR_readahead, fd,
				(off64_t) i, 2*1024*1024));
			if (TEST_RETURN != 0)
				break;
		}
		check_ret(0);
		*cached = get_cached_size();

		/* offset of file shouldn't change after readahead */
		offset = lseek(fd, 0, SEEK_CUR);
		if (offset == (off_t) - 1)
			tst_brkm(TBROK | TERRNO, cleanup, "lseek failed");
		if (offset == 0)
			tst_resm(TPASS, "offset is still at 0 as expected");
		else
			tst_resm(TFAIL, "offset has changed to: %lu", offset);
	}

	if (gettimeofday(&now, NULL) == -1)
		tst_brkm(TBROK | TERRNO, cleanup, "gettimeofday failed");
	time_start_usec = now.tv_sec * 1000000 + now.tv_usec;
	read_bytes_start = get_bytes_read();

	p = mmap(NULL, fsize, PROT_READ, MAP_SHARED | MAP_POPULATE, fd, 0);
	if (p == MAP_FAILED)
		tst_brkm(TBROK | TERRNO, cleanup, "mmap failed");

	/* for old kernels, where MAP_POPULATE doesn't work, touch each page */
	tmp = 0;
	for (i = 0; i < fsize; i += pagesize)
		tmp = tmp ^ p[i];
	/* prevent gcc from optimizing out loop above */
	if (tmp != 0)
		tst_brkm(TBROK, NULL, "This line should not be reached");

	if (!do_readahead)
		*cached = get_cached_size();

	if (munmap(p, fsize) == -1)
		tst_brkm(TBROK | TERRNO, cleanup, "munmap failed");

	*read_bytes = get_bytes_read() - read_bytes_start;
	if (gettimeofday(&now, NULL) == -1)
		tst_brkm(TBROK | TERRNO, cleanup, "gettimeofday failed");
	time_end_usec = now.tv_sec * 1000000 + now.tv_usec;
	*usec = time_end_usec - time_start_usec;

	if (close(fd) == -1)
		tst_brkm(TBROK | TERRNO, cleanup, "close failed");
}
Ejemplo n.º 3
0
/* read_testfile - mmap testfile and read every page.
 * This functions measures how many I/O and time it takes to fully
 * read contents of test file.
 *
 * @do_readahead: call readahead prior to reading file content?
 * @fname: name of file to test
 * @fsize: how many bytes to read/mmap
 * @read_bytes: returns difference of bytes read, parsed from /proc/<pid>/io
 * @usec: returns how many microsecond it took to go over fsize bytes
 * @cached: returns cached kB from /proc/meminfo
 */
static int read_testfile(struct tcase *tc, int do_readahead,
			 const char *fname, size_t fsize,
			 unsigned long *read_bytes, long long *usec,
			 unsigned long *cached)
{
	int fd;
	size_t i = 0;
	long read_bytes_start;
	unsigned char *p, tmp;
	off_t offset = 0;

	fd = SAFE_OPEN(fname, O_RDONLY);

	if (do_readahead) {
		do {
			TEST(tc->readahead(fd, offset, fsize - offset));
			if (TST_RET != 0) {
				SAFE_CLOSE(fd);
				return TST_ERR;
			}

			i++;
			offset += readahead_length;
		} while ((size_t)offset < fsize);
		tst_res(TINFO, "readahead calls made: %zu", i);
		*cached = get_cached_size();

		/* offset of file shouldn't change after readahead */
		offset = SAFE_LSEEK(fd, 0, SEEK_CUR);
		if (offset == 0)
			tst_res(TPASS, "offset is still at 0 as expected");
		else
			tst_res(TFAIL, "offset has changed to: %lu", offset);
	}

	tst_timer_start(CLOCK_MONOTONIC);
	read_bytes_start = get_bytes_read();

	p = SAFE_MMAP(NULL, fsize, PROT_READ, MAP_SHARED | MAP_POPULATE, fd, 0);

	/* for old kernels, where MAP_POPULATE doesn't work, touch each page */
	tmp = 0;
	for (i = 0; i < fsize; i += pagesize)
		tmp = tmp ^ p[i];
	/* prevent gcc from optimizing out loop above */
	if (tmp != 0)
		tst_brk(TBROK, "This line should not be reached");

	if (!do_readahead)
		*cached = get_cached_size();

	SAFE_MUNMAP(p, fsize);

	*read_bytes = get_bytes_read() - read_bytes_start;

	tst_timer_stop();
	*usec = tst_timer_elapsed_us();

	SAFE_CLOSE(fd);
	return 0;
}