i915_gem_proc.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. /*
  2. * Copyright © 2008 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. * Eric Anholt <eric@anholt.net>
  25. * Keith Packard <keithp@keithp.com>
  26. *
  27. */
  28. #include "drmP.h"
  29. #include "drm.h"
  30. #include "i915_drm.h"
  31. #include "i915_drv.h"
  32. static int i915_gem_active_info(char *buf, char **start, off_t offset,
  33. int request, int *eof, void *data)
  34. {
  35. struct drm_minor *minor = (struct drm_minor *) data;
  36. struct drm_device *dev = minor->dev;
  37. drm_i915_private_t *dev_priv = dev->dev_private;
  38. struct drm_i915_gem_object *obj_priv;
  39. int len = 0;
  40. if (offset > DRM_PROC_LIMIT) {
  41. *eof = 1;
  42. return 0;
  43. }
  44. *start = &buf[offset];
  45. *eof = 0;
  46. DRM_PROC_PRINT("Active:\n");
  47. list_for_each_entry(obj_priv, &dev_priv->mm.active_list,
  48. list)
  49. {
  50. struct drm_gem_object *obj = obj_priv->obj;
  51. if (obj->name) {
  52. DRM_PROC_PRINT(" %p(%d): %08x %08x %d\n",
  53. obj, obj->name,
  54. obj->read_domains, obj->write_domain,
  55. obj_priv->last_rendering_seqno);
  56. } else {
  57. DRM_PROC_PRINT(" %p: %08x %08x %d\n",
  58. obj,
  59. obj->read_domains, obj->write_domain,
  60. obj_priv->last_rendering_seqno);
  61. }
  62. }
  63. if (len > request + offset)
  64. return request;
  65. *eof = 1;
  66. return len - offset;
  67. }
  68. static int i915_gem_flushing_info(char *buf, char **start, off_t offset,
  69. int request, int *eof, void *data)
  70. {
  71. struct drm_minor *minor = (struct drm_minor *) data;
  72. struct drm_device *dev = minor->dev;
  73. drm_i915_private_t *dev_priv = dev->dev_private;
  74. struct drm_i915_gem_object *obj_priv;
  75. int len = 0;
  76. if (offset > DRM_PROC_LIMIT) {
  77. *eof = 1;
  78. return 0;
  79. }
  80. *start = &buf[offset];
  81. *eof = 0;
  82. DRM_PROC_PRINT("Flushing:\n");
  83. list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list,
  84. list)
  85. {
  86. struct drm_gem_object *obj = obj_priv->obj;
  87. if (obj->name) {
  88. DRM_PROC_PRINT(" %p(%d): %08x %08x %d\n",
  89. obj, obj->name,
  90. obj->read_domains, obj->write_domain,
  91. obj_priv->last_rendering_seqno);
  92. } else {
  93. DRM_PROC_PRINT(" %p: %08x %08x %d\n", obj,
  94. obj->read_domains, obj->write_domain,
  95. obj_priv->last_rendering_seqno);
  96. }
  97. }
  98. if (len > request + offset)
  99. return request;
  100. *eof = 1;
  101. return len - offset;
  102. }
  103. static int i915_gem_inactive_info(char *buf, char **start, off_t offset,
  104. int request, int *eof, void *data)
  105. {
  106. struct drm_minor *minor = (struct drm_minor *) data;
  107. struct drm_device *dev = minor->dev;
  108. drm_i915_private_t *dev_priv = dev->dev_private;
  109. struct drm_i915_gem_object *obj_priv;
  110. int len = 0;
  111. if (offset > DRM_PROC_LIMIT) {
  112. *eof = 1;
  113. return 0;
  114. }
  115. *start = &buf[offset];
  116. *eof = 0;
  117. DRM_PROC_PRINT("Inactive:\n");
  118. list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list,
  119. list)
  120. {
  121. struct drm_gem_object *obj = obj_priv->obj;
  122. if (obj->name) {
  123. DRM_PROC_PRINT(" %p(%d): %08x %08x %d\n",
  124. obj, obj->name,
  125. obj->read_domains, obj->write_domain,
  126. obj_priv->last_rendering_seqno);
  127. } else {
  128. DRM_PROC_PRINT(" %p: %08x %08x %d\n", obj,
  129. obj->read_domains, obj->write_domain,
  130. obj_priv->last_rendering_seqno);
  131. }
  132. }
  133. if (len > request + offset)
  134. return request;
  135. *eof = 1;
  136. return len - offset;
  137. }
  138. static int i915_gem_request_info(char *buf, char **start, off_t offset,
  139. int request, int *eof, void *data)
  140. {
  141. struct drm_minor *minor = (struct drm_minor *) data;
  142. struct drm_device *dev = minor->dev;
  143. drm_i915_private_t *dev_priv = dev->dev_private;
  144. struct drm_i915_gem_request *gem_request;
  145. int len = 0;
  146. if (offset > DRM_PROC_LIMIT) {
  147. *eof = 1;
  148. return 0;
  149. }
  150. *start = &buf[offset];
  151. *eof = 0;
  152. DRM_PROC_PRINT("Request:\n");
  153. list_for_each_entry(gem_request, &dev_priv->mm.request_list,
  154. list)
  155. {
  156. DRM_PROC_PRINT(" %d @ %d %08x\n",
  157. gem_request->seqno,
  158. (int) (jiffies - gem_request->emitted_jiffies),
  159. gem_request->flush_domains);
  160. }
  161. if (len > request + offset)
  162. return request;
  163. *eof = 1;
  164. return len - offset;
  165. }
  166. static int i915_gem_seqno_info(char *buf, char **start, off_t offset,
  167. int request, int *eof, void *data)
  168. {
  169. struct drm_minor *minor = (struct drm_minor *) data;
  170. struct drm_device *dev = minor->dev;
  171. drm_i915_private_t *dev_priv = dev->dev_private;
  172. int len = 0;
  173. if (offset > DRM_PROC_LIMIT) {
  174. *eof = 1;
  175. return 0;
  176. }
  177. *start = &buf[offset];
  178. *eof = 0;
  179. if (dev_priv->hw_status_page != NULL) {
  180. DRM_PROC_PRINT("Current sequence: %d\n",
  181. i915_get_gem_seqno(dev));
  182. } else {
  183. DRM_PROC_PRINT("Current sequence: hws uninitialized\n");
  184. }
  185. DRM_PROC_PRINT("Waiter sequence: %d\n",
  186. dev_priv->mm.waiting_gem_seqno);
  187. DRM_PROC_PRINT("IRQ sequence: %d\n", dev_priv->mm.irq_gem_seqno);
  188. if (len > request + offset)
  189. return request;
  190. *eof = 1;
  191. return len - offset;
  192. }
  193. static int i915_interrupt_info(char *buf, char **start, off_t offset,
  194. int request, int *eof, void *data)
  195. {
  196. struct drm_minor *minor = (struct drm_minor *) data;
  197. struct drm_device *dev = minor->dev;
  198. drm_i915_private_t *dev_priv = dev->dev_private;
  199. int len = 0;
  200. if (offset > DRM_PROC_LIMIT) {
  201. *eof = 1;
  202. return 0;
  203. }
  204. *start = &buf[offset];
  205. *eof = 0;
  206. DRM_PROC_PRINT("Interrupt enable: %08x\n",
  207. I915_READ(IER));
  208. DRM_PROC_PRINT("Interrupt identity: %08x\n",
  209. I915_READ(IIR));
  210. DRM_PROC_PRINT("Interrupt mask: %08x\n",
  211. I915_READ(IMR));
  212. DRM_PROC_PRINT("Pipe A stat: %08x\n",
  213. I915_READ(PIPEASTAT));
  214. DRM_PROC_PRINT("Pipe B stat: %08x\n",
  215. I915_READ(PIPEBSTAT));
  216. DRM_PROC_PRINT("Interrupts received: %d\n",
  217. atomic_read(&dev_priv->irq_received));
  218. if (dev_priv->hw_status_page != NULL) {
  219. DRM_PROC_PRINT("Current sequence: %d\n",
  220. i915_get_gem_seqno(dev));
  221. } else {
  222. DRM_PROC_PRINT("Current sequence: hws uninitialized\n");
  223. }
  224. DRM_PROC_PRINT("Waiter sequence: %d\n",
  225. dev_priv->mm.waiting_gem_seqno);
  226. DRM_PROC_PRINT("IRQ sequence: %d\n",
  227. dev_priv->mm.irq_gem_seqno);
  228. if (len > request + offset)
  229. return request;
  230. *eof = 1;
  231. return len - offset;
  232. }
  233. static struct drm_proc_list {
  234. /** file name */
  235. const char *name;
  236. /** proc callback*/
  237. int (*f) (char *, char **, off_t, int, int *, void *);
  238. } i915_gem_proc_list[] = {
  239. {"i915_gem_active", i915_gem_active_info},
  240. {"i915_gem_flushing", i915_gem_flushing_info},
  241. {"i915_gem_inactive", i915_gem_inactive_info},
  242. {"i915_gem_request", i915_gem_request_info},
  243. {"i915_gem_seqno", i915_gem_seqno_info},
  244. {"i915_gem_interrupt", i915_interrupt_info},
  245. };
  246. #define I915_GEM_PROC_ENTRIES ARRAY_SIZE(i915_gem_proc_list)
  247. int i915_gem_proc_init(struct drm_minor *minor)
  248. {
  249. struct proc_dir_entry *ent;
  250. int i, j;
  251. for (i = 0; i < I915_GEM_PROC_ENTRIES; i++) {
  252. ent = create_proc_entry(i915_gem_proc_list[i].name,
  253. S_IFREG | S_IRUGO, minor->dev_root);
  254. if (!ent) {
  255. DRM_ERROR("Cannot create /proc/dri/.../%s\n",
  256. i915_gem_proc_list[i].name);
  257. for (j = 0; j < i; j++)
  258. remove_proc_entry(i915_gem_proc_list[i].name,
  259. minor->dev_root);
  260. return -1;
  261. }
  262. ent->read_proc = i915_gem_proc_list[i].f;
  263. ent->data = minor;
  264. }
  265. return 0;
  266. }
  267. void i915_gem_proc_cleanup(struct drm_minor *minor)
  268. {
  269. int i;
  270. if (!minor->dev_root)
  271. return;
  272. for (i = 0; i < I915_GEM_PROC_ENTRIES; i++)
  273. remove_proc_entry(i915_gem_proc_list[i].name, minor->dev_root);
  274. }