blob: 1e7efacfc6b85a0905ae7098ce7a138381e5df9a [file] [log] [blame]
Chris Wilsoncd306d42015-07-24 18:54:11 +01001/*
2 * Copyright © 2011-2015 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 * Authors:
24 * Chris Wilson <chris@chris-wilson.co.uk>
25 *
26 */
27
28#include <unistd.h>
29#include <stdlib.h>
30#include <stdint.h>
31#include <stdio.h>
32#include <string.h>
33#include <fcntl.h>
34#include <inttypes.h>
35#include <errno.h>
36#include <sys/stat.h>
37#include <sys/ioctl.h>
38#include <sys/time.h>
39#include <time.h>
40
41#include "drm.h"
42#include "ioctl_wrappers.h"
43#include "drmtest.h"
44#include "igt_aux.h"
45#include "igt_stats.h"
46
47#define OBJECT_SIZE (1<<23)
48
49#define LOCAL_I915_EXEC_NO_RELOC (1<<11)
50#define LOCAL_I915_EXEC_HANDLE_LUT (1<<12)
51
Chris Wilsoncd306d42015-07-24 18:54:11 +010052static double elapsed(const struct timespec *start,
53 const struct timespec *end)
54{
55 return (end->tv_sec - start->tv_sec) + 1e-9*(end->tv_nsec - start->tv_nsec);
56}
57
58static void make_busy(int fd, uint32_t handle)
59{
60 struct drm_i915_gem_execbuffer2 execbuf;
61 struct drm_i915_gem_exec_object2 gem_exec;
62
63 const uint32_t buf[] = {MI_BATCH_BUFFER_END};
64 gem_write(fd, handle, 0, buf, sizeof(buf));
65
66 memset(&gem_exec, 0, sizeof(gem_exec));
67 gem_exec.handle = handle;
68
69 memset(&execbuf, 0, sizeof(execbuf));
70 execbuf.buffers_ptr = (uintptr_t)&gem_exec;
71 execbuf.buffer_count = 1;
72 execbuf.flags |= LOCAL_I915_EXEC_HANDLE_LUT;
73 execbuf.flags |= LOCAL_I915_EXEC_NO_RELOC;
74 if (__gem_execbuf(fd, &execbuf)) {
75 execbuf.flags = 0;
76 gem_execbuf(fd, &execbuf);
77 }
78}
79
80int main(int argc, char **argv)
81{
Micah Fedkec81d2932015-07-22 21:54:02 +000082 int fd = drm_open_driver(DRIVER_INTEL);
Chris Wilsoncd306d42015-07-24 18:54:11 +010083 int size = 0;
84 int busy = 0;
85 int reps = 13;
Chris Wilson6ec897c2016-05-07 21:26:56 +010086 int ncpus = 1;
Chris Wilsoncd306d42015-07-24 18:54:11 +010087 int c, n, s;
88
Chris Wilson6ec897c2016-05-07 21:26:56 +010089 while ((c = getopt (argc, argv, "bs:r:f")) != -1) {
Chris Wilsoncd306d42015-07-24 18:54:11 +010090 switch (c) {
91 case 's':
92 size = atoi(optarg);
93 break;
94
95 case 'r':
96 reps = atoi(optarg);
97 if (reps < 1)
98 reps = 1;
99 break;
100
Chris Wilson6ec897c2016-05-07 21:26:56 +0100101 case 'f':
102 ncpus = sysconf(_SC_NPROCESSORS_ONLN);
103 break;
104
Chris Wilsoncd306d42015-07-24 18:54:11 +0100105 case 'b':
106 busy = true;
107 break;
108
109 default:
110 break;
111 }
112 }
113
114 if (size == 0) {
115 for (s = 4096; s <= OBJECT_SIZE; s <<= 1) {
116 igt_stats_t stats;
117
118 igt_stats_init_with_size(&stats, reps);
119 for (n = 0; n < reps; n++) {
120 struct timespec start, end;
121 uint64_t count = 0;
122
123 clock_gettime(CLOCK_MONOTONIC, &start);
124 do {
125 for (c = 0; c < 1000; c++) {
126 uint32_t handle;
127
128 handle = gem_create(fd, s);
129 gem_set_domain(fd, handle,
130 I915_GEM_DOMAIN_GTT,
131 I915_GEM_DOMAIN_GTT);
132 if (busy)
133 make_busy(fd, handle);
134 gem_close(fd, handle);
135 }
136 count += c;
137 clock_gettime(CLOCK_MONOTONIC, &end);
138 } while (end.tv_sec - start.tv_sec < 2);
139
140 igt_stats_push_float(&stats, count / elapsed(&start, &end));
141 }
142 printf("%f\n", igt_stats_get_trimean(&stats));
143 igt_stats_fini(&stats);
144 }
145 } else {
Chris Wilson6ec897c2016-05-07 21:26:56 +0100146 double *shared;
147
148 shared = mmap(0, 4096, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
Chris Wilsoncd306d42015-07-24 18:54:11 +0100149 for (n = 0; n < reps; n++) {
Chris Wilson6ec897c2016-05-07 21:26:56 +0100150 memset(shared, 0, 4096);
Chris Wilsoncd306d42015-07-24 18:54:11 +0100151
Chris Wilson6ec897c2016-05-07 21:26:56 +0100152 igt_fork(child, ncpus) {
153 struct timespec start, end;
154 uint64_t count = 0;
Chris Wilsoncd306d42015-07-24 18:54:11 +0100155
Chris Wilson6ec897c2016-05-07 21:26:56 +0100156 clock_gettime(CLOCK_MONOTONIC, &start);
157 do {
158 for (c = 0; c < 1000; c++) {
159 uint32_t handle;
Chris Wilsoncd306d42015-07-24 18:54:11 +0100160
Chris Wilson6ec897c2016-05-07 21:26:56 +0100161 handle = gem_create(fd, size);
162 gem_set_domain(fd, handle,
163 I915_GEM_DOMAIN_GTT,
164 I915_GEM_DOMAIN_GTT);
165 if (busy)
166 make_busy(fd, handle);
167 gem_close(fd, handle);
168 }
169 count += c;
170 clock_gettime(CLOCK_MONOTONIC, &end);
171 } while (end.tv_sec - start.tv_sec < 2);
172
173 shared[child] = count / elapsed(&start, &end);
174 }
175 igt_waitchildren();
176
177 for (int child = 0; child < ncpus; child++)
178 shared[ncpus] += shared[child];
179
Chris Wilson0a679502016-05-08 14:35:08 +0100180 printf("%7.3f\n", shared[ncpus]);
Chris Wilsoncd306d42015-07-24 18:54:11 +0100181 }
182 }
183
184 return 0;
185}