• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2013 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  */
24 
25 #include <unistd.h>
26 #include <fcntl.h>
27 #include <errno.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 
32 #include "gem-objects.h"
33 #include "debugfs.h"
34 
35 /* /sys/kernel/debug/dri/0/i915_gem_objects:
36  *	46 objects, 20107264 bytes
37  *	42 [42] objects, 15863808 [15863808] bytes in gtt
38  *	  0 [0] active objects, 0 [0] bytes
39  *	  42 [42] inactive objects, 15863808 [15863808] bytes
40  *	0 unbound objects, 0 bytes
41  *	3 purgeable objects, 4456448 bytes
42  *	30 pinned mappable objects, 3821568 bytes
43  *	1 fault mappable objects, 3145728 bytes
44  *	2145386496 [536870912] gtt total
45  *
46  *	Xorg: 35 objects, 16347136 bytes (0 active, 12103680 inactive, 0 unbound)
47  */
48 
gem_objects_init(struct gem_objects * obj)49 int gem_objects_init(struct gem_objects *obj)
50 {
51 	char buf[8192], *b;
52 	int fd, len;
53 
54 	memset(obj, 0, sizeof(*obj));
55 
56 	sprintf(buf, "%s/i915_gem_objects", debugfs_dri_path);
57 	fd = open(buf, 0);
58 	if (fd < 0)
59 		return errno;
60 	len = read(fd, buf+1, sizeof(buf)-2);
61 	close(fd);
62 
63 	if (len < 0)
64 		return EIO;
65 
66 	/* Add sentinel values for the string searches */
67 	buf[0] = '\n';
68 	buf[len+1] = '\0';
69 
70 	b = strstr(buf, "gtt total");
71 	if (b == NULL)
72 		return EIO;
73 
74 	while (*b != '\n')
75 		b--;
76 
77 	sscanf(b, "%ld [%ld]",
78 	       &obj->max_gtt, &obj->max_aperture);
79 
80 	return 0;
81 }
82 
insert_sorted(struct gem_objects * obj,struct gem_objects_comm * comm)83 static void insert_sorted(struct gem_objects *obj,
84 			  struct gem_objects_comm *comm)
85 {
86 	struct gem_objects_comm *next, **prev;
87 
88 	for (prev = &obj->comm; (next = *prev) != NULL; prev = &next->next)
89 		if (comm->bytes > next->bytes)
90 			break;
91 
92 	comm->next = *prev;
93 	*prev = comm;
94 }
95 
gem_objects_update(struct gem_objects * obj)96 int gem_objects_update(struct gem_objects *obj)
97 {
98 	char buf[8192], *b;
99 	struct gem_objects_comm *comm;
100 	struct gem_objects_comm *freed;
101 	int fd, len, ret;
102 
103 	freed = obj->comm;
104 	obj->comm = NULL;
105 
106 	sprintf(buf, "%s/i915_gem_objects", debugfs_dri_path);
107 	fd = open(buf, 0);
108 	if (fd < 0) {
109 		ret = errno;
110 		goto done;
111 	}
112 	len = read(fd, buf, sizeof(buf)-1);
113 	close(fd);
114 
115 	if (len < 0) {
116 		ret = EIO;
117 		goto done;
118 	}
119 
120 	buf[len] = '\0';
121 	while (buf[--len] == '\n')
122 		buf[len] = '\0';
123 
124 	b = buf;
125 
126 	sscanf(b, "%lu objects, %lu bytes",
127 	       &obj->total_count, &obj->total_bytes);
128 
129 	b = strchr(b, '\n');
130 	sscanf(b, "%*d [%*d] objects, %lu [%lu] bytes in gtt",
131 	       &obj->total_gtt, &obj->total_aperture);
132 
133 	ret = 0;
134 	b = strchr(b, ':');
135 	if (b == NULL)
136 		goto done;
137 
138 	while (*b != '\n')
139 		b--;
140 	b++;
141 
142 	do {
143 		char *eol, *colon;
144 
145 		comm = freed;
146 		if (comm)
147 			freed = comm->next;
148 		else
149 			comm = malloc(sizeof(*comm));
150 		if (comm == NULL)
151 			break;
152 
153 		/* Xorg: 35 objects, 16347136 bytes (0 active, 12103680 inactive, 0 unbound) */
154 		eol = strchr(b, '\n');
155 		if (eol) {
156 			do {
157 			*eol++ = '\0';
158 			} while (*eol == '\n');
159 		}
160 
161 		colon = strchr(b, ':');
162 		memcpy(comm->name, b, colon-b+1);
163 		comm->name[colon-b+1] = '\0';
164 
165 		sscanf(colon + 1, "%lu objects, %lu bytes",
166 		       &comm->count, &comm->bytes);
167 
168 		insert_sorted(obj, comm);
169 		b = eol;
170 	} while (b != NULL);
171 
172 done:
173 	while (freed) {
174 		comm = freed;
175 		freed = comm->next;
176 		free(comm);
177 	}
178 
179 	return ret;
180 }
181