blob: f4cf472ca9bd05b08ee547b620d8a80562f9f69d [file] [log] [blame]
Chris Wilson5d635f92013-08-06 15:18:30 +01001/*
2 * Copyright © 2011 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
Thomas Wood804e11f2015-08-17 17:57:43 +010028#include "igt.h"
Chris Wilson5d635f92013-08-06 15:18:30 +010029#include <unistd.h>
30#include <stdlib.h>
31#include <stdint.h>
32#include <stdio.h>
33#include <string.h>
Chris Wilson5d635f92013-08-06 15:18:30 +010034#include <fcntl.h>
35#include <inttypes.h>
36#include <errno.h>
37#include <sys/stat.h>
38#include <sys/ioctl.h>
Chris Wilson5d635f92013-08-06 15:18:30 +010039#include <sys/time.h>
40#include "drm.h"
Chris Wilson5d635f92013-08-06 15:18:30 +010041
42#define OBJECT_SIZE 16384
Ankitprasad Sharma48c94532015-12-02 14:54:51 +053043#define LARGE_OBJECT_SIZE 1024 * 1024
44#define KGRN "\x1B[32m"
45#define KRED "\x1B[31m"
46#define KNRM "\x1B[0m"
Chris Wilson5d635f92013-08-06 15:18:30 +010047
48static void do_gem_read(int fd, uint32_t handle, void *buf, int len, int loops)
49{
50 while (loops--)
51 gem_read(fd, handle, 0, buf, len);
52}
53
54static double elapsed(const struct timeval *start,
55 const struct timeval *end,
56 int loop)
57{
58 return (1e6*(end->tv_sec - start->tv_sec) + (end->tv_usec - start->tv_usec))/loop;
59}
60
61static const char *bytes_per_sec(char *buf, double v)
62{
63 const char *order[] = {
64 "",
65 "KiB",
66 "MiB",
67 "GiB",
68 "TiB",
69 NULL,
70 }, **o = order;
71
72 while (v > 1000 && o[1]) {
73 v /= 1000;
74 o++;
75 }
76 sprintf(buf, "%.1f%s/s", v, *o);
77 return buf;
78}
79
80
Daniel Vetterb3880d32013-08-14 18:02:46 +020081uint32_t *src, dst;
Ankitprasad Sharma48c94532015-12-02 14:54:51 +053082uint32_t *dst_user, src_stolen, large_stolen;
83uint32_t *stolen_pf_user, *stolen_nopf_user;
Daniel Vetterb3880d32013-08-14 18:02:46 +020084int fd, count;
85
Chris Wilson5d635f92013-08-06 15:18:30 +010086int main(int argc, char **argv)
87{
88 int object_size = 0;
Ankitprasad Sharma48c94532015-12-02 14:54:51 +053089 double usecs;
90 char buf[100];
Chris Wilson866a6f22015-12-12 18:56:37 +000091 const char* bps;
Chris Wilson467796a2013-08-10 15:49:33 +010092 const struct {
93 int level;
94 const char *name;
95 } cache[] = {
96 { 0, "uncached" },
97 { 1, "snoop" },
98 { 2, "display" },
99 { -1 },
100 }, *c;
Chris Wilson5d635f92013-08-06 15:18:30 +0100101
Daniel Vetter1caaf0a2013-08-12 12:17:35 +0200102 igt_subtest_init(argc, argv);
103 igt_skip_on_simulation();
Chris Wilson5d635f92013-08-06 15:18:30 +0100104
Daniel Vetter7553ad62013-08-12 10:43:59 +0200105 if (argc > 1 && atoi(argv[1]))
Chris Wilson5d635f92013-08-06 15:18:30 +0100106 object_size = atoi(argv[1]);
107 if (object_size == 0)
108 object_size = OBJECT_SIZE;
109 object_size = (object_size + 3) & -4;
110
Daniel Vetterb3880d32013-08-14 18:02:46 +0200111 igt_fixture {
Micah Fedkec81d2932015-07-22 21:54:02 +0000112 fd = drm_open_driver(DRIVER_INTEL);
Chris Wilson5d635f92013-08-06 15:18:30 +0100113
Daniel Vetterb3880d32013-08-14 18:02:46 +0200114 dst = gem_create(fd, object_size);
115 src = malloc(object_size);
Ankitprasad Sharma48c94532015-12-02 14:54:51 +0530116 src_stolen = gem_create_stolen(fd, object_size);
117 dst_user = malloc(object_size);
Daniel Vetterb3880d32013-08-14 18:02:46 +0200118 }
Chris Wilson5d635f92013-08-06 15:18:30 +0100119
Jesse Barnes50016402015-08-13 13:08:52 -0700120 igt_subtest("basic") {
Chris Wilson467796a2013-08-10 15:49:33 +0100121 for (count = 1; count <= 1<<17; count <<= 1) {
122 struct timeval start, end;
123
124 gettimeofday(&start, NULL);
125 do_gem_read(fd, dst, src, object_size, count);
126 gettimeofday(&end, NULL);
Ankitprasad Sharma48c94532015-12-02 14:54:51 +0530127 usecs = elapsed(&start, &end, count);
128 bps = bytes_per_sec(buf, object_size/usecs*1e6);
Daniel Vettere624fa82014-05-14 00:36:04 +0200129 igt_info("Time to pread %d bytes x %6d: %7.3fµs, %s\n",
Ankitprasad Sharma48c94532015-12-02 14:54:51 +0530130 object_size, count, usecs, bps);
Chris Wilson467796a2013-08-10 15:49:33 +0100131 fflush(stdout);
132 }
Chris Wilson5d635f92013-08-06 15:18:30 +0100133 }
134
Daniel Vetter7553ad62013-08-12 10:43:59 +0200135 for (c = cache; c->level != -1; c++) {
Daniel Vetter1caaf0a2013-08-12 12:17:35 +0200136 igt_subtest(c->name) {
Daniel Vetter7553ad62013-08-12 10:43:59 +0200137 gem_set_caching(fd, dst, c->level);
138
139 for (count = 1; count <= 1<<17; count <<= 1) {
140 struct timeval start, end;
141
142 gettimeofday(&start, NULL);
143 do_gem_read(fd, dst, src, object_size, count);
144 gettimeofday(&end, NULL);
Ankitprasad Sharma48c94532015-12-02 14:54:51 +0530145 usecs = elapsed(&start, &end, count);
146 bps = bytes_per_sec(buf, object_size/usecs*1e6);
Daniel Vettere624fa82014-05-14 00:36:04 +0200147 igt_info("Time to %s pread %d bytes x %6d: %7.3fµs, %s\n",
Ankitprasad Sharma48c94532015-12-02 14:54:51 +0530148 c->name, object_size, count, usecs, bps);
Daniel Vetter7553ad62013-08-12 10:43:59 +0200149 fflush(stdout);
150 }
151 }
152 }
153
Ankitprasad Sharma48c94532015-12-02 14:54:51 +0530154 igt_subtest("stolen-normal") {
Ankitprasad Sharmabeef31a2016-06-06 14:52:42 +0530155 gem_require_stolen_support(fd);
Ankitprasad Sharma48c94532015-12-02 14:54:51 +0530156 for (count = 1; count <= 1<<17; count <<= 1) {
157 struct timeval start, end;
158
159 gettimeofday(&start, NULL);
160 do_gem_read(fd, src_stolen, dst_user, object_size, count);
161 gettimeofday(&end, NULL);
162 usecs = elapsed(&start, &end, count);
163 bps = bytes_per_sec(buf, object_size/usecs*1e6);
164 igt_info("Time to pread %d bytes x %6d: %7.3fµs, %s\n",
165 object_size, count, usecs, bps);
166 fflush(stdout);
167 }
168 }
169 for (c = cache; c->level != -1; c++) {
170 igt_subtest_f("stolen-%s", c->name) {
Ankitprasad Sharmabeef31a2016-06-06 14:52:42 +0530171 gem_require_stolen_support(fd);
Ankitprasad Sharma48c94532015-12-02 14:54:51 +0530172 gem_set_caching(fd, src_stolen, c->level);
173
174 for (count = 1; count <= 1<<17; count <<= 1) {
175 struct timeval start, end;
176
177 gettimeofday(&start, NULL);
178 do_gem_read(fd, src_stolen, dst_user,
179 object_size, count);
180 gettimeofday(&end, NULL);
181 usecs = elapsed(&start, &end, count);
182 bps = bytes_per_sec(buf, object_size/usecs*1e6);
183 igt_info("Time to stolen-%s pread %d bytes x %6d: %7.3fµs, %s\n",
184 c->name, object_size, count, usecs, bps);
185 fflush(stdout);
186 }
187 }
188 }
189
190 /* List the time taken in pread operation for stolen objects, with
191 * and without the overhead of page fault handling on accessing the
192 * user space buffer
193 */
194 igt_subtest("pagefault-pread") {
Ankitprasad Sharmabeef31a2016-06-06 14:52:42 +0530195 gem_require_stolen_support(fd);
Ankitprasad Sharma48c94532015-12-02 14:54:51 +0530196 large_stolen = gem_create_stolen(fd, LARGE_OBJECT_SIZE);
197 stolen_nopf_user = (uint32_t *) mmap(NULL, LARGE_OBJECT_SIZE,
198 PROT_WRITE,
199 MAP_ANONYMOUS|MAP_PRIVATE,
200 -1, 0);
201 igt_assert(stolen_nopf_user);
202
203 for (count = 1; count <= 10; count ++) {
204 struct timeval start, end;
205 double t_elapsed = 0;
206
207 gettimeofday(&start, NULL);
208 do_gem_read(fd, large_stolen, stolen_nopf_user,
209 LARGE_OBJECT_SIZE, 1);
210 gettimeofday(&end, NULL);
211 t_elapsed = elapsed(&start, &end, count);
212 bps = bytes_per_sec(buf, object_size/t_elapsed*1e6);
213 igt_info("Pagefault-N - Time to pread %d bytes: %7.3fµs, %s\n",
214 LARGE_OBJECT_SIZE, t_elapsed, bps);
215
216 stolen_pf_user = (uint32_t *) mmap(NULL, LARGE_OBJECT_SIZE,
217 PROT_WRITE,
218 MAP_ANONYMOUS|MAP_PRIVATE,
219 -1, 0);
220 igt_assert(stolen_pf_user);
221
222 gettimeofday(&start, NULL);
223 do_gem_read(fd, large_stolen, stolen_pf_user,
224 LARGE_OBJECT_SIZE, 1);
225 gettimeofday(&end, NULL);
226 usecs = elapsed(&start, &end, count);
227 bps = bytes_per_sec(buf, object_size/usecs*1e6);
228 igt_info("Pagefault-Y - Time to pread %d bytes: %7.3fµs, %s%s%s\n",
229 LARGE_OBJECT_SIZE, usecs,
230 t_elapsed < usecs ? KGRN : KRED, bps, KNRM);
231 fflush(stdout);
232 munmap(stolen_pf_user, LARGE_OBJECT_SIZE);
233 }
234 munmap(stolen_nopf_user, LARGE_OBJECT_SIZE);
235 gem_close(fd, large_stolen);
236 }
237
238
Daniel Vetterb3880d32013-08-14 18:02:46 +0200239 igt_fixture {
240 free(src);
241 gem_close(fd, dst);
Ankitprasad Sharma48c94532015-12-02 14:54:51 +0530242 free(dst_user);
243 gem_close(fd, src_stolen);
Chris Wilson5d635f92013-08-06 15:18:30 +0100244
Daniel Vetterb3880d32013-08-14 18:02:46 +0200245 close(fd);
246 }
Chris Wilson5d635f92013-08-06 15:18:30 +0100247
Daniel Vetter68778772013-08-12 12:26:35 +0200248 igt_exit();
Chris Wilson5d635f92013-08-06 15:18:30 +0100249}