Example #1
0
static void draw_rect_mmap_wc(int fd, struct buf_data *buf, struct rect *rect,
			      uint32_t color)
{
	uint32_t *ptr;
	uint32_t tiling, swizzle;

	gem_set_domain(fd, buf->handle, I915_GEM_DOMAIN_GTT,
		       I915_GEM_DOMAIN_GTT);
	gem_get_tiling(fd, buf->handle, &tiling, &swizzle);

	/* We didn't implement suport for the older tiling methods yet. */
	if (tiling != I915_TILING_NONE)
		igt_require(intel_gen(intel_get_drm_devid(fd)) >= 5);

	ptr = gem_mmap__wc(fd, buf->handle, 0, buf->size,
			   PROT_READ | PROT_WRITE);

	switch (tiling) {
	case I915_TILING_NONE:
		draw_rect_ptr_linear(ptr, buf->stride, rect, color, buf->bpp);
		break;
	case I915_TILING_X:
		draw_rect_ptr_tiled(ptr, buf->stride, swizzle, rect, color,
				    buf->bpp);
		break;
	default:
		igt_assert(false);
		break;
	}

	igt_assert(munmap(ptr, buf->size) == 0);
}
static void *
mmap_coherent(int fd, uint32_t handle, int size)
{
	if (gem_has_llc(fd)) {
		coherent_domain = I915_GEM_DOMAIN_CPU;
		return gem_mmap__cpu(fd, handle, 0, size, PROT_WRITE);
	}

	coherent_domain = I915_GEM_DOMAIN_GTT;
	if (gem_mmap__has_wc(fd))
		return gem_mmap__wc(fd, handle, 0, size, PROT_WRITE);
	else
		return gem_mmap__gtt(fd, handle, size, PROT_WRITE);
}
static void *wc_mmap(void *closure)
{
	struct thread_contention *t = closure;
	int n;

	for (n = 0; n < t->loops; n++) {
		uint32_t *ptr = gem_mmap__wc(t->fd, t->handle, 0, OBJECT_SIZE, PROT_READ | PROT_WRITE);
		igt_assert(ptr);
		memset(ptr + (rand() % 256) * 4096 / 4, 0, 4096);
		munmap(ptr, OBJECT_SIZE);
	}

	return NULL;
}
Example #4
0
static void *
mmap_coherent(int fd, uint32_t handle, int size)
{
	int domain;
	void *ptr;

	if (gem_has_llc(fd) || !gem_mmap__has_wc(fd)) {
		domain = I915_GEM_DOMAIN_CPU;
		ptr = gem_mmap__cpu(fd, handle, 0, size, PROT_WRITE);
	} else {
		domain = I915_GEM_DOMAIN_GTT;
		ptr = gem_mmap__wc(fd, handle, 0, size, PROT_WRITE);
	}

	gem_set_domain(fd, handle, domain, domain);
	return ptr;
}
Example #5
0
int main(int argc, char **argv)
{
	int fd = drm_open_driver(DRIVER_INTEL);
	enum map {CPU, GTT, WC} map = CPU;
	enum dir {READ, WRITE, CLEAR, FAULT} dir = READ;
	int tiling = I915_TILING_NONE;
	void *buf = malloc(OBJECT_SIZE);
	uint32_t handle;
	void *ptr, *src, *dst;
	int reps = 13;
	int c, size;

	while ((c = getopt (argc, argv, "m:d:r:t:")) != -1) {
		switch (c) {
		case 'm':
			if (strcmp(optarg, "cpu") == 0)
				map = CPU;
			else if (strcmp(optarg, "gtt") == 0)
				map = GTT;
			else if (strcmp(optarg, "wc") == 0)
				map = WC;
			else
				abort();
			break;

		case 'd':
			if (strcmp(optarg, "read") == 0)
				dir = READ;
			else if (strcmp(optarg, "write") == 0)
				dir = WRITE;
			else if (strcmp(optarg, "clear") == 0)
				dir = CLEAR;
			else if (strcmp(optarg, "fault") == 0)
				dir = FAULT;
			else
				abort();
			break;

		case 't':
			if (strcmp(optarg, "x") == 0)
				tiling = I915_TILING_X;
			else if (strcmp(optarg, "y") == 0)
				tiling = I915_TILING_Y;
			else if (strcmp(optarg, "none") == 0)
				tiling = I915_TILING_NONE;
			else
				abort();
			break;

		case 'r':
			reps = atoi(optarg);
			if (reps < 1)
				reps = 1;
			break;

		default:
			break;
		}
	}

	handle = gem_create(fd, OBJECT_SIZE);
	switch (map) {
	case CPU:
		ptr = gem_mmap__cpu(fd, handle, 0, OBJECT_SIZE, PROT_WRITE);
		gem_set_domain(fd, handle, I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
		break;
	case GTT:
		ptr = gem_mmap__gtt(fd, handle, OBJECT_SIZE, PROT_WRITE);
		gem_set_domain(fd, handle, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
		break;
	case WC:
		ptr = gem_mmap__wc(fd, handle, 0, OBJECT_SIZE, PROT_WRITE);
		gem_set_domain(fd, handle, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
		break;
	default:
		abort();
	}

	gem_set_tiling(fd, handle, tiling, 512);

	if (dir == READ) {
		src = ptr;
		dst = buf;
	} else {
		src = buf;
		dst = ptr;
	}

	for (size = 1; size <= OBJECT_SIZE; size <<= 1) {
		igt_stats_t stats;
		int n;

		igt_stats_init_with_size(&stats, reps);

		for (n = 0; n < reps; n++) {
			struct timespec start, end;
			int page;

			clock_gettime(CLOCK_MONOTONIC, &start);
			switch (dir) {
			case CLEAR:
				memset(dst, 0, size);
				break;
			case FAULT:
				for (page = 0; page < OBJECT_SIZE; page += 4096) {
					uint32_t *x = (uint32_t *)ptr + page/4;
					page += *x; /* should be zero! */
				}
				break;
			default:
				memcpy(dst, src, size);
				break;
			}
			clock_gettime(CLOCK_MONOTONIC, &end);

			igt_stats_push(&stats, elapsed(&start, &end));
		}

		printf("%7.3f\n", igt_stats_get_trimean(&stats)/1000);
		igt_stats_fini(&stats);
	}

	return 0;
}
Example #6
0
int main(int argc, char **argv)
{
	struct timeval start, end;
	uint8_t *buf;
	uint32_t handle;
	int size = OBJECT_SIZE;
	int loop, i, tiling;
	int fd;

	igt_simple_init(argc, argv);

	igt_skip_on_simulation();

	if (argc > 1)
		size = atoi(argv[1]);
	if (size == 0) {
		igt_warn("Invalid object size specified\n");
		return 1;
	}

	buf = malloc(size);
	memset(buf, 0, size);
	fd = drm_open_driver(DRIVER_INTEL);

	handle = gem_create(fd, size);
	igt_assert(handle);

	for (tiling = I915_TILING_NONE; tiling <= I915_TILING_Y; tiling++) {
		if (tiling != I915_TILING_NONE) {
			igt_info("\nSetting tiling mode to %s\n",
				 tiling == I915_TILING_X ? "X" : "Y");
			gem_set_tiling(fd, handle, tiling, 512);
		}

		if (tiling == I915_TILING_NONE) {
			gem_set_domain(fd, handle,
				       I915_GEM_DOMAIN_CPU,
				       I915_GEM_DOMAIN_CPU);

			{
				uint32_t *base = gem_mmap__cpu(fd, handle, 0, size, PROT_READ | PROT_WRITE);
				volatile uint32_t *ptr = base;
				int x = 0;

				for (i = 0; i < size/sizeof(*ptr); i++)
					x += ptr[i];

				/* force overtly clever gcc to actually compute x */
				ptr[0] = x;

				munmap(base, size);

				/* mmap read */
				gettimeofday(&start, NULL);
				for (loop = 0; loop < 1000; loop++) {
					base = gem_mmap__cpu(fd, handle, 0,
							     size,
							     PROT_READ | PROT_WRITE);
					ptr = base;
					x = 0;

					for (i = 0; i < size/sizeof(*ptr); i++)
						x += ptr[i];

					/* force overtly clever gcc to actually compute x */
					ptr[0] = x;

					munmap(base, size);
				}
				gettimeofday(&end, NULL);
				igt_info("Time to read %dk through a CPU map:		%7.3fµs\n",
					 size/1024, elapsed(&start, &end, loop));

				/* mmap write */
				gettimeofday(&start, NULL);
				for (loop = 0; loop < 1000; loop++) {
					base = gem_mmap__cpu(fd, handle, 0,
							     size,
							     PROT_READ | PROT_WRITE);
					ptr = base;

					for (i = 0; i < size/sizeof(*ptr); i++)
						ptr[i] = i;

					munmap(base, size);
				}
				gettimeofday(&end, NULL);
				igt_info("Time to write %dk through a CPU map:		%7.3fµs\n",
					 size/1024, elapsed(&start, &end, loop));

				gettimeofday(&start, NULL);
				for (loop = 0; loop < 1000; loop++) {
					base = gem_mmap__cpu(fd, handle, 0,
							     size,
							     PROT_READ | PROT_WRITE);
					memset(base, 0, size);
					munmap(base, size);
				}
				gettimeofday(&end, NULL);
				igt_info("Time to clear %dk through a CPU map:		%7.3fµs\n",
					 size/1024, elapsed(&start, &end, loop));

				gettimeofday(&start, NULL);
				base = gem_mmap__cpu(fd, handle, 0, size,
						     PROT_READ | PROT_WRITE);
				for (loop = 0; loop < 1000; loop++)
					memset(base, 0, size);
				munmap(base, size);
				gettimeofday(&end, NULL);
				igt_info("Time to clear %dk through a cached CPU map:	%7.3fµs\n",
					 size/1024, elapsed(&start, &end, loop));
			}

			/* CPU pwrite */
			gettimeofday(&start, NULL);
			for (loop = 0; loop < 1000; loop++)
				gem_write(fd, handle, 0, buf, size);
			gettimeofday(&end, NULL);
			igt_info("Time to pwrite %dk through the CPU:		%7.3fµs\n",
				 size/1024, elapsed(&start, &end, loop));

			/* CPU pread */
			gettimeofday(&start, NULL);
			for (loop = 0; loop < 1000; loop++)
				gem_read(fd, handle, 0, buf, size);
			gettimeofday(&end, NULL);
			igt_info("Time to pread %dk through the CPU:		%7.3fµs\n",
				 size/1024, elapsed(&start, &end, loop));
		}

		/* prefault into gtt */
		{
			uint32_t *base = gem_mmap__gtt(fd, handle, size, PROT_READ | PROT_WRITE);
			volatile uint32_t *ptr = base;
			int x = 0;

			for (i = 0; i < size/sizeof(*ptr); i++)
				x += ptr[i];

			/* force overtly clever gcc to actually compute x */
			ptr[0] = x;

			munmap(base, size);
		}
		/* mmap read */
		gettimeofday(&start, NULL);
		for (loop = 0; loop < 1000; loop++) {
			uint32_t *base = gem_mmap__gtt(fd, handle, size, PROT_READ | PROT_WRITE);
			volatile uint32_t *ptr = base;
			int x = 0;

			for (i = 0; i < size/sizeof(*ptr); i++)
				x += ptr[i];

			/* force overtly clever gcc to actually compute x */
			ptr[0] = x;

			munmap(base, size);
		}
		gettimeofday(&end, NULL);
		igt_info("Time to read %dk through a GTT map:		%7.3fµs\n",
			 size/1024, elapsed(&start, &end, loop));

		if (gem_mmap__has_wc(fd)) {
			gettimeofday(&start, NULL);
			for (loop = 0; loop < 1000; loop++) {
				uint32_t *base = gem_mmap__wc(fd, handle, 0, size, PROT_READ | PROT_WRITE);
				volatile uint32_t *ptr = base;
				int x = 0;

				for (i = 0; i < size/sizeof(*ptr); i++)
					x += ptr[i];

				/* force overtly clever gcc to actually compute x */
				ptr[0] = x;

				munmap(base, size);
			}
			gettimeofday(&end, NULL);
			igt_info("Time to read %dk through a WC map:		%7.3fµs\n",
					size/1024, elapsed(&start, &end, loop));
		}


		/* mmap write */
		gettimeofday(&start, NULL);
		for (loop = 0; loop < 1000; loop++) {
			uint32_t *base = gem_mmap__gtt(fd, handle, size, PROT_READ | PROT_WRITE);
			volatile uint32_t *ptr = base;

			for (i = 0; i < size/sizeof(*ptr); i++)
				ptr[i] = i;

			munmap(base, size);
		}
		gettimeofday(&end, NULL);
		igt_info("Time to write %dk through a GTT map:		%7.3fµs\n",
			 size/1024, elapsed(&start, &end, loop));

		if (gem_mmap__has_wc(fd)) {
			/* mmap write */
			gettimeofday(&start, NULL);
			for (loop = 0; loop < 1000; loop++) {
				uint32_t *base = gem_mmap__wc(fd, handle, 0, size, PROT_READ | PROT_WRITE);
				volatile uint32_t *ptr = base;

				for (i = 0; i < size/sizeof(*ptr); i++)
					ptr[i] = i;

				munmap(base, size);
			}
			gettimeofday(&end, NULL);
			igt_info("Time to write %dk through a WC map:		%7.3fµs\n",
					size/1024, elapsed(&start, &end, loop));
		}

		/* mmap clear */
		gettimeofday(&start, NULL);
		for (loop = 0; loop < 1000; loop++) {
			uint32_t *base = gem_mmap__gtt(fd, handle, size, PROT_READ | PROT_WRITE);
			memset(base, 0, size);
			munmap(base, size);
		}
		gettimeofday(&end, NULL);
		igt_info("Time to clear %dk through a GTT map:		%7.3fµs\n",
			 size/1024, elapsed(&start, &end, loop));

		if (gem_mmap__has_wc(fd)) {
			/* mmap clear */
			gettimeofday(&start, NULL);
			for (loop = 0; loop < 1000; loop++) {
				uint32_t *base = gem_mmap__wc(fd, handle, 0, size, PROT_READ | PROT_WRITE);
				memset(base, 0, size);
				munmap(base, size);
			}
			gettimeofday(&end, NULL);
			igt_info("Time to clear %dk through a WC map:		%7.3fµs\n",
					size/1024, elapsed(&start, &end, loop));
		}

		gettimeofday(&start, NULL);{
			uint32_t *base = gem_mmap__gtt(fd, handle, size, PROT_READ | PROT_WRITE);
			for (loop = 0; loop < 1000; loop++)
				memset(base, 0, size);
			munmap(base, size);
		} gettimeofday(&end, NULL);
		igt_info("Time to clear %dk through a cached GTT map:	%7.3fµs\n",
			 size/1024, elapsed(&start, &end, loop));

		if (gem_mmap__has_wc(fd)) {
			gettimeofday(&start, NULL);{
				uint32_t *base = gem_mmap__wc(fd, handle, 0, size, PROT_READ | PROT_WRITE);
				for (loop = 0; loop < 1000; loop++)
					memset(base, 0, size);
				munmap(base, size);
			} gettimeofday(&end, NULL);
			igt_info("Time to clear %dk through a cached WC map:	%7.3fµs\n",
					size/1024, elapsed(&start, &end, loop));
		}

		/* mmap read */
		gettimeofday(&start, NULL);
		for (loop = 0; loop < 1000; loop++) {
			uint32_t *base = gem_mmap__gtt(fd, handle, size, PROT_READ | PROT_WRITE);
			volatile uint32_t *ptr = base;
			int x = 0;

			for (i = 0; i < size/sizeof(*ptr); i++)
				x += ptr[i];

			/* force overtly clever gcc to actually compute x */
			ptr[0] = x;

			munmap(base, size);
		}
		gettimeofday(&end, NULL);
		igt_info("Time to read %dk (again) through a GTT map:	%7.3fµs\n",
			 size/1024, elapsed(&start, &end, loop));

		if (tiling == I915_TILING_NONE) {
			/* GTT pwrite */
			gettimeofday(&start, NULL);
			for (loop = 0; loop < 1000; loop++)
				gem_write(fd, handle, 0, buf, size);
			gettimeofday(&end, NULL);
			igt_info("Time to pwrite %dk through the GTT:		%7.3fµs\n",
				 size/1024, elapsed(&start, &end, loop));

			/* GTT pread */
			gettimeofday(&start, NULL);
			for (loop = 0; loop < 1000; loop++)
				gem_read(fd, handle, 0, buf, size);
			gettimeofday(&end, NULL);
			igt_info("Time to pread %dk through the GTT:		%7.3fµs\n",
				 size/1024, elapsed(&start, &end, loop));

			/* GTT pwrite, including clflush */
			gettimeofday(&start, NULL);
			for (loop = 0; loop < 1000; loop++) {
				gem_write(fd, handle, 0, buf, size);
				gem_sync(fd, handle);
			}
			gettimeofday(&end, NULL);
			igt_info("Time to pwrite %dk through the GTT (clflush):	%7.3fµs\n",
				 size/1024, elapsed(&start, &end, loop));

			/* GTT pread, including clflush */
			gettimeofday(&start, NULL);
			for (loop = 0; loop < 1000; loop++) {
				gem_sync(fd, handle);
				gem_read(fd, handle, 0, buf, size);
			}
			gettimeofday(&end, NULL);
			igt_info("Time to pread %dk through the GTT (clflush):	%7.3fµs\n",
				 size/1024, elapsed(&start, &end, loop));

			/* partial writes */
			igt_info("Now partial writes.\n");
			size /= 4;

			/* partial GTT pwrite, including clflush */
			gettimeofday(&start, NULL);
			for (loop = 0; loop < 1000; loop++) {
				gem_write(fd, handle, 0, buf, size);
				gem_sync(fd, handle);
			}
			gettimeofday(&end, NULL);
			igt_info("Time to pwrite %dk through the GTT (clflush):	%7.3fµs\n",
			       size/1024, elapsed(&start, &end, loop));

			/* partial GTT pread, including clflush */
			gettimeofday(&start, NULL);
			for (loop = 0; loop < 1000; loop++) {
				gem_sync(fd, handle);
				gem_read(fd, handle, 0, buf, size);
			}
			gettimeofday(&end, NULL);
			igt_info("Time to pread %dk through the GTT (clflush):	%7.3fµs\n",
			       size/1024, elapsed(&start, &end, loop));

			size *= 4;
		}
	}

	gem_close(fd, handle);
	close(fd);

	igt_exit();
}
Example #7
0
int main(int argc, char **argv)
{
	int fd = drm_open_driver(DRIVER_INTEL);
	enum map {CPU, GTT, WC} map = CPU;
	enum dir {READ, WRITE, CLEAR, FAULT} dir = READ;
	int tiling = I915_TILING_NONE;
	struct timespec start, end;
	void *buf = malloc(OBJECT_SIZE);
	uint32_t handle;
	void *ptr, *src, *dst;
	int reps = 1;
	int loops;
	int c;

	while ((c = getopt (argc, argv, "m:d:r:t:")) != -1) {
		switch (c) {
		case 'm':
			if (strcmp(optarg, "cpu") == 0)
				map = CPU;
			else if (strcmp(optarg, "gtt") == 0)
				map = GTT;
			else if (strcmp(optarg, "wc") == 0)
				map = WC;
			else
				abort();
			break;

		case 'd':
			if (strcmp(optarg, "read") == 0)
				dir = READ;
			else if (strcmp(optarg, "write") == 0)
				dir = WRITE;
			else if (strcmp(optarg, "clear") == 0)
				dir = CLEAR;
			else if (strcmp(optarg, "fault") == 0)
				dir = FAULT;
			else
				abort();
			break;

		case 't':
			if (strcmp(optarg, "x") == 0)
				tiling = I915_TILING_X;
			else if (strcmp(optarg, "y") == 0)
				tiling = I915_TILING_Y;
			else if (strcmp(optarg, "none") == 0)
				tiling = I915_TILING_NONE;
			else
				abort();
			break;

		case 'r':
			reps = atoi(optarg);
			if (reps < 1)
				reps = 1;
			break;

		default:
			break;
		}
	}

	handle = gem_create(fd, OBJECT_SIZE);
	switch (map) {
	case CPU:
		ptr = gem_mmap__cpu(fd, handle, 0, OBJECT_SIZE, PROT_WRITE);
		gem_set_domain(fd, handle, I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
		break;
	case GTT:
		ptr = gem_mmap__gtt(fd, handle, OBJECT_SIZE, PROT_WRITE);
		gem_set_domain(fd, handle, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
		break;
	case WC:
		ptr = gem_mmap__wc(fd, handle, 0, OBJECT_SIZE, PROT_WRITE);
		gem_set_domain(fd, handle, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
		break;
	default:
		abort();
	}

	gem_set_tiling(fd, handle, tiling, 512);

	if (dir == READ) {
		src = ptr;
		dst = buf;
	} else {
		src = buf;
		dst = ptr;
	}

	clock_gettime(CLOCK_MONOTONIC, &start);
	switch (dir) {
	case CLEAR:
	case FAULT:
		memset(dst, 0, OBJECT_SIZE);
		break;
	default:
		memcpy(dst, src, OBJECT_SIZE);
		break;
	}
	clock_gettime(CLOCK_MONOTONIC, &end);

	loops = 2 / elapsed(&start, &end);
	while (reps--) {
		clock_gettime(CLOCK_MONOTONIC, &start);
		for (c = 0; c < loops; c++) {
			int page;

			switch (dir) {
			case CLEAR:
				memset(dst, 0, OBJECT_SIZE);
				break;
			case FAULT:
				munmap(ptr, OBJECT_SIZE);
				switch (map) {
				case CPU:
					ptr = gem_mmap__cpu(fd, handle, 0, OBJECT_SIZE, PROT_WRITE);
					break;
				case GTT:
					ptr = gem_mmap__gtt(fd, handle, OBJECT_SIZE, PROT_WRITE);
					break;
				case WC:
					ptr = gem_mmap__wc(fd, handle, 0, OBJECT_SIZE, PROT_WRITE);
					break;
				default:
					abort();
				}
				for (page = 0; page < OBJECT_SIZE; page += 4096) {
					uint32_t *x = (uint32_t *)ptr + page/4;
					__asm__ __volatile__("": : :"memory");
					page += *x; /* should be zero! */
				}
				break;
			default:
				memcpy(dst, src, OBJECT_SIZE);
				break;
			}
		}
		clock_gettime(CLOCK_MONOTONIC, &end);
		printf("%7.3f\n", OBJECT_SIZE / elapsed(&start, &end) * loops / (1024*1024));
	}

	return 0;
}