xref: /aosp_15_r20/external/igt-gpu-tools/benchmarks/gem_userptr_benchmark.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker  * Copyright © 2014 Intel Corporation
3*d83cc019SAndroid Build Coastguard Worker  *
4*d83cc019SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*d83cc019SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
6*d83cc019SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
7*d83cc019SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*d83cc019SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
9*d83cc019SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
10*d83cc019SAndroid Build Coastguard Worker  *
11*d83cc019SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
12*d83cc019SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
13*d83cc019SAndroid Build Coastguard Worker  * Software.
14*d83cc019SAndroid Build Coastguard Worker  *
15*d83cc019SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*d83cc019SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*d83cc019SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*d83cc019SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*d83cc019SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*d83cc019SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*d83cc019SAndroid Build Coastguard Worker  * IN THE SOFTWARE.
22*d83cc019SAndroid Build Coastguard Worker  *
23*d83cc019SAndroid Build Coastguard Worker  * Authors:
24*d83cc019SAndroid Build Coastguard Worker  *    Tvrtko Ursulin <[email protected]>
25*d83cc019SAndroid Build Coastguard Worker  *
26*d83cc019SAndroid Build Coastguard Worker  */
27*d83cc019SAndroid Build Coastguard Worker 
28*d83cc019SAndroid Build Coastguard Worker /** @file gem_userptr_benchmark.c
29*d83cc019SAndroid Build Coastguard Worker  *
30*d83cc019SAndroid Build Coastguard Worker  * Benchmark the userptr code and impact of having userptr surfaces
31*d83cc019SAndroid Build Coastguard Worker  * in process address space on some normal operations.
32*d83cc019SAndroid Build Coastguard Worker  *
33*d83cc019SAndroid Build Coastguard Worker  */
34*d83cc019SAndroid Build Coastguard Worker 
35*d83cc019SAndroid Build Coastguard Worker #include <stdlib.h>
36*d83cc019SAndroid Build Coastguard Worker #include <stdio.h>
37*d83cc019SAndroid Build Coastguard Worker #include <string.h>
38*d83cc019SAndroid Build Coastguard Worker #include <fcntl.h>
39*d83cc019SAndroid Build Coastguard Worker #include <inttypes.h>
40*d83cc019SAndroid Build Coastguard Worker #include <errno.h>
41*d83cc019SAndroid Build Coastguard Worker #include <assert.h>
42*d83cc019SAndroid Build Coastguard Worker #include <sys/stat.h>
43*d83cc019SAndroid Build Coastguard Worker #include <sys/time.h>
44*d83cc019SAndroid Build Coastguard Worker #include <sys/mman.h>
45*d83cc019SAndroid Build Coastguard Worker #include <signal.h>
46*d83cc019SAndroid Build Coastguard Worker 
47*d83cc019SAndroid Build Coastguard Worker #include "drm.h"
48*d83cc019SAndroid Build Coastguard Worker #include "i915_drm.h"
49*d83cc019SAndroid Build Coastguard Worker 
50*d83cc019SAndroid Build Coastguard Worker #include "drmtest.h"
51*d83cc019SAndroid Build Coastguard Worker #include "intel_bufmgr.h"
52*d83cc019SAndroid Build Coastguard Worker #include "intel_batchbuffer.h"
53*d83cc019SAndroid Build Coastguard Worker #include "intel_chipset.h"
54*d83cc019SAndroid Build Coastguard Worker #include "ioctl_wrappers.h"
55*d83cc019SAndroid Build Coastguard Worker #include "igt_aux.h"
56*d83cc019SAndroid Build Coastguard Worker 
57*d83cc019SAndroid Build Coastguard Worker #ifndef PAGE_SIZE
58*d83cc019SAndroid Build Coastguard Worker   #define PAGE_SIZE 4096
59*d83cc019SAndroid Build Coastguard Worker #endif
60*d83cc019SAndroid Build Coastguard Worker 
61*d83cc019SAndroid Build Coastguard Worker static uint32_t userptr_flags = LOCAL_I915_USERPTR_UNSYNCHRONIZED;
62*d83cc019SAndroid Build Coastguard Worker 
63*d83cc019SAndroid Build Coastguard Worker #define BO_SIZE (65536)
64*d83cc019SAndroid Build Coastguard Worker 
gem_userptr_test_unsynchronized(void)65*d83cc019SAndroid Build Coastguard Worker static void gem_userptr_test_unsynchronized(void)
66*d83cc019SAndroid Build Coastguard Worker {
67*d83cc019SAndroid Build Coastguard Worker 	userptr_flags = LOCAL_I915_USERPTR_UNSYNCHRONIZED;
68*d83cc019SAndroid Build Coastguard Worker }
69*d83cc019SAndroid Build Coastguard Worker 
gem_userptr_test_synchronized(void)70*d83cc019SAndroid Build Coastguard Worker static void gem_userptr_test_synchronized(void)
71*d83cc019SAndroid Build Coastguard Worker {
72*d83cc019SAndroid Build Coastguard Worker 	userptr_flags = 0;
73*d83cc019SAndroid Build Coastguard Worker }
74*d83cc019SAndroid Build Coastguard Worker 
75*d83cc019SAndroid Build Coastguard Worker static void **handle_ptr_map;
76*d83cc019SAndroid Build Coastguard Worker static unsigned int num_handle_ptr_map;
77*d83cc019SAndroid Build Coastguard Worker 
add_handle_ptr(uint32_t handle,void * ptr)78*d83cc019SAndroid Build Coastguard Worker static void add_handle_ptr(uint32_t handle, void *ptr)
79*d83cc019SAndroid Build Coastguard Worker {
80*d83cc019SAndroid Build Coastguard Worker 	if (handle >= num_handle_ptr_map) {
81*d83cc019SAndroid Build Coastguard Worker 		handle_ptr_map = realloc(handle_ptr_map,
82*d83cc019SAndroid Build Coastguard Worker 					 (handle + 1000) * sizeof(void*));
83*d83cc019SAndroid Build Coastguard Worker 		num_handle_ptr_map = handle + 1000;
84*d83cc019SAndroid Build Coastguard Worker 	}
85*d83cc019SAndroid Build Coastguard Worker 
86*d83cc019SAndroid Build Coastguard Worker 	handle_ptr_map[handle] = ptr;
87*d83cc019SAndroid Build Coastguard Worker }
88*d83cc019SAndroid Build Coastguard Worker 
get_handle_ptr(uint32_t handle)89*d83cc019SAndroid Build Coastguard Worker static void *get_handle_ptr(uint32_t handle)
90*d83cc019SAndroid Build Coastguard Worker {
91*d83cc019SAndroid Build Coastguard Worker 	return handle_ptr_map[handle];
92*d83cc019SAndroid Build Coastguard Worker }
93*d83cc019SAndroid Build Coastguard Worker 
free_handle_ptr(uint32_t handle)94*d83cc019SAndroid Build Coastguard Worker static void free_handle_ptr(uint32_t handle)
95*d83cc019SAndroid Build Coastguard Worker {
96*d83cc019SAndroid Build Coastguard Worker 	igt_assert(handle < num_handle_ptr_map);
97*d83cc019SAndroid Build Coastguard Worker 	igt_assert(handle_ptr_map[handle]);
98*d83cc019SAndroid Build Coastguard Worker 
99*d83cc019SAndroid Build Coastguard Worker 	free(handle_ptr_map[handle]);
100*d83cc019SAndroid Build Coastguard Worker 	handle_ptr_map[handle] = NULL;
101*d83cc019SAndroid Build Coastguard Worker }
102*d83cc019SAndroid Build Coastguard Worker 
create_userptr_bo(int fd,int size)103*d83cc019SAndroid Build Coastguard Worker static uint32_t create_userptr_bo(int fd, int size)
104*d83cc019SAndroid Build Coastguard Worker {
105*d83cc019SAndroid Build Coastguard Worker 	void *ptr;
106*d83cc019SAndroid Build Coastguard Worker 	uint32_t handle;
107*d83cc019SAndroid Build Coastguard Worker 	int ret;
108*d83cc019SAndroid Build Coastguard Worker 
109*d83cc019SAndroid Build Coastguard Worker 	ret = posix_memalign(&ptr, PAGE_SIZE, size);
110*d83cc019SAndroid Build Coastguard Worker 	igt_assert(ret == 0);
111*d83cc019SAndroid Build Coastguard Worker 
112*d83cc019SAndroid Build Coastguard Worker 	gem_userptr(fd, (uint32_t *)ptr, size, 0, userptr_flags, &handle);
113*d83cc019SAndroid Build Coastguard Worker 	add_handle_ptr(handle, ptr);
114*d83cc019SAndroid Build Coastguard Worker 
115*d83cc019SAndroid Build Coastguard Worker 	return handle;
116*d83cc019SAndroid Build Coastguard Worker }
117*d83cc019SAndroid Build Coastguard Worker 
free_userptr_bo(int fd,uint32_t handle)118*d83cc019SAndroid Build Coastguard Worker static void free_userptr_bo(int fd, uint32_t handle)
119*d83cc019SAndroid Build Coastguard Worker {
120*d83cc019SAndroid Build Coastguard Worker 	gem_close(fd, handle);
121*d83cc019SAndroid Build Coastguard Worker 	free_handle_ptr(handle);
122*d83cc019SAndroid Build Coastguard Worker }
123*d83cc019SAndroid Build Coastguard Worker 
has_userptr(int fd)124*d83cc019SAndroid Build Coastguard Worker static int has_userptr(int fd)
125*d83cc019SAndroid Build Coastguard Worker {
126*d83cc019SAndroid Build Coastguard Worker 	uint32_t handle = 0;
127*d83cc019SAndroid Build Coastguard Worker 	void *ptr;
128*d83cc019SAndroid Build Coastguard Worker 	uint32_t oldflags;
129*d83cc019SAndroid Build Coastguard Worker 	int ret;
130*d83cc019SAndroid Build Coastguard Worker 
131*d83cc019SAndroid Build Coastguard Worker 	assert(posix_memalign(&ptr, PAGE_SIZE, PAGE_SIZE) == 0);
132*d83cc019SAndroid Build Coastguard Worker 	oldflags = userptr_flags;
133*d83cc019SAndroid Build Coastguard Worker 	gem_userptr_test_unsynchronized();
134*d83cc019SAndroid Build Coastguard Worker 	ret = __gem_userptr(fd, ptr, PAGE_SIZE, 0, userptr_flags, &handle);
135*d83cc019SAndroid Build Coastguard Worker 	userptr_flags = oldflags;
136*d83cc019SAndroid Build Coastguard Worker 	if (ret != 0) {
137*d83cc019SAndroid Build Coastguard Worker 		free(ptr);
138*d83cc019SAndroid Build Coastguard Worker 		return 0;
139*d83cc019SAndroid Build Coastguard Worker 	}
140*d83cc019SAndroid Build Coastguard Worker 
141*d83cc019SAndroid Build Coastguard Worker 	gem_close(fd, handle);
142*d83cc019SAndroid Build Coastguard Worker 	free(ptr);
143*d83cc019SAndroid Build Coastguard Worker 
144*d83cc019SAndroid Build Coastguard Worker 	return handle != 0;
145*d83cc019SAndroid Build Coastguard Worker }
146*d83cc019SAndroid Build Coastguard Worker 
147*d83cc019SAndroid Build Coastguard Worker static const unsigned int nr_bos[] = {0, 1, 10, 100, 1000, 10000};
148*d83cc019SAndroid Build Coastguard Worker static const unsigned int test_duration_sec = 3;
149*d83cc019SAndroid Build Coastguard Worker 
150*d83cc019SAndroid Build Coastguard Worker static volatile unsigned int run_test;
151*d83cc019SAndroid Build Coastguard Worker 
alarm_handler(int sig)152*d83cc019SAndroid Build Coastguard Worker static void alarm_handler(int sig)
153*d83cc019SAndroid Build Coastguard Worker {
154*d83cc019SAndroid Build Coastguard Worker 	assert(run_test == 1);
155*d83cc019SAndroid Build Coastguard Worker 	run_test = 0;
156*d83cc019SAndroid Build Coastguard Worker }
157*d83cc019SAndroid Build Coastguard Worker 
start_test(unsigned int duration)158*d83cc019SAndroid Build Coastguard Worker static void start_test(unsigned int duration)
159*d83cc019SAndroid Build Coastguard Worker {
160*d83cc019SAndroid Build Coastguard Worker 	run_test = 1;
161*d83cc019SAndroid Build Coastguard Worker 	if (duration == 0)
162*d83cc019SAndroid Build Coastguard Worker 		duration = test_duration_sec;
163*d83cc019SAndroid Build Coastguard Worker 	signal(SIGALRM, alarm_handler);
164*d83cc019SAndroid Build Coastguard Worker 	alarm(duration);
165*d83cc019SAndroid Build Coastguard Worker }
166*d83cc019SAndroid Build Coastguard Worker 
exchange_ptr(void * array,unsigned i,unsigned j)167*d83cc019SAndroid Build Coastguard Worker static void exchange_ptr(void *array, unsigned i, unsigned j)
168*d83cc019SAndroid Build Coastguard Worker {
169*d83cc019SAndroid Build Coastguard Worker 	void **arr, *tmp;
170*d83cc019SAndroid Build Coastguard Worker 	arr = (void **)array;
171*d83cc019SAndroid Build Coastguard Worker 
172*d83cc019SAndroid Build Coastguard Worker 	tmp = arr[i];
173*d83cc019SAndroid Build Coastguard Worker 	arr[i] = arr[j];
174*d83cc019SAndroid Build Coastguard Worker 	arr[j] = tmp;
175*d83cc019SAndroid Build Coastguard Worker }
176*d83cc019SAndroid Build Coastguard Worker 
test_malloc_free(int random)177*d83cc019SAndroid Build Coastguard Worker static void test_malloc_free(int random)
178*d83cc019SAndroid Build Coastguard Worker {
179*d83cc019SAndroid Build Coastguard Worker 	unsigned long iter = 0;
180*d83cc019SAndroid Build Coastguard Worker 	unsigned int i, tot = 1000;
181*d83cc019SAndroid Build Coastguard Worker 	void *ptr[tot];
182*d83cc019SAndroid Build Coastguard Worker 
183*d83cc019SAndroid Build Coastguard Worker 	start_test(test_duration_sec);
184*d83cc019SAndroid Build Coastguard Worker 
185*d83cc019SAndroid Build Coastguard Worker 	while (run_test) {
186*d83cc019SAndroid Build Coastguard Worker 		for (i = 0; i < tot; i++) {
187*d83cc019SAndroid Build Coastguard Worker 			ptr[i] = malloc(1000);
188*d83cc019SAndroid Build Coastguard Worker 			assert(ptr[i]);
189*d83cc019SAndroid Build Coastguard Worker 		}
190*d83cc019SAndroid Build Coastguard Worker 		if (random)
191*d83cc019SAndroid Build Coastguard Worker 			igt_permute_array(ptr, tot, exchange_ptr);
192*d83cc019SAndroid Build Coastguard Worker 		for (i = 0; i < tot; i++)
193*d83cc019SAndroid Build Coastguard Worker 			free(ptr[i]);
194*d83cc019SAndroid Build Coastguard Worker 		iter++;
195*d83cc019SAndroid Build Coastguard Worker 	}
196*d83cc019SAndroid Build Coastguard Worker 
197*d83cc019SAndroid Build Coastguard Worker 	printf("%8lu iter/s\n", iter / test_duration_sec);
198*d83cc019SAndroid Build Coastguard Worker }
199*d83cc019SAndroid Build Coastguard Worker 
test_malloc_realloc_free(int random)200*d83cc019SAndroid Build Coastguard Worker static void test_malloc_realloc_free(int random)
201*d83cc019SAndroid Build Coastguard Worker {
202*d83cc019SAndroid Build Coastguard Worker 	unsigned long iter = 0;
203*d83cc019SAndroid Build Coastguard Worker 	unsigned int i, tot = 1000;
204*d83cc019SAndroid Build Coastguard Worker 	void *ptr[tot];
205*d83cc019SAndroid Build Coastguard Worker 
206*d83cc019SAndroid Build Coastguard Worker 	start_test(test_duration_sec);
207*d83cc019SAndroid Build Coastguard Worker 
208*d83cc019SAndroid Build Coastguard Worker 	while (run_test) {
209*d83cc019SAndroid Build Coastguard Worker 		for (i = 0; i < tot; i++) {
210*d83cc019SAndroid Build Coastguard Worker 			ptr[i] = malloc(1000);
211*d83cc019SAndroid Build Coastguard Worker 			assert(ptr[i]);
212*d83cc019SAndroid Build Coastguard Worker 		}
213*d83cc019SAndroid Build Coastguard Worker 		if (random)
214*d83cc019SAndroid Build Coastguard Worker 			igt_permute_array(ptr, tot, exchange_ptr);
215*d83cc019SAndroid Build Coastguard Worker 		for (i = 0; i < tot; i++) {
216*d83cc019SAndroid Build Coastguard Worker 			ptr[i] = realloc(ptr[i], 2000);
217*d83cc019SAndroid Build Coastguard Worker 			assert(ptr[i]);
218*d83cc019SAndroid Build Coastguard Worker 		}
219*d83cc019SAndroid Build Coastguard Worker 		if (random)
220*d83cc019SAndroid Build Coastguard Worker 			igt_permute_array(ptr, tot, exchange_ptr);
221*d83cc019SAndroid Build Coastguard Worker 		for (i = 0; i < tot; i++)
222*d83cc019SAndroid Build Coastguard Worker 			free(ptr[i]);
223*d83cc019SAndroid Build Coastguard Worker 		iter++;
224*d83cc019SAndroid Build Coastguard Worker 	}
225*d83cc019SAndroid Build Coastguard Worker 
226*d83cc019SAndroid Build Coastguard Worker 	printf("%8lu iter/s\n", iter / test_duration_sec);
227*d83cc019SAndroid Build Coastguard Worker }
228*d83cc019SAndroid Build Coastguard Worker 
test_mmap_unmap(int random)229*d83cc019SAndroid Build Coastguard Worker static void test_mmap_unmap(int random)
230*d83cc019SAndroid Build Coastguard Worker {
231*d83cc019SAndroid Build Coastguard Worker 	unsigned long iter = 0;
232*d83cc019SAndroid Build Coastguard Worker 	unsigned int i, tot = 1000;
233*d83cc019SAndroid Build Coastguard Worker 	void *ptr[tot];
234*d83cc019SAndroid Build Coastguard Worker 
235*d83cc019SAndroid Build Coastguard Worker 	start_test(test_duration_sec);
236*d83cc019SAndroid Build Coastguard Worker 
237*d83cc019SAndroid Build Coastguard Worker 	while (run_test) {
238*d83cc019SAndroid Build Coastguard Worker 		for (i = 0; i < tot; i++) {
239*d83cc019SAndroid Build Coastguard Worker 			ptr[i] = mmap(NULL, 1000, PROT_READ | PROT_WRITE,
240*d83cc019SAndroid Build Coastguard Worker 					MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
241*d83cc019SAndroid Build Coastguard Worker 			assert(ptr[i] != MAP_FAILED);
242*d83cc019SAndroid Build Coastguard Worker 		}
243*d83cc019SAndroid Build Coastguard Worker 		if (random)
244*d83cc019SAndroid Build Coastguard Worker 			igt_permute_array(ptr, tot, exchange_ptr);
245*d83cc019SAndroid Build Coastguard Worker 		for (i = 0; i < tot; i++)
246*d83cc019SAndroid Build Coastguard Worker 			munmap(ptr[i], 1000);
247*d83cc019SAndroid Build Coastguard Worker 		iter++;
248*d83cc019SAndroid Build Coastguard Worker 	}
249*d83cc019SAndroid Build Coastguard Worker 
250*d83cc019SAndroid Build Coastguard Worker 	printf("%8lu iter/s\n", iter / test_duration_sec);
251*d83cc019SAndroid Build Coastguard Worker }
252*d83cc019SAndroid Build Coastguard Worker 
test_ptr_read(void * ptr)253*d83cc019SAndroid Build Coastguard Worker static void test_ptr_read(void *ptr)
254*d83cc019SAndroid Build Coastguard Worker {
255*d83cc019SAndroid Build Coastguard Worker 	unsigned long iter = 0;
256*d83cc019SAndroid Build Coastguard Worker 	volatile unsigned long *p;
257*d83cc019SAndroid Build Coastguard Worker 	unsigned long i, loops;
258*d83cc019SAndroid Build Coastguard Worker 
259*d83cc019SAndroid Build Coastguard Worker 	loops = BO_SIZE / sizeof(unsigned long) / 4;
260*d83cc019SAndroid Build Coastguard Worker 
261*d83cc019SAndroid Build Coastguard Worker 	start_test(test_duration_sec);
262*d83cc019SAndroid Build Coastguard Worker 
263*d83cc019SAndroid Build Coastguard Worker 	while (run_test) {
264*d83cc019SAndroid Build Coastguard Worker 		p = (unsigned long *)ptr;
265*d83cc019SAndroid Build Coastguard Worker 		for (i = 0; i < loops; i++) {
266*d83cc019SAndroid Build Coastguard Worker 			(void)*p++;
267*d83cc019SAndroid Build Coastguard Worker 			(void)*p++;
268*d83cc019SAndroid Build Coastguard Worker 			(void)*p++;
269*d83cc019SAndroid Build Coastguard Worker 			(void)*p++;
270*d83cc019SAndroid Build Coastguard Worker 		}
271*d83cc019SAndroid Build Coastguard Worker 		iter++;
272*d83cc019SAndroid Build Coastguard Worker 	}
273*d83cc019SAndroid Build Coastguard Worker 
274*d83cc019SAndroid Build Coastguard Worker 	printf("%8lu MB/s\n", iter / test_duration_sec * BO_SIZE / 1000000);
275*d83cc019SAndroid Build Coastguard Worker }
276*d83cc019SAndroid Build Coastguard Worker 
test_ptr_write(void * ptr)277*d83cc019SAndroid Build Coastguard Worker static void test_ptr_write(void *ptr)
278*d83cc019SAndroid Build Coastguard Worker {
279*d83cc019SAndroid Build Coastguard Worker 	unsigned long iter = 0;
280*d83cc019SAndroid Build Coastguard Worker 	volatile unsigned long *p;
281*d83cc019SAndroid Build Coastguard Worker 	register unsigned long i, loops;
282*d83cc019SAndroid Build Coastguard Worker 
283*d83cc019SAndroid Build Coastguard Worker 	loops = BO_SIZE / sizeof(unsigned long) / 4;
284*d83cc019SAndroid Build Coastguard Worker 
285*d83cc019SAndroid Build Coastguard Worker 	start_test(test_duration_sec);
286*d83cc019SAndroid Build Coastguard Worker 
287*d83cc019SAndroid Build Coastguard Worker 	while (run_test) {
288*d83cc019SAndroid Build Coastguard Worker 		p = (unsigned long *)ptr;
289*d83cc019SAndroid Build Coastguard Worker 		for (i = 0; i < loops; i++) {
290*d83cc019SAndroid Build Coastguard Worker 			*p++ = i;
291*d83cc019SAndroid Build Coastguard Worker 			*p++ = i;
292*d83cc019SAndroid Build Coastguard Worker 			*p++ = i;
293*d83cc019SAndroid Build Coastguard Worker 			*p++ = i;
294*d83cc019SAndroid Build Coastguard Worker 		}
295*d83cc019SAndroid Build Coastguard Worker 		iter++;
296*d83cc019SAndroid Build Coastguard Worker 	}
297*d83cc019SAndroid Build Coastguard Worker 
298*d83cc019SAndroid Build Coastguard Worker 	printf("%8lu MB/s\n", iter / test_duration_sec * BO_SIZE / 1000000);
299*d83cc019SAndroid Build Coastguard Worker }
300*d83cc019SAndroid Build Coastguard Worker 
do_impact_tests(unsigned int n,const char * pfix,const char * pfix2,void * ptr)301*d83cc019SAndroid Build Coastguard Worker static void do_impact_tests(unsigned int n, const char *pfix, const char *pfix2,
302*d83cc019SAndroid Build Coastguard Worker 			    void *ptr)
303*d83cc019SAndroid Build Coastguard Worker {
304*d83cc019SAndroid Build Coastguard Worker 	printf("%s%sptr-read,                   %5u bos = ", pfix, pfix2, n);
305*d83cc019SAndroid Build Coastguard Worker 	test_ptr_read(ptr);
306*d83cc019SAndroid Build Coastguard Worker 
307*d83cc019SAndroid Build Coastguard Worker 	printf("%s%sptr-write                   %5u bos = ", pfix, pfix2, n);
308*d83cc019SAndroid Build Coastguard Worker 	test_ptr_write(ptr);
309*d83cc019SAndroid Build Coastguard Worker 
310*d83cc019SAndroid Build Coastguard Worker 	printf("%s%smalloc-free,                %5u bos = ", pfix, pfix2, n);
311*d83cc019SAndroid Build Coastguard Worker 	test_malloc_free(0);
312*d83cc019SAndroid Build Coastguard Worker 	printf("%s%smalloc-free-random          %5u bos = ", pfix, pfix2, n);
313*d83cc019SAndroid Build Coastguard Worker 	test_malloc_free(1);
314*d83cc019SAndroid Build Coastguard Worker 
315*d83cc019SAndroid Build Coastguard Worker 	printf("%s%smalloc-realloc-free,        %5u bos = ", pfix, pfix2, n);
316*d83cc019SAndroid Build Coastguard Worker 	test_malloc_realloc_free(0);
317*d83cc019SAndroid Build Coastguard Worker 	printf("%s%smalloc-realloc-free-random, %5u bos = ", pfix, pfix2, n);
318*d83cc019SAndroid Build Coastguard Worker 	test_malloc_realloc_free(1);
319*d83cc019SAndroid Build Coastguard Worker 
320*d83cc019SAndroid Build Coastguard Worker 	printf("%s%smmap-unmap,                 %5u bos = ", pfix, pfix2, n);
321*d83cc019SAndroid Build Coastguard Worker 	test_mmap_unmap(0);
322*d83cc019SAndroid Build Coastguard Worker 	printf("%s%smmap-unmap-random,          %5u bos = ", pfix, pfix2, n);
323*d83cc019SAndroid Build Coastguard Worker 	test_mmap_unmap(1);
324*d83cc019SAndroid Build Coastguard Worker }
325*d83cc019SAndroid Build Coastguard Worker 
test_impact_overlap(int fd,const char * prefix)326*d83cc019SAndroid Build Coastguard Worker static void test_impact_overlap(int fd, const char *prefix)
327*d83cc019SAndroid Build Coastguard Worker {
328*d83cc019SAndroid Build Coastguard Worker 	unsigned int total = sizeof(nr_bos) / sizeof(nr_bos[0]);
329*d83cc019SAndroid Build Coastguard Worker 	unsigned int subtest, i;
330*d83cc019SAndroid Build Coastguard Worker 	uint32_t handles[nr_bos[total-1]];
331*d83cc019SAndroid Build Coastguard Worker 	void *block = NULL;
332*d83cc019SAndroid Build Coastguard Worker 	void *ptr;
333*d83cc019SAndroid Build Coastguard Worker 	unsigned char *p;
334*d83cc019SAndroid Build Coastguard Worker 	char buffer[BO_SIZE];
335*d83cc019SAndroid Build Coastguard Worker 	int ret;
336*d83cc019SAndroid Build Coastguard Worker 
337*d83cc019SAndroid Build Coastguard Worker 	for (subtest = 0; subtest < total; subtest++) {
338*d83cc019SAndroid Build Coastguard Worker 		if (nr_bos[subtest] > 0) {
339*d83cc019SAndroid Build Coastguard Worker 			igt_assert(PAGE_SIZE < BO_SIZE);
340*d83cc019SAndroid Build Coastguard Worker 			ret = posix_memalign(&block, PAGE_SIZE,
341*d83cc019SAndroid Build Coastguard Worker 					PAGE_SIZE * nr_bos[subtest] + BO_SIZE);
342*d83cc019SAndroid Build Coastguard Worker 			igt_assert(ret == 0);
343*d83cc019SAndroid Build Coastguard Worker 
344*d83cc019SAndroid Build Coastguard Worker 			for (i = 0, p = block; i < nr_bos[subtest];
345*d83cc019SAndroid Build Coastguard Worker 			     i++, p += PAGE_SIZE)
346*d83cc019SAndroid Build Coastguard Worker 				gem_userptr(fd, (uint32_t *)p, BO_SIZE, 0, userptr_flags, &handles[i]);
347*d83cc019SAndroid Build Coastguard Worker 		}
348*d83cc019SAndroid Build Coastguard Worker 
349*d83cc019SAndroid Build Coastguard Worker 		if (nr_bos[subtest] > 0)
350*d83cc019SAndroid Build Coastguard Worker 			ptr = block;
351*d83cc019SAndroid Build Coastguard Worker 		else
352*d83cc019SAndroid Build Coastguard Worker 			ptr = buffer;
353*d83cc019SAndroid Build Coastguard Worker 
354*d83cc019SAndroid Build Coastguard Worker 		do_impact_tests(nr_bos[subtest], prefix, "overlap-", ptr);
355*d83cc019SAndroid Build Coastguard Worker 
356*d83cc019SAndroid Build Coastguard Worker 		for (i = 0; i < nr_bos[subtest]; i++)
357*d83cc019SAndroid Build Coastguard Worker 			gem_close(fd, handles[i]);
358*d83cc019SAndroid Build Coastguard Worker 
359*d83cc019SAndroid Build Coastguard Worker 		free(block);
360*d83cc019SAndroid Build Coastguard Worker 		block = NULL;
361*d83cc019SAndroid Build Coastguard Worker 	}
362*d83cc019SAndroid Build Coastguard Worker }
363*d83cc019SAndroid Build Coastguard Worker 
test_impact(int fd,const char * prefix)364*d83cc019SAndroid Build Coastguard Worker static void test_impact(int fd, const char *prefix)
365*d83cc019SAndroid Build Coastguard Worker {
366*d83cc019SAndroid Build Coastguard Worker 	unsigned int total = sizeof(nr_bos) / sizeof(nr_bos[0]);
367*d83cc019SAndroid Build Coastguard Worker 	unsigned int subtest, i;
368*d83cc019SAndroid Build Coastguard Worker 	uint32_t handles[nr_bos[total-1]];
369*d83cc019SAndroid Build Coastguard Worker 	void *ptr;
370*d83cc019SAndroid Build Coastguard Worker 	char buffer[BO_SIZE];
371*d83cc019SAndroid Build Coastguard Worker 
372*d83cc019SAndroid Build Coastguard Worker 	for (subtest = 0; subtest < total; subtest++) {
373*d83cc019SAndroid Build Coastguard Worker 		for (i = 0; i < nr_bos[subtest]; i++)
374*d83cc019SAndroid Build Coastguard Worker 			handles[i] = create_userptr_bo(fd, BO_SIZE);
375*d83cc019SAndroid Build Coastguard Worker 
376*d83cc019SAndroid Build Coastguard Worker 		if (nr_bos[subtest] > 0)
377*d83cc019SAndroid Build Coastguard Worker 			ptr = get_handle_ptr(handles[0]);
378*d83cc019SAndroid Build Coastguard Worker 		else
379*d83cc019SAndroid Build Coastguard Worker 			ptr = buffer;
380*d83cc019SAndroid Build Coastguard Worker 
381*d83cc019SAndroid Build Coastguard Worker 		do_impact_tests(nr_bos[subtest], prefix, "no-overlap-", ptr);
382*d83cc019SAndroid Build Coastguard Worker 
383*d83cc019SAndroid Build Coastguard Worker 		for (i = 0; i < nr_bos[subtest]; i++)
384*d83cc019SAndroid Build Coastguard Worker 			free_userptr_bo(fd, handles[i]);
385*d83cc019SAndroid Build Coastguard Worker 	}
386*d83cc019SAndroid Build Coastguard Worker }
387*d83cc019SAndroid Build Coastguard Worker 
test_single(int fd)388*d83cc019SAndroid Build Coastguard Worker static void test_single(int fd)
389*d83cc019SAndroid Build Coastguard Worker {
390*d83cc019SAndroid Build Coastguard Worker 	char *ptr, *bo_ptr;
391*d83cc019SAndroid Build Coastguard Worker 	uint32_t handle = 0;
392*d83cc019SAndroid Build Coastguard Worker 	unsigned long iter = 0;
393*d83cc019SAndroid Build Coastguard Worker 	unsigned long map_size = BO_SIZE + PAGE_SIZE - 1;
394*d83cc019SAndroid Build Coastguard Worker 
395*d83cc019SAndroid Build Coastguard Worker 	ptr = mmap(NULL, map_size, PROT_READ | PROT_WRITE,
396*d83cc019SAndroid Build Coastguard Worker 			MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
397*d83cc019SAndroid Build Coastguard Worker 	assert(ptr != MAP_FAILED);
398*d83cc019SAndroid Build Coastguard Worker 
399*d83cc019SAndroid Build Coastguard Worker 	bo_ptr = (char *)ALIGN((unsigned long)ptr, PAGE_SIZE);
400*d83cc019SAndroid Build Coastguard Worker 
401*d83cc019SAndroid Build Coastguard Worker 	start_test(test_duration_sec);
402*d83cc019SAndroid Build Coastguard Worker 
403*d83cc019SAndroid Build Coastguard Worker 	while (run_test) {
404*d83cc019SAndroid Build Coastguard Worker 		gem_userptr(fd, bo_ptr, BO_SIZE, 0, userptr_flags, &handle);
405*d83cc019SAndroid Build Coastguard Worker 		gem_close(fd, handle);
406*d83cc019SAndroid Build Coastguard Worker 		iter++;
407*d83cc019SAndroid Build Coastguard Worker 	}
408*d83cc019SAndroid Build Coastguard Worker 
409*d83cc019SAndroid Build Coastguard Worker 	munmap(ptr, map_size);
410*d83cc019SAndroid Build Coastguard Worker 
411*d83cc019SAndroid Build Coastguard Worker 	printf("%8lu iter/s\n", iter / test_duration_sec);
412*d83cc019SAndroid Build Coastguard Worker }
413*d83cc019SAndroid Build Coastguard Worker 
test_multiple(int fd,unsigned int batch,int random)414*d83cc019SAndroid Build Coastguard Worker static void test_multiple(int fd, unsigned int batch, int random)
415*d83cc019SAndroid Build Coastguard Worker {
416*d83cc019SAndroid Build Coastguard Worker 	char *ptr, *bo_ptr;
417*d83cc019SAndroid Build Coastguard Worker 	uint32_t handles[10000];
418*d83cc019SAndroid Build Coastguard Worker 	int map[10000];
419*d83cc019SAndroid Build Coastguard Worker 	unsigned long iter = 0;
420*d83cc019SAndroid Build Coastguard Worker 	int i;
421*d83cc019SAndroid Build Coastguard Worker 	unsigned long map_size = batch * BO_SIZE + PAGE_SIZE - 1;
422*d83cc019SAndroid Build Coastguard Worker 
423*d83cc019SAndroid Build Coastguard Worker 	assert(batch < (sizeof(handles) / sizeof(handles[0])));
424*d83cc019SAndroid Build Coastguard Worker 	assert(batch < (sizeof(map) / sizeof(map[0])));
425*d83cc019SAndroid Build Coastguard Worker 
426*d83cc019SAndroid Build Coastguard Worker 	ptr = mmap(NULL, map_size, PROT_READ | PROT_WRITE,
427*d83cc019SAndroid Build Coastguard Worker 			MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
428*d83cc019SAndroid Build Coastguard Worker 	assert(ptr != MAP_FAILED);
429*d83cc019SAndroid Build Coastguard Worker 
430*d83cc019SAndroid Build Coastguard Worker 	bo_ptr = (char *)ALIGN((unsigned long)ptr, PAGE_SIZE);
431*d83cc019SAndroid Build Coastguard Worker 
432*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < batch; i++)
433*d83cc019SAndroid Build Coastguard Worker 		map[i] = i;
434*d83cc019SAndroid Build Coastguard Worker 
435*d83cc019SAndroid Build Coastguard Worker 	start_test(test_duration_sec);
436*d83cc019SAndroid Build Coastguard Worker 
437*d83cc019SAndroid Build Coastguard Worker 	while (run_test) {
438*d83cc019SAndroid Build Coastguard Worker 		if (random)
439*d83cc019SAndroid Build Coastguard Worker 			igt_permute_array(map, batch, igt_exchange_int);
440*d83cc019SAndroid Build Coastguard Worker 		for (i = 0; i < batch; i++) {
441*d83cc019SAndroid Build Coastguard Worker 			gem_userptr(fd, bo_ptr + map[i] * BO_SIZE, BO_SIZE,
442*d83cc019SAndroid Build Coastguard Worker 						0, userptr_flags, &handles[i]);
443*d83cc019SAndroid Build Coastguard Worker 		}
444*d83cc019SAndroid Build Coastguard Worker 		if (random)
445*d83cc019SAndroid Build Coastguard Worker 			igt_permute_array(map, batch, igt_exchange_int);
446*d83cc019SAndroid Build Coastguard Worker 		for (i = 0; i < batch; i++)
447*d83cc019SAndroid Build Coastguard Worker 			gem_close(fd, handles[map[i]]);
448*d83cc019SAndroid Build Coastguard Worker 		iter++;
449*d83cc019SAndroid Build Coastguard Worker 	}
450*d83cc019SAndroid Build Coastguard Worker 
451*d83cc019SAndroid Build Coastguard Worker 	munmap(ptr, map_size);
452*d83cc019SAndroid Build Coastguard Worker 
453*d83cc019SAndroid Build Coastguard Worker 	printf("%8lu iter/s\n", iter * batch / test_duration_sec);
454*d83cc019SAndroid Build Coastguard Worker }
455*d83cc019SAndroid Build Coastguard Worker 
test_userptr(int fd)456*d83cc019SAndroid Build Coastguard Worker static void test_userptr(int fd)
457*d83cc019SAndroid Build Coastguard Worker {
458*d83cc019SAndroid Build Coastguard Worker 	printf("create-destroy                = ");
459*d83cc019SAndroid Build Coastguard Worker 	test_single(fd);
460*d83cc019SAndroid Build Coastguard Worker 
461*d83cc019SAndroid Build Coastguard Worker 	printf("multi-create-destroy          = ");
462*d83cc019SAndroid Build Coastguard Worker 	test_multiple(fd, 100, 0);
463*d83cc019SAndroid Build Coastguard Worker 
464*d83cc019SAndroid Build Coastguard Worker 	printf("multi-create-destroy-random   = ");
465*d83cc019SAndroid Build Coastguard Worker 	test_multiple(fd, 100, 1);
466*d83cc019SAndroid Build Coastguard Worker }
467*d83cc019SAndroid Build Coastguard Worker 
main(int argc,char ** argv)468*d83cc019SAndroid Build Coastguard Worker int main(int argc, char **argv)
469*d83cc019SAndroid Build Coastguard Worker {
470*d83cc019SAndroid Build Coastguard Worker 	int fd = -1, ret;
471*d83cc019SAndroid Build Coastguard Worker 
472*d83cc019SAndroid Build Coastguard Worker 	igt_skip_on_simulation();
473*d83cc019SAndroid Build Coastguard Worker 
474*d83cc019SAndroid Build Coastguard Worker 	igt_subtest_init(argc, argv);
475*d83cc019SAndroid Build Coastguard Worker 
476*d83cc019SAndroid Build Coastguard Worker 	fd = drm_open_driver(DRIVER_INTEL);
477*d83cc019SAndroid Build Coastguard Worker 	igt_assert(fd >= 0);
478*d83cc019SAndroid Build Coastguard Worker 
479*d83cc019SAndroid Build Coastguard Worker 	ret = has_userptr(fd);
480*d83cc019SAndroid Build Coastguard Worker 	igt_skip_on_f(ret == 0, "No userptr support - %s (%d)\n",
481*d83cc019SAndroid Build Coastguard Worker 			strerror(errno), ret);
482*d83cc019SAndroid Build Coastguard Worker 
483*d83cc019SAndroid Build Coastguard Worker 
484*d83cc019SAndroid Build Coastguard Worker 	gem_userptr_test_unsynchronized();
485*d83cc019SAndroid Build Coastguard Worker 
486*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("userptr-unsync")
487*d83cc019SAndroid Build Coastguard Worker 		test_userptr(fd);
488*d83cc019SAndroid Build Coastguard Worker 
489*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("userptr-impact-unsync")
490*d83cc019SAndroid Build Coastguard Worker 		test_impact(fd, "unsync-");
491*d83cc019SAndroid Build Coastguard Worker 
492*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("userptr-impact-unsync-overlap")
493*d83cc019SAndroid Build Coastguard Worker 		test_impact_overlap(fd, "unsync-");
494*d83cc019SAndroid Build Coastguard Worker 
495*d83cc019SAndroid Build Coastguard Worker 	gem_userptr_test_synchronized();
496*d83cc019SAndroid Build Coastguard Worker 
497*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("userptr-sync")
498*d83cc019SAndroid Build Coastguard Worker 		test_userptr(fd);
499*d83cc019SAndroid Build Coastguard Worker 
500*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("userptr-impact-sync")
501*d83cc019SAndroid Build Coastguard Worker 		test_impact(fd, "sync-");
502*d83cc019SAndroid Build Coastguard Worker 
503*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("userptr-impact-sync-overlap")
504*d83cc019SAndroid Build Coastguard Worker 		test_impact_overlap(fd, "sync-");
505*d83cc019SAndroid Build Coastguard Worker 
506*d83cc019SAndroid Build Coastguard Worker 	igt_exit();
507*d83cc019SAndroid Build Coastguard Worker 
508*d83cc019SAndroid Build Coastguard Worker 	return 0;
509*d83cc019SAndroid Build Coastguard Worker }
510