Beispiel #1
0
int ringbuffer_init(struct ringbuffer *b, size_t size, bool roundup_ok) {
  int err;
  
  if (size == 0 || size*2 < size || (size%PAGE_SIZE) != 0) {
    if (!roundup_ok) {
      errno = EINVAL;
      return -1;
    }
    size = ((size+PAGE_SIZE-1)/PAGE_SIZE)*PAGE_SIZE;
  }
  b->size = size;
  
  b->start = b->buf = mmap(NULL, size*2, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
  if (b->buf == NULL) return -1;
  
  if (remap_file_pages(b->buf, size, 0, size/PAGE_SIZE, 0)) goto unmap;
  
  *(char *)b->buf = 0x42;
  if (*((char *)b->buf+size) != 0x42) {
    fprintf(stderr, "ERROR: SOMETHING BORKED UP THE RINGBUFFER!\n");
    assert(0);
  }
  *(char *)b->buf = 0;
  
  return 0;
  
unmap:
  err = errno;
  munmap(b->buf, size*2);
  errno = err;
  return -1;
}
Beispiel #2
0
static void nonlinear(void)
{
	int fd;
	const int NPAGES = 10;
	int i;
	char *page;
	char *tmp;

	fd = tempfd();
	tmp = xmalloc(PS);
	for (i = 0; i < NPAGES; i++)  {
		memset(tmp, i, PS);
		write(fd, tmp, PS);
	}
	free(tmp);
	page = checked_mmap(NULL, PS*NPAGES, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
	int k = NPAGES - 1;
	for (i = 0; i < NPAGES; i++, k--) {
		if (remap_file_pages(page + i*PS, PS, 0, k, 0))
			perror("remap_file_pages");
	}
	*page = 1;
	testmem("rfp file dirty", page, MREAD);
	expecterr("rfp fsync expect error", fsync(fd) < 0);
	optionalerr("rfp msync expect error", msync(page, PS, MS_SYNC) < 0);
	close(fd);
}
int
main(int argc, char *argv[])
{
    int fd, j;
    char ch;
    long pageSize;
    char *addr;

    fd = open("/tmp/tfile", O_CREAT | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
    if (fd == -1)
        errExit("open");

    pageSize = sysconf(_SC_PAGESIZE);
    if (pageSize == -1)
        fatal("Couldn't determine page size");

    for (ch = 'a'; ch < 'd'; ch++)
        for (j = 0; j < pageSize; j++)
            write(fd, &ch, 1);

    system("od -a /tmp/tfile");

    addr = mmap(0, 3 * pageSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (addr == MAP_FAILED)
        errExit("mmap");

    printf("Mapped at address %p\n", addr);

    /* The three pages of the file -- 0 1 2 -- are currently mapped
       linearly. Now we rearrange the mapping to 2 1 0. */

    if (remap_file_pages(addr, pageSize, 0, 2, 0) == -1)
        errExit("remap_file_pages");
    if (remap_file_pages(addr + 2 * pageSize, pageSize, 0, 0, 0) == -1)
        errExit("remap_file_pages");

    /* Now we modify the contents of the mapping */

    for (j = 0; j < 0x100; j++)         /* Modifies page 2 of file */
        *(addr + j) = '0';
    for (j = 0; j < 0x100; j++)         /* Modifies page 0 of file */
        *(addr + 2 * pageSize + j) = '2';

    system("od -a /tmp/tfile");

    exit(EXIT_SUCCESS);
}
Beispiel #4
0
int
Mono_Posix_Syscall_remap_file_pages (void *start, mph_size_t size, 
		int prot, mph_ssize_t pgoff, int flags)
{
	int _prot, _flags;

	mph_return_if_size_t_overflow (size);
	mph_return_if_ssize_t_overflow (pgoff);

	if (Mono_Posix_FromMmapProts (prot, &_prot) == -1)
		return -1;
	if (Mono_Posix_FromMmapFlags (flags, &_flags) == -1)
		return -1;

	return remap_file_pages (start, (size_t) size, _prot, (ssize_t) pgoff, _flags);
}
Beispiel #5
0
/**
 * Allocates a buffer of the given size, but mapped consecutively twice in
 * memory, to avoid wrapping at the (first) end of the buffer
 * @param rb ring buffer
 * @param size size requested for the buffer, must be a multiple of page_size
 * @param page_size actual page_size in the system
 * @return errno-compatible negative value on error, 0 otherwise
 */
static int allocate_mirrored_buffer(struct rs_rb *rb, size_t size,
		long page_size)
{
	int ret;

	rb->base = mmap(NULL, 2 * size, PROT_READ | PROT_WRITE,
			MAP_SHARED | MAP_ANONYMOUS, -1, 0);
	if (rb->base == MAP_FAILED)
		return -errno;

	ret = remap_file_pages(rb->base, size, 0, (size / page_size), 0);
	if (ret == -1)
		return -errno;

	return 0;
}
/*
 *  remap_order()
 *	remap based on given order
 */
static int remap_order(
	const args_t *args,
	const size_t stride,
	mapdata_t *data,
	const size_t *order,
	const size_t page_size)
{
	size_t i;

	for (i = 0; i < N_PAGES; i++) {
		int ret;

		ret = remap_file_pages(data + (i * stride), page_size,
			0, order[i], 0);
		if (ret < 0) {
			pr_fail_err("remap_file_pages");
			return -1;
		}
	}

	return 0;
}
Beispiel #7
0
int main(int ac, char **av)
{
	int lc, i;

#if defined (__s390__) || (__s390x__) || (__ia64__)
	/* Disables the test in case the kernel version is lower than 2.6.12 and arch is s390 */
	if ((tst_kvercmp(2, 6, 12)) < 0) {
		tst_resm(TWARN,
			 "This test can only run on kernels that are 2.6.12 and higher");
		exit(0);
	}
#endif

	tst_parse_opts(ac, av, NULL, NULL);

	setup();

	for (lc = 0; TEST_LOOPING(lc); lc++) {

		tst_count = 0;

		for (i = 0; i < TST_TOTAL; i++) {
			/* do the setup if the test have one */
			if (testcase[i].setupfunc
			    && testcase[i].setupfunc(i) == -1) {
				tst_resm(TWARN,
					 "Failed to setup test %d"
					 " Skipping test", i);
				continue;
			}

			/* run the test */
			TEST(remap_file_pages
			     (testcase[i].start, testcase[i].size,
			      testcase[i].prot, testcase[i].pgoff,
			      testcase[i].flags));

			/* do the cleanup if the test have one */
			if (testcase[i].cleanfunc
			    && testcase[i].cleanfunc(i) == -1) {
				tst_brkm(TBROK, cleanup,
					 "Failed to cleanup test %d,"
					 " quitting the test", i);
			}

			/* verify the return code */
			if ((TEST_RETURN == -1)
			    && (TEST_ERRNO == testcase[i].exp_errno)) {
				tst_resm(TPASS,
					 "remap_file_pages(2) expected failure;"
					 " Got errno - %s : %s",
					 testcase[i].exp_errval,
					 testcase[i].err_desc);
			} else {
				tst_resm(TFAIL,
					 "remap_file_pages(2) failed to produce"
					 " expected error: %d, errno: %s."
					 " because got error %d",
					 testcase[i].exp_errno,
					 testcase[i].exp_errval, TEST_ERRNO);
			}
		}		/* end of test loops */
	}			/* end of  test looping */

	/* clean up and exit */
	cleanup();

	tst_exit();
}
Beispiel #8
0
/* test case function, that runs remap_file_pages */
static void test_nonlinear(int fd)
{
	char *data = NULL;
	int i, j, repeat = 2;

	for (i = 0; i < cache_pages; i++) {
		char *page = cache_contents + i * page_sz;

		for (j = 0; j < page_words; j++)
			page[j] = i;
	}

	if (write(fd, cache_contents, cache_sz) != cache_sz) {
		tst_resm(TFAIL,
			 "Write Error for \"cache_contents\" to \"cache_sz\" of %zu (errno=%d : %s)",
			 cache_sz, errno, strerror(errno));
		cleanup(NULL);
	}

	data = mmap((void *)WINDOW_START,
		    window_sz, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

	if (data == MAP_FAILED) {
		tst_resm(TFAIL, "mmap Error, errno=%d : %s", errno,
			 strerror(errno));
		cleanup(NULL);
	}

again:
	for (i = 0; i < window_pages; i += 2) {
		char *page = data + i * page_sz;

		if (remap_file_pages(page, page_sz * 2, 0,
				     (window_pages - i - 2), 0) == -1) {
			tst_resm(TFAIL | TERRNO,
				 "remap_file_pages error for page=%p, "
				 "page_sz=%d, window_pages=%zu",
				 page, (page_sz * 2), (window_pages - i - 2));
			cleanup(data);
		}
	}

	for (i = 0; i < window_pages; i++) {
		/*
		 * Double-check the correctness of the mapping:
		 */
		if (i & 1) {
			if (data[i * page_sz] != window_pages - i) {
				tst_resm(TFAIL,
					 "hm, mapped incorrect data, "
					 "data[%d]=%d, (window_pages-%d)=%zu",
					 (i * page_sz), data[i * page_sz], i,
					 (window_pages - i));
				cleanup(data);
			}
		} else {
			if (data[i * page_sz] != window_pages - i - 2) {
				tst_resm(TFAIL,
					 "hm, mapped incorrect data, "
					 "data[%d]=%d, (window_pages-%d-2)=%zu",
					 (i * page_sz), data[i * page_sz], i,
					 (window_pages - i - 2));
				cleanup(data);
			}
		}
	}

	if (--repeat)
		goto again;

	munmap(data, window_sz);
}