Rev 4560 | Rev 5354 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4560 | Rev 5060 | ||
---|---|---|---|
Line 40... | Line 40... | ||
40 | switch (ring) { |
40 | switch (ring) { |
41 | case RCS: return "render"; |
41 | case RCS: return "render"; |
42 | case VCS: return "bsd"; |
42 | case VCS: return "bsd"; |
43 | case BCS: return "blt"; |
43 | case BCS: return "blt"; |
44 | case VECS: return "vebox"; |
44 | case VECS: return "vebox"; |
- | 45 | case VCS2: return "bsd2"; |
|
45 | default: return ""; |
46 | default: return ""; |
46 | } |
47 | } |
47 | } |
48 | } |
Line 48... | Line 49... | ||
48 | 49 | ||
Line 144... | Line 145... | ||
144 | /* Seek the first printf which is hits start position */ |
145 | /* Seek the first printf which is hits start position */ |
145 | if (e->pos < e->start) { |
146 | if (e->pos < e->start) { |
146 | va_list tmp; |
147 | va_list tmp; |
Line 147... | Line 148... | ||
147 | 148 | ||
- | 149 | va_copy(tmp, args); |
|
- | 150 | len = vsnprintf(NULL, 0, f, tmp); |
|
- | 151 | va_end(tmp); |
|
148 | va_copy(tmp, args); |
152 | |
149 | if (!__i915_error_seek(e, vsnprintf(NULL, 0, f, tmp))) |
153 | if (!__i915_error_seek(e, len)) |
150 | return; |
154 | return; |
Line 151... | Line 155... | ||
151 | } |
155 | } |
152 | 156 | ||
Line 199... | Line 203... | ||
199 | err->rseqno, err->wseqno); |
203 | err->rseqno, err->wseqno); |
200 | err_puts(m, pin_flag(err->pinned)); |
204 | err_puts(m, pin_flag(err->pinned)); |
201 | err_puts(m, tiling_flag(err->tiling)); |
205 | err_puts(m, tiling_flag(err->tiling)); |
202 | err_puts(m, dirty_flag(err->dirty)); |
206 | err_puts(m, dirty_flag(err->dirty)); |
203 | err_puts(m, purgeable_flag(err->purgeable)); |
207 | err_puts(m, purgeable_flag(err->purgeable)); |
- | 208 | err_puts(m, err->userptr ? " userptr" : ""); |
|
204 | err_puts(m, err->ring != -1 ? " " : ""); |
209 | err_puts(m, err->ring != -1 ? " " : ""); |
205 | err_puts(m, ring_str(err->ring)); |
210 | err_puts(m, ring_str(err->ring)); |
206 | err_puts(m, i915_cache_level_str(err->cache_level)); |
211 | err_puts(m, i915_cache_level_str(err->cache_level)); |
Line 207... | Line 212... | ||
207 | 212 | ||
Line 233... | Line 238... | ||
233 | return "unknown"; |
238 | return "unknown"; |
234 | } |
239 | } |
Line 235... | Line 240... | ||
235 | 240 | ||
236 | static void i915_ring_error_state(struct drm_i915_error_state_buf *m, |
241 | static void i915_ring_error_state(struct drm_i915_error_state_buf *m, |
237 | struct drm_device *dev, |
242 | struct drm_device *dev, |
238 | struct drm_i915_error_state *error, |
- | |
239 | unsigned ring) |
243 | struct drm_i915_error_ring *ring) |
240 | { |
- | |
241 | BUG_ON(ring >= I915_NUM_RINGS); /* shut up confused gcc */ |
244 | { |
242 | if (!error->ring[ring].valid) |
245 | if (!ring->valid) |
Line 243... | Line 246... | ||
243 | return; |
246 | return; |
244 | 247 | ||
245 | err_printf(m, "%s command stream:\n", ring_str(ring)); |
248 | err_printf(m, " HEAD: 0x%08x\n", ring->head); |
246 | err_printf(m, " HEAD: 0x%08x\n", error->head[ring]); |
249 | err_printf(m, " TAIL: 0x%08x\n", ring->tail); |
247 | err_printf(m, " TAIL: 0x%08x\n", error->tail[ring]); |
250 | err_printf(m, " CTL: 0x%08x\n", ring->ctl); |
248 | err_printf(m, " CTL: 0x%08x\n", error->ctl[ring]); |
251 | err_printf(m, " HWS: 0x%08x\n", ring->hws); |
249 | err_printf(m, " ACTHD: 0x%08x\n", error->acthd[ring]); |
252 | err_printf(m, " ACTHD: 0x%08x %08x\n", (u32)(ring->acthd>>32), (u32)ring->acthd); |
250 | err_printf(m, " IPEIR: 0x%08x\n", error->ipeir[ring]); |
253 | err_printf(m, " IPEIR: 0x%08x\n", ring->ipeir); |
251 | err_printf(m, " IPEHR: 0x%08x\n", error->ipehr[ring]); |
254 | err_printf(m, " IPEHR: 0x%08x\n", ring->ipehr); |
252 | err_printf(m, " INSTDONE: 0x%08x\n", error->instdone[ring]); |
255 | err_printf(m, " INSTDONE: 0x%08x\n", ring->instdone); |
253 | if (INTEL_INFO(dev)->gen >= 4) { |
256 | if (INTEL_INFO(dev)->gen >= 4) { |
254 | err_printf(m, " BBADDR: 0x%08llx\n", error->bbaddr[ring]); |
257 | err_printf(m, " BBADDR: 0x%08x %08x\n", (u32)(ring->bbaddr>>32), (u32)ring->bbaddr); |
255 | err_printf(m, " BB_STATE: 0x%08x\n", error->bbstate[ring]); |
258 | err_printf(m, " BB_STATE: 0x%08x\n", ring->bbstate); |
256 | err_printf(m, " INSTPS: 0x%08x\n", error->instps[ring]); |
259 | err_printf(m, " INSTPS: 0x%08x\n", ring->instps); |
257 | } |
260 | } |
- | 261 | err_printf(m, " INSTPM: 0x%08x\n", ring->instpm); |
|
258 | err_printf(m, " INSTPM: 0x%08x\n", error->instpm[ring]); |
262 | err_printf(m, " FADDR: 0x%08x %08x\n", upper_32_bits(ring->faddr), |
259 | err_printf(m, " FADDR: 0x%08x\n", error->faddr[ring]); |
263 | lower_32_bits(ring->faddr)); |
260 | if (INTEL_INFO(dev)->gen >= 6) { |
264 | if (INTEL_INFO(dev)->gen >= 6) { |
261 | err_printf(m, " RC PSMI: 0x%08x\n", error->rc_psmi[ring]); |
265 | err_printf(m, " RC PSMI: 0x%08x\n", ring->rc_psmi); |
262 | err_printf(m, " FAULT_REG: 0x%08x\n", error->fault_reg[ring]); |
266 | err_printf(m, " FAULT_REG: 0x%08x\n", ring->fault_reg); |
263 | err_printf(m, " SYNC_0: 0x%08x [last synced 0x%08x]\n", |
267 | err_printf(m, " SYNC_0: 0x%08x [last synced 0x%08x]\n", |
264 | error->semaphore_mboxes[ring][0], |
268 | ring->semaphore_mboxes[0], |
265 | error->semaphore_seqno[ring][0]); |
269 | ring->semaphore_seqno[0]); |
266 | err_printf(m, " SYNC_1: 0x%08x [last synced 0x%08x]\n", |
270 | err_printf(m, " SYNC_1: 0x%08x [last synced 0x%08x]\n", |
267 | error->semaphore_mboxes[ring][1], |
271 | ring->semaphore_mboxes[1], |
268 | error->semaphore_seqno[ring][1]); |
272 | ring->semaphore_seqno[1]); |
269 | if (HAS_VEBOX(dev)) { |
273 | if (HAS_VEBOX(dev)) { |
270 | err_printf(m, " SYNC_2: 0x%08x [last synced 0x%08x]\n", |
274 | err_printf(m, " SYNC_2: 0x%08x [last synced 0x%08x]\n", |
271 | error->semaphore_mboxes[ring][2], |
275 | ring->semaphore_mboxes[2], |
272 | error->semaphore_seqno[ring][2]); |
276 | ring->semaphore_seqno[2]); |
- | 277 | } |
|
- | 278 | } |
|
- | 279 | if (USES_PPGTT(dev)) { |
|
- | 280 | err_printf(m, " GFX_MODE: 0x%08x\n", ring->vm_info.gfx_mode); |
|
- | 281 | ||
- | 282 | if (INTEL_INFO(dev)->gen >= 8) { |
|
- | 283 | int i; |
|
- | 284 | for (i = 0; i < 4; i++) |
|
- | 285 | err_printf(m, " PDP%d: 0x%016llx\n", |
|
- | 286 | i, ring->vm_info.pdp[i]); |
|
- | 287 | } else { |
|
- | 288 | err_printf(m, " PP_DIR_BASE: 0x%08x\n", |
|
- | 289 | ring->vm_info.pp_dir_base); |
|
273 | } |
290 | } |
274 | } |
291 | } |
275 | err_printf(m, " seqno: 0x%08x\n", error->seqno[ring]); |
292 | err_printf(m, " seqno: 0x%08x\n", ring->seqno); |
276 | err_printf(m, " waiting: %s\n", yesno(error->waiting[ring])); |
293 | err_printf(m, " waiting: %s\n", yesno(ring->waiting)); |
277 | err_printf(m, " ring->head: 0x%08x\n", error->cpu_ring_head[ring]); |
294 | err_printf(m, " ring->head: 0x%08x\n", ring->cpu_ring_head); |
278 | err_printf(m, " ring->tail: 0x%08x\n", error->cpu_ring_tail[ring]); |
295 | err_printf(m, " ring->tail: 0x%08x\n", ring->cpu_ring_tail); |
279 | err_printf(m, " hangcheck: %s [%d]\n", |
296 | err_printf(m, " hangcheck: %s [%d]\n", |
280 | hangcheck_action_to_str(error->hangcheck_action[ring]), |
297 | hangcheck_action_to_str(ring->hangcheck_action), |
Line 281... | Line 298... | ||
281 | error->hangcheck_score[ring]); |
298 | ring->hangcheck_score); |
282 | } |
299 | } |
283 | 300 | ||
Line 288... | Line 305... | ||
288 | va_start(args, f); |
305 | va_start(args, f); |
289 | i915_error_vprintf(e, f, args); |
306 | i915_error_vprintf(e, f, args); |
290 | va_end(args); |
307 | va_end(args); |
291 | } |
308 | } |
Line -... | Line 309... | ||
- | 309 | ||
- | 310 | static void print_error_obj(struct drm_i915_error_state_buf *m, |
|
- | 311 | struct drm_i915_error_object *obj) |
|
- | 312 | { |
|
- | 313 | int page, offset, elt; |
|
- | 314 | ||
- | 315 | for (page = offset = 0; page < obj->page_count; page++) { |
|
- | 316 | for (elt = 0; elt < PAGE_SIZE/4; elt++) { |
|
- | 317 | err_printf(m, "%08x : %08x\n", offset, |
|
- | 318 | obj->pages[page][elt]); |
|
- | 319 | offset += 4; |
|
- | 320 | } |
|
- | 321 | } |
|
- | 322 | } |
|
292 | 323 | ||
293 | int i915_error_state_to_str(struct drm_i915_error_state_buf *m, |
324 | int i915_error_state_to_str(struct drm_i915_error_state_buf *m, |
294 | const struct i915_error_state_file_priv *error_priv) |
325 | const struct i915_error_state_file_priv *error_priv) |
295 | { |
326 | { |
296 | struct drm_device *dev = error_priv->dev; |
327 | struct drm_device *dev = error_priv->dev; |
297 | drm_i915_private_t *dev_priv = dev->dev_private; |
328 | struct drm_i915_private *dev_priv = dev->dev_private; |
298 | struct drm_i915_error_state *error = error_priv->error; |
329 | struct drm_i915_error_state *error = error_priv->error; |
- | 330 | int i, j, offset, elt; |
|
Line 299... | Line 331... | ||
299 | int i, j, page, offset, elt; |
331 | int max_hangcheck_score; |
300 | 332 | ||
301 | if (!error) { |
333 | if (!error) { |
302 | err_printf(m, "no error state collected\n"); |
334 | err_printf(m, "no error state collected\n"); |
Line -... | Line 335... | ||
- | 335 | goto out; |
|
303 | goto out; |
336 | } |
304 | } |
337 | |
305 | 338 | err_printf(m, "%s\n", error->error_msg); |
|
- | 339 | err_printf(m, "Time: %ld s %ld us\n", error->time.tv_sec, |
|
- | 340 | error->time.tv_usec); |
|
- | 341 | err_printf(m, "Kernel: " UTS_RELEASE "\n"); |
|
- | 342 | max_hangcheck_score = 0; |
|
- | 343 | for (i = 0; i < ARRAY_SIZE(error->ring); i++) { |
|
- | 344 | if (error->ring[i].hangcheck_score > max_hangcheck_score) |
|
- | 345 | max_hangcheck_score = error->ring[i].hangcheck_score; |
|
- | 346 | } |
|
- | 347 | for (i = 0; i < ARRAY_SIZE(error->ring); i++) { |
|
- | 348 | if (error->ring[i].hangcheck_score == max_hangcheck_score && |
|
- | 349 | error->ring[i].pid != -1) { |
|
- | 350 | err_printf(m, "Active process (on ring %s): %s [%d]\n", |
|
- | 351 | ring_str(i), |
|
- | 352 | error->ring[i].comm, |
|
- | 353 | error->ring[i].pid); |
|
- | 354 | } |
|
306 | err_printf(m, "Time: %ld s %ld us\n", error->time.tv_sec, |
355 | } |
307 | error->time.tv_usec); |
356 | err_printf(m, "Reset count: %u\n", error->reset_count); |
308 | err_printf(m, "Kernel: " UTS_RELEASE "\n"); |
357 | err_printf(m, "Suspend count: %u\n", error->suspend_count); |
309 | err_printf(m, "PCI ID: 0x%04x\n", dev->pdev->device); |
358 | err_printf(m, "PCI ID: 0x%04x\n", dev->pdev->device); |
310 | err_printf(m, "EIR: 0x%08x\n", error->eir); |
359 | err_printf(m, "EIR: 0x%08x\n", error->eir); |
Line 328... | Line 377... | ||
328 | } |
377 | } |
Line 329... | Line 378... | ||
329 | 378 | ||
330 | if (INTEL_INFO(dev)->gen == 7) |
379 | if (INTEL_INFO(dev)->gen == 7) |
Line 331... | Line 380... | ||
331 | err_printf(m, "ERR_INT: 0x%08x\n", error->err_int); |
380 | err_printf(m, "ERR_INT: 0x%08x\n", error->err_int); |
- | 381 | ||
332 | 382 | for (i = 0; i < ARRAY_SIZE(error->ring); i++) { |
|
- | 383 | err_printf(m, "%s command stream:\n", ring_str(i)); |
|
Line 333... | Line 384... | ||
333 | for (i = 0; i < ARRAY_SIZE(error->ring); i++) |
384 | i915_ring_error_state(m, dev, &error->ring[i]); |
334 | i915_ring_error_state(m, dev, error, i); |
385 | } |
335 | 386 | ||
336 | if (error->active_bo) |
387 | if (error->active_bo) |
Line 344... | Line 395... | ||
344 | error->pinned_bo_count[0]); |
395 | error->pinned_bo_count[0]); |
Line 345... | Line 396... | ||
345 | 396 | ||
346 | for (i = 0; i < ARRAY_SIZE(error->ring); i++) { |
397 | for (i = 0; i < ARRAY_SIZE(error->ring); i++) { |
Line 347... | Line 398... | ||
347 | struct drm_i915_error_object *obj; |
398 | struct drm_i915_error_object *obj; |
- | 399 | ||
- | 400 | obj = error->ring[i].batchbuffer; |
|
- | 401 | if (obj) { |
|
348 | 402 | err_puts(m, dev_priv->ring[i].name); |
|
349 | if ((obj = error->ring[i].batchbuffer)) { |
403 | if (error->ring[i].pid != -1) |
- | 404 | err_printf(m, " (submitted by %s [%d])", |
|
- | 405 | error->ring[i].comm, |
|
350 | err_printf(m, "%s --- gtt_offset = 0x%08x\n", |
406 | error->ring[i].pid); |
351 | dev_priv->ring[i].name, |
- | |
352 | obj->gtt_offset); |
- | |
353 | offset = 0; |
- | |
354 | for (page = 0; page < obj->page_count; page++) { |
- | |
355 | for (elt = 0; elt < PAGE_SIZE/4; elt++) { |
407 | err_printf(m, " --- gtt_offset = 0x%08x\n", |
356 | err_printf(m, "%08x : %08x\n", offset, |
- | |
357 | obj->pages[page][elt]); |
- | |
358 | offset += 4; |
408 | obj->gtt_offset); |
- | 409 | print_error_obj(m, obj); |
|
- | 410 | } |
|
- | 411 | ||
- | 412 | obj = error->ring[i].wa_batchbuffer; |
|
- | 413 | if (obj) { |
|
- | 414 | err_printf(m, "%s (w/a) --- gtt_offset = 0x%08x\n", |
|
359 | } |
415 | dev_priv->ring[i].name, obj->gtt_offset); |
Line 360... | Line 416... | ||
360 | } |
416 | print_error_obj(m, obj); |
361 | } |
417 | } |
362 | 418 | ||
Line 374... | Line 430... | ||
374 | 430 | ||
375 | if ((obj = error->ring[i].ringbuffer)) { |
431 | if ((obj = error->ring[i].ringbuffer)) { |
376 | err_printf(m, "%s --- ringbuffer = 0x%08x\n", |
432 | err_printf(m, "%s --- ringbuffer = 0x%08x\n", |
377 | dev_priv->ring[i].name, |
433 | dev_priv->ring[i].name, |
378 | obj->gtt_offset); |
- | |
379 | offset = 0; |
- | |
380 | for (page = 0; page < obj->page_count; page++) { |
- | |
381 | for (elt = 0; elt < PAGE_SIZE/4; elt++) { |
434 | obj->gtt_offset); |
382 | err_printf(m, "%08x : %08x\n", |
- | |
383 | offset, |
- | |
384 | obj->pages[page][elt]); |
- | |
385 | offset += 4; |
- | |
386 | } |
- | |
387 | } |
435 | print_error_obj(m, obj); |
Line 388... | Line 436... | ||
388 | } |
436 | } |
389 | 437 | ||
390 | if ((obj = error->ring[i].ctx)) { |
438 | if ((obj = error->ring[i].hws_page)) { |
391 | err_printf(m, "%s --- HW Context = 0x%08x\n", |
439 | err_printf(m, "%s --- HW Status = 0x%08x\n", |
392 | dev_priv->ring[i].name, |
440 | dev_priv->ring[i].name, |
393 | obj->gtt_offset); |
441 | obj->gtt_offset); |
394 | offset = 0; |
442 | offset = 0; |
Line 400... | Line 448... | ||
400 | obj->pages[0][elt+2], |
448 | obj->pages[0][elt+2], |
401 | obj->pages[0][elt+3]); |
449 | obj->pages[0][elt+3]); |
402 | offset += 16; |
450 | offset += 16; |
403 | } |
451 | } |
404 | } |
452 | } |
- | 453 | ||
- | 454 | if ((obj = error->ring[i].ctx)) { |
|
- | 455 | err_printf(m, "%s --- HW Context = 0x%08x\n", |
|
- | 456 | dev_priv->ring[i].name, |
|
- | 457 | obj->gtt_offset); |
|
- | 458 | print_error_obj(m, obj); |
|
- | 459 | } |
|
405 | } |
460 | } |
Line 406... | Line 461... | ||
406 | 461 | ||
407 | if (error->overlay) |
462 | if (error->overlay) |
Line 467... | Line 522... | ||
467 | int i; |
522 | int i; |
Line 468... | Line 523... | ||
468 | 523 | ||
469 | for (i = 0; i < ARRAY_SIZE(error->ring); i++) { |
524 | for (i = 0; i < ARRAY_SIZE(error->ring); i++) { |
470 | i915_error_object_free(error->ring[i].batchbuffer); |
525 | i915_error_object_free(error->ring[i].batchbuffer); |
- | 526 | i915_error_object_free(error->ring[i].ringbuffer); |
|
471 | i915_error_object_free(error->ring[i].ringbuffer); |
527 | i915_error_object_free(error->ring[i].hws_page); |
472 | i915_error_object_free(error->ring[i].ctx); |
528 | i915_error_object_free(error->ring[i].ctx); |
473 | kfree(error->ring[i].requests); |
529 | kfree(error->ring[i].requests); |
Line 474... | Line 530... | ||
474 | } |
530 | } |
Line 480... | Line 536... | ||
480 | } |
536 | } |
Line 481... | Line 537... | ||
481 | 537 | ||
482 | static struct drm_i915_error_object * |
538 | static struct drm_i915_error_object * |
483 | i915_error_object_create_sized(struct drm_i915_private *dev_priv, |
539 | i915_error_object_create_sized(struct drm_i915_private *dev_priv, |
- | 540 | struct drm_i915_gem_object *src, |
|
484 | struct drm_i915_gem_object *src, |
541 | struct i915_address_space *vm, |
485 | const int num_pages) |
542 | const int num_pages) |
486 | { |
543 | { |
487 | struct drm_i915_error_object *dst; |
544 | struct drm_i915_error_object *dst; |
488 | int i; |
545 | int i; |
Line 493... | Line 550... | ||
493 | 550 | ||
494 | dst = kmalloc(sizeof(*dst) + num_pages * sizeof(u32 *), GFP_ATOMIC); |
551 | dst = kmalloc(sizeof(*dst) + num_pages * sizeof(u32 *), GFP_ATOMIC); |
495 | if (dst == NULL) |
552 | if (dst == NULL) |
Line 496... | Line 553... | ||
496 | return NULL; |
553 | return NULL; |
497 | 554 | ||
498 | reloc_offset = dst->gtt_offset = i915_gem_obj_ggtt_offset(src); |
555 | reloc_offset = dst->gtt_offset = i915_gem_obj_offset(src, vm); |
499 | for (i = 0; i < num_pages; i++) { |
556 | for (i = 0; i < num_pages; i++) { |
Line 500... | Line 557... | ||
500 | unsigned long flags; |
557 | unsigned long flags; |
501 | void *d; |
558 | void *d; |
502 | 559 | ||
Line 503... | Line 560... | ||
503 | d = kmalloc(PAGE_SIZE, GFP_ATOMIC); |
560 | d = kmalloc(PAGE_SIZE, GFP_ATOMIC); |
- | 561 | if (d == NULL) |
|
504 | if (d == NULL) |
562 | goto unwind; |
505 | goto unwind; |
563 | |
- | 564 | local_irq_save(flags); |
|
506 | 565 | if (src->cache_level == I915_CACHE_NONE && |
|
Line 507... | Line 566... | ||
507 | local_irq_save(flags); |
566 | reloc_offset < dev_priv->gtt.mappable_end && |
508 | if (reloc_offset < dev_priv->gtt.mappable_end && |
567 | src->has_global_gtt_mapping && |
509 | src->has_global_gtt_mapping) { |
568 | i915_is_ggtt(vm)) { |
Line 554... | Line 613... | ||
554 | while (i--) |
613 | while (i--) |
555 | kfree(dst->pages[i]); |
614 | kfree(dst->pages[i]); |
556 | kfree(dst); |
615 | kfree(dst); |
557 | return NULL; |
616 | return NULL; |
558 | } |
617 | } |
559 | #define i915_error_object_create(dev_priv, src) \ |
618 | #define i915_error_object_create(dev_priv, src, vm) \ |
560 | i915_error_object_create_sized((dev_priv), (src), \ |
619 | i915_error_object_create_sized((dev_priv), (src), (vm), \ |
- | 620 | (src)->base.size>>PAGE_SHIFT) |
|
- | 621 | ||
- | 622 | #define i915_error_ggtt_object_create(dev_priv, src) \ |
|
- | 623 | i915_error_object_create_sized((dev_priv), (src), &(dev_priv)->gtt.base, \ |
|
561 | (src)->base.size>>PAGE_SHIFT) |
624 | (src)->base.size>>PAGE_SHIFT) |
Line 562... | Line 625... | ||
562 | 625 | ||
563 | static void capture_bo(struct drm_i915_error_buffer *err, |
626 | static void capture_bo(struct drm_i915_error_buffer *err, |
564 | struct drm_i915_gem_object *obj) |
627 | struct drm_i915_gem_object *obj) |
Line 570... | Line 633... | ||
570 | err->gtt_offset = i915_gem_obj_ggtt_offset(obj); |
633 | err->gtt_offset = i915_gem_obj_ggtt_offset(obj); |
571 | err->read_domains = obj->base.read_domains; |
634 | err->read_domains = obj->base.read_domains; |
572 | err->write_domain = obj->base.write_domain; |
635 | err->write_domain = obj->base.write_domain; |
573 | err->fence_reg = obj->fence_reg; |
636 | err->fence_reg = obj->fence_reg; |
574 | err->pinned = 0; |
637 | err->pinned = 0; |
575 | if (obj->pin_count > 0) |
638 | if (i915_gem_obj_is_pinned(obj)) |
576 | err->pinned = 1; |
639 | err->pinned = 1; |
577 | if (obj->user_pin_count > 0) |
640 | if (obj->user_pin_count > 0) |
578 | err->pinned = -1; |
641 | err->pinned = -1; |
579 | err->tiling = obj->tiling_mode; |
642 | err->tiling = obj->tiling_mode; |
580 | err->dirty = obj->dirty; |
643 | err->dirty = obj->dirty; |
581 | err->purgeable = obj->madv != I915_MADV_WILLNEED; |
644 | err->purgeable = obj->madv != I915_MADV_WILLNEED; |
- | 645 | err->userptr = obj->userptr.mm != NULL; |
|
582 | err->ring = obj->ring ? obj->ring->id : -1; |
646 | err->ring = obj->ring ? obj->ring->id : -1; |
583 | err->cache_level = obj->cache_level; |
647 | err->cache_level = obj->cache_level; |
584 | } |
648 | } |
Line 585... | Line 649... | ||
585 | 649 | ||
Line 603... | Line 667... | ||
603 | { |
667 | { |
604 | struct drm_i915_gem_object *obj; |
668 | struct drm_i915_gem_object *obj; |
605 | int i = 0; |
669 | int i = 0; |
Line 606... | Line 670... | ||
606 | 670 | ||
607 | list_for_each_entry(obj, head, global_list) { |
671 | list_for_each_entry(obj, head, global_list) { |
608 | if (obj->pin_count == 0) |
672 | if (!i915_gem_obj_is_pinned(obj)) |
Line 609... | Line 673... | ||
609 | continue; |
673 | continue; |
610 | 674 | ||
611 | capture_bo(err++, obj); |
675 | capture_bo(err++, obj); |
612 | if (++i == count) |
676 | if (++i == count) |
Line 613... | Line 677... | ||
613 | break; |
677 | break; |
614 | } |
678 | } |
Line -... | Line 679... | ||
- | 679 | ||
- | 680 | return i; |
|
- | 681 | } |
|
- | 682 | ||
- | 683 | /* Generate a semi-unique error code. The code is not meant to have meaning, The |
|
- | 684 | * code's only purpose is to try to prevent false duplicated bug reports by |
|
- | 685 | * grossly estimating a GPU error state. |
|
- | 686 | * |
|
- | 687 | * TODO Ideally, hashing the batchbuffer would be a very nice way to determine |
|
- | 688 | * the hang if we could strip the GTT offset information from it. |
|
- | 689 | * |
|
- | 690 | * It's only a small step better than a random number in its current form. |
|
- | 691 | */ |
|
- | 692 | static uint32_t i915_error_generate_code(struct drm_i915_private *dev_priv, |
|
- | 693 | struct drm_i915_error_state *error, |
|
- | 694 | int *ring_id) |
|
- | 695 | { |
|
- | 696 | uint32_t error_code = 0; |
|
- | 697 | int i; |
|
- | 698 | ||
- | 699 | /* IPEHR would be an ideal way to detect errors, as it's the gross |
|
- | 700 | * measure of "the command that hung." However, has some very common |
|
- | 701 | * synchronization commands which almost always appear in the case |
|
- | 702 | * strictly a client bug. Use instdone to differentiate those some. |
|
- | 703 | */ |
|
- | 704 | for (i = 0; i < I915_NUM_RINGS; i++) { |
|
- | 705 | if (error->ring[i].hangcheck_action == HANGCHECK_HUNG) { |
|
- | 706 | if (ring_id) |
|
- | 707 | *ring_id = i; |
|
- | 708 | ||
- | 709 | return error->ring[i].ipehr ^ error->ring[i].instdone; |
|
- | 710 | } |
|
- | 711 | } |
|
615 | 712 | ||
616 | return i; |
713 | return error_code; |
617 | } |
714 | } |
618 | 715 | ||
619 | static void i915_gem_record_fences(struct drm_device *dev, |
716 | static void i915_gem_record_fences(struct drm_device *dev, |
Line 647... | Line 744... | ||
647 | default: |
744 | default: |
648 | BUG(); |
745 | BUG(); |
649 | } |
746 | } |
650 | } |
747 | } |
Line 651... | Line -... | ||
651 | - | ||
652 | static struct drm_i915_error_object * |
- | |
653 | i915_error_first_batchbuffer(struct drm_i915_private *dev_priv, |
- | |
654 | struct intel_ring_buffer *ring) |
- | |
655 | { |
- | |
656 | struct i915_address_space *vm; |
- | |
657 | struct i915_vma *vma; |
- | |
658 | struct drm_i915_gem_object *obj; |
- | |
659 | u32 seqno; |
- | |
660 | - | ||
661 | if (!ring->get_seqno) |
- | |
662 | return NULL; |
- | |
663 | - | ||
664 | if (HAS_BROKEN_CS_TLB(dev_priv->dev)) { |
- | |
665 | u32 acthd = I915_READ(ACTHD); |
- | |
666 | - | ||
667 | if (WARN_ON(ring->id != RCS)) |
- | |
668 | return NULL; |
- | |
669 | - | ||
670 | obj = ring->scratch.obj; |
- | |
671 | if (obj != NULL && |
- | |
672 | acthd >= i915_gem_obj_ggtt_offset(obj) && |
- | |
673 | acthd < i915_gem_obj_ggtt_offset(obj) + obj->base.size) |
- | |
674 | return i915_error_object_create(dev_priv, obj); |
- | |
675 | } |
- | |
676 | - | ||
677 | seqno = ring->get_seqno(ring, false); |
- | |
678 | list_for_each_entry(vm, &dev_priv->vm_list, global_link) { |
- | |
679 | list_for_each_entry(vma, &vm->active_list, mm_list) { |
- | |
680 | obj = vma->obj; |
- | |
681 | if (obj->ring != ring) |
- | |
682 | continue; |
- | |
683 | - | ||
684 | if (i915_seqno_passed(seqno, obj->last_read_seqno)) |
- | |
685 | continue; |
- | |
686 | - | ||
687 | if ((obj->base.read_domains & I915_GEM_DOMAIN_COMMAND) == 0) |
- | |
688 | continue; |
- | |
689 | - | ||
690 | /* We need to copy these to an anonymous buffer as the simplest |
- | |
691 | * method to avoid being overwritten by userspace. |
- | |
692 | */ |
- | |
693 | return i915_error_object_create(dev_priv, obj); |
- | |
694 | } |
- | |
695 | } |
- | |
696 | - | ||
697 | return NULL; |
- | |
698 | } |
- | |
699 | 748 | ||
700 | static void i915_record_ring_state(struct drm_device *dev, |
749 | static void i915_record_ring_state(struct drm_device *dev, |
701 | struct drm_i915_error_state *error, |
750 | struct intel_engine_cs *ring, |
702 | struct intel_ring_buffer *ring) |
751 | struct drm_i915_error_ring *ering) |
703 | { |
752 | { |
Line 704... | Line 753... | ||
704 | struct drm_i915_private *dev_priv = dev->dev_private; |
753 | struct drm_i915_private *dev_priv = dev->dev_private; |
705 | 754 | ||
706 | if (INTEL_INFO(dev)->gen >= 6) { |
755 | if (INTEL_INFO(dev)->gen >= 6) { |
707 | error->rc_psmi[ring->id] = I915_READ(ring->mmio_base + 0x50); |
756 | ering->rc_psmi = I915_READ(ring->mmio_base + 0x50); |
708 | error->fault_reg[ring->id] = I915_READ(RING_FAULT_REG(ring)); |
757 | ering->fault_reg = I915_READ(RING_FAULT_REG(ring)); |
709 | error->semaphore_mboxes[ring->id][0] |
758 | ering->semaphore_mboxes[0] |
710 | = I915_READ(RING_SYNC_0(ring->mmio_base)); |
759 | = I915_READ(RING_SYNC_0(ring->mmio_base)); |
711 | error->semaphore_mboxes[ring->id][1] |
760 | ering->semaphore_mboxes[1] |
712 | = I915_READ(RING_SYNC_1(ring->mmio_base)); |
761 | = I915_READ(RING_SYNC_1(ring->mmio_base)); |
713 | error->semaphore_seqno[ring->id][0] = ring->sync_seqno[0]; |
762 | ering->semaphore_seqno[0] = ring->semaphore.sync_seqno[0]; |
Line 714... | Line 763... | ||
714 | error->semaphore_seqno[ring->id][1] = ring->sync_seqno[1]; |
763 | ering->semaphore_seqno[1] = ring->semaphore.sync_seqno[1]; |
715 | } |
764 | } |
716 | 765 | ||
717 | if (HAS_VEBOX(dev)) { |
766 | if (HAS_VEBOX(dev)) { |
718 | error->semaphore_mboxes[ring->id][2] = |
767 | ering->semaphore_mboxes[2] = |
Line 719... | Line 768... | ||
719 | I915_READ(RING_SYNC_2(ring->mmio_base)); |
768 | I915_READ(RING_SYNC_2(ring->mmio_base)); |
720 | error->semaphore_seqno[ring->id][2] = ring->sync_seqno[2]; |
769 | ering->semaphore_seqno[2] = ring->semaphore.sync_seqno[2]; |
721 | } |
770 | } |
722 | 771 | ||
723 | if (INTEL_INFO(dev)->gen >= 4) { |
772 | if (INTEL_INFO(dev)->gen >= 4) { |
724 | error->faddr[ring->id] = I915_READ(RING_DMA_FADD(ring->mmio_base)); |
773 | ering->faddr = I915_READ(RING_DMA_FADD(ring->mmio_base)); |
725 | error->ipeir[ring->id] = I915_READ(RING_IPEIR(ring->mmio_base)); |
774 | ering->ipeir = I915_READ(RING_IPEIR(ring->mmio_base)); |
726 | error->ipehr[ring->id] = I915_READ(RING_IPEHR(ring->mmio_base)); |
775 | ering->ipehr = I915_READ(RING_IPEHR(ring->mmio_base)); |
- | 776 | ering->instdone = I915_READ(RING_INSTDONE(ring->mmio_base)); |
|
727 | error->instdone[ring->id] = I915_READ(RING_INSTDONE(ring->mmio_base)); |
777 | ering->instps = I915_READ(RING_INSTPS(ring->mmio_base)); |
- | 778 | ering->bbaddr = I915_READ(RING_BBADDR(ring->mmio_base)); |
|
728 | error->instps[ring->id] = I915_READ(RING_INSTPS(ring->mmio_base)); |
779 | if (INTEL_INFO(dev)->gen >= 8) { |
- | 780 | ering->faddr |= (u64) I915_READ(RING_DMA_FADD_UDW(ring->mmio_base)) << 32; |
|
- | 781 | ering->bbaddr |= (u64) I915_READ(RING_BBADDR_UDW(ring->mmio_base)) << 32; |
|
- | 782 | } |
|
- | 783 | ering->bbstate = I915_READ(RING_BBSTATE(ring->mmio_base)); |
|
- | 784 | } else { |
|
- | 785 | ering->faddr = I915_READ(DMA_FADD_I8XX); |
|
- | 786 | ering->ipeir = I915_READ(IPEIR); |
|
- | 787 | ering->ipehr = I915_READ(IPEHR); |
|
- | 788 | ering->instdone = I915_READ(INSTDONE); |
|
- | 789 | } |
|
- | 790 | ||
- | 791 | ering->waiting = waitqueue_active(&ring->irq_queue); |
|
- | 792 | ering->instpm = I915_READ(RING_INSTPM(ring->mmio_base)); |
|
- | 793 | ering->seqno = ring->get_seqno(ring, false); |
|
- | 794 | ering->acthd = intel_ring_get_active_head(ring); |
|
- | 795 | ering->head = I915_READ_HEAD(ring); |
|
- | 796 | ering->tail = I915_READ_TAIL(ring); |
|
- | 797 | ering->ctl = I915_READ_CTL(ring); |
|
- | 798 | ||
- | 799 | if (I915_NEED_GFX_HWS(dev)) { |
|
- | 800 | int mmio; |
|
- | 801 | ||
- | 802 | if (IS_GEN7(dev)) { |
|
- | 803 | switch (ring->id) { |
|
- | 804 | default: |
|
- | 805 | case RCS: |
|
- | 806 | mmio = RENDER_HWS_PGA_GEN7; |
|
- | 807 | break; |
|
- | 808 | case BCS: |
|
- | 809 | mmio = BLT_HWS_PGA_GEN7; |
|
- | 810 | break; |
|
- | 811 | case VCS: |
|
- | 812 | mmio = BSD_HWS_PGA_GEN7; |
|
- | 813 | break; |
|
- | 814 | case VECS: |
|
- | 815 | mmio = VEBOX_HWS_PGA_GEN7; |
|
729 | error->bbaddr[ring->id] = I915_READ(RING_BBADDR(ring->mmio_base)); |
816 | break; |
730 | if (INTEL_INFO(dev)->gen >= 8) |
817 | } |
731 | error->bbaddr[ring->id] |= (u64) I915_READ(RING_BBADDR_UDW(ring->mmio_base)) << 32; |
818 | } else if (IS_GEN6(ring->dev)) { |
- | 819 | mmio = RING_HWS_PGA_GEN6(ring->mmio_base); |
|
- | 820 | } else { |
|
732 | error->bbstate[ring->id] = I915_READ(RING_BBSTATE(ring->mmio_base)); |
821 | /* XXX: gen8 returns to sanity */ |
733 | } else { |
- | |
734 | error->faddr[ring->id] = I915_READ(DMA_FADD_I8XX); |
822 | mmio = RING_HWS_PGA(ring->mmio_base); |
Line 735... | Line 823... | ||
735 | error->ipeir[ring->id] = I915_READ(IPEIR); |
823 | } |
736 | error->ipehr[ring->id] = I915_READ(IPEHR); |
- | |
737 | error->instdone[ring->id] = I915_READ(INSTDONE); |
824 | |
- | 825 | ering->hws = I915_READ(mmio); |
|
738 | } |
826 | } |
739 | 827 | ||
- | 828 | ering->cpu_ring_head = ring->buffer->head; |
|
740 | error->waiting[ring->id] = waitqueue_active(&ring->irq_queue); |
829 | ering->cpu_ring_tail = ring->buffer->tail; |
741 | error->instpm[ring->id] = I915_READ(RING_INSTPM(ring->mmio_base)); |
830 | |
Line 742... | Line -... | ||
742 | error->seqno[ring->id] = ring->get_seqno(ring, false); |
- | |
743 | error->acthd[ring->id] = intel_ring_get_active_head(ring); |
831 | ering->hangcheck_score = ring->hangcheck.score; |
Line -... | Line 832... | ||
- | 832 | ering->hangcheck_action = ring->hangcheck.action; |
|
- | 833 | ||
- | 834 | if (USES_PPGTT(dev)) { |
|
- | 835 | int i; |
|
- | 836 | ||
744 | error->head[ring->id] = I915_READ_HEAD(ring); |
837 | ering->vm_info.gfx_mode = I915_READ(RING_MODE_GEN7(ring)); |
- | 838 | ||
745 | error->tail[ring->id] = I915_READ_TAIL(ring); |
839 | switch (INTEL_INFO(dev)->gen) { |
- | 840 | case 8: |
|
- | 841 | for (i = 0; i < 4; i++) { |
|
- | 842 | ering->vm_info.pdp[i] = |
|
- | 843 | I915_READ(GEN8_RING_PDP_UDW(ring, i)); |
|
- | 844 | ering->vm_info.pdp[i] <<= 32; |
|
- | 845 | ering->vm_info.pdp[i] |= |
|
- | 846 | I915_READ(GEN8_RING_PDP_LDW(ring, i)); |
|
- | 847 | } |
|
- | 848 | break; |
|
- | 849 | case 7: |
|
- | 850 | ering->vm_info.pp_dir_base = |
|
- | 851 | I915_READ(RING_PP_DIR_BASE(ring)); |
|
746 | error->ctl[ring->id] = I915_READ_CTL(ring); |
852 | break; |
Line 747... | Line 853... | ||
747 | 853 | case 6: |
|
748 | error->cpu_ring_head[ring->id] = ring->head; |
854 | ering->vm_info.pp_dir_base = |
749 | error->cpu_ring_tail[ring->id] = ring->tail; |
855 | I915_READ(RING_PP_DIR_BASE_READ(ring)); |
750 | 856 | break; |
|
751 | error->hangcheck_score[ring->id] = ring->hangcheck.score; |
857 | } |
752 | error->hangcheck_action[ring->id] = ring->hangcheck.action; |
858 | } |
Line 764... | Line 870... | ||
764 | if (ring->id != RCS || !error->ccid) |
870 | if (ring->id != RCS || !error->ccid) |
765 | return; |
871 | return; |
Line 766... | Line 872... | ||
766 | 872 | ||
767 | list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { |
873 | list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { |
768 | if ((error->ccid & PAGE_MASK) == i915_gem_obj_ggtt_offset(obj)) { |
874 | if ((error->ccid & PAGE_MASK) == i915_gem_obj_ggtt_offset(obj)) { |
769 | ering->ctx = i915_error_object_create_sized(dev_priv, |
- | |
770 | obj, 1); |
875 | ering->ctx = i915_error_ggtt_object_create(dev_priv, obj); |
771 | break; |
876 | break; |
772 | } |
877 | } |
773 | } |
878 | } |
Line 779... | Line 884... | ||
779 | struct drm_i915_private *dev_priv = dev->dev_private; |
884 | struct drm_i915_private *dev_priv = dev->dev_private; |
780 | struct drm_i915_gem_request *request; |
885 | struct drm_i915_gem_request *request; |
781 | int i, count; |
886 | int i, count; |
Line 782... | Line 887... | ||
782 | 887 | ||
783 | for (i = 0; i < I915_NUM_RINGS; i++) { |
888 | for (i = 0; i < I915_NUM_RINGS; i++) { |
- | 889 | struct intel_engine_cs *ring = &dev_priv->ring[i]; |
|
- | 890 | ||
Line 784... | Line 891... | ||
784 | struct intel_ring_buffer *ring = &dev_priv->ring[i]; |
891 | error->ring[i].pid = -1; |
785 | 892 | ||
Line 786... | Line 893... | ||
786 | if (ring->dev == NULL) |
893 | if (ring->dev == NULL) |
Line 787... | Line 894... | ||
787 | continue; |
894 | continue; |
Line -... | Line 895... | ||
- | 895 | ||
- | 896 | error->ring[i].valid = true; |
|
- | 897 | ||
- | 898 | i915_record_ring_state(dev, ring, &error->ring[i]); |
|
- | 899 | ||
- | 900 | request = i915_gem_find_active_request(ring); |
|
788 | 901 | if (request) { |
|
789 | error->ring[i].valid = true; |
902 | /* We need to copy these to an anonymous buffer |
- | 903 | * as the simplest method to avoid being overwritten |
|
- | 904 | * by userspace. |
|
- | 905 | */ |
|
- | 906 | error->ring[i].batchbuffer = |
|
- | 907 | i915_error_object_create(dev_priv, |
|
- | 908 | request->batch_obj, |
|
- | 909 | request->ctx ? |
|
- | 910 | request->ctx->vm : |
|
- | 911 | &dev_priv->gtt.base); |
|
- | 912 | ||
- | 913 | if (HAS_BROKEN_CS_TLB(dev_priv->dev) && |
|
- | 914 | ring->scratch.obj) |
|
- | 915 | error->ring[i].wa_batchbuffer = |
|
- | 916 | i915_error_ggtt_object_create(dev_priv, |
|
- | 917 | ring->scratch.obj); |
|
- | 918 | ||
- | 919 | if (request->file_priv) { |
|
- | 920 | struct task_struct *task; |
|
- | 921 | ||
- | 922 | rcu_read_lock(); |
|
- | 923 | task = pid_task(request->file_priv->file->pid, |
|
- | 924 | PIDTYPE_PID); |
|
- | 925 | if (task) { |
|
- | 926 | strcpy(error->ring[i].comm, task->comm); |
|
Line 790... | Line 927... | ||
790 | 927 | error->ring[i].pid = task->pid; |
|
791 | i915_record_ring_state(dev, error, ring); |
928 | } |
Line -... | Line 929... | ||
- | 929 | rcu_read_unlock(); |
|
- | 930 | } |
|
- | 931 | } |
|
Line 792... | Line 932... | ||
792 | 932 | ||
Line 793... | Line 933... | ||
793 | error->ring[i].batchbuffer = |
933 | error->ring[i].ringbuffer = |
794 | i915_error_first_batchbuffer(dev_priv, ring); |
934 | i915_error_ggtt_object_create(dev_priv, ring->buffer->obj); |
Line 840... | Line 980... | ||
840 | i = 0; |
980 | i = 0; |
841 | list_for_each_entry(vma, &vm->active_list, mm_list) |
981 | list_for_each_entry(vma, &vm->active_list, mm_list) |
842 | i++; |
982 | i++; |
843 | error->active_bo_count[ndx] = i; |
983 | error->active_bo_count[ndx] = i; |
844 | list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) |
984 | list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) |
845 | if (obj->pin_count) |
985 | if (i915_gem_obj_is_pinned(obj)) |
846 | i++; |
986 | i++; |
847 | error->pinned_bo_count[ndx] = i - error->active_bo_count[ndx]; |
987 | error->pinned_bo_count[ndx] = i - error->active_bo_count[ndx]; |
Line 848... | Line 988... | ||
848 | 988 | ||
849 | if (i) { |
989 | if (i) { |
Line 874... | Line 1014... | ||
874 | int cnt = 0, i = 0; |
1014 | int cnt = 0, i = 0; |
Line 875... | Line 1015... | ||
875 | 1015 | ||
876 | list_for_each_entry(vm, &dev_priv->vm_list, global_link) |
1016 | list_for_each_entry(vm, &dev_priv->vm_list, global_link) |
Line 877... | Line -... | ||
877 | cnt++; |
- | |
878 | - | ||
879 | if (WARN(cnt > 1, "Multiple VMs not yet supported\n")) |
- | |
880 | cnt = 1; |
- | |
881 | - | ||
882 | vm = &dev_priv->gtt.base; |
1017 | cnt++; |
883 | 1018 | ||
884 | error->active_bo = kcalloc(cnt, sizeof(*error->active_bo), GFP_ATOMIC); |
1019 | error->active_bo = kcalloc(cnt, sizeof(*error->active_bo), GFP_ATOMIC); |
885 | error->pinned_bo = kcalloc(cnt, sizeof(*error->pinned_bo), GFP_ATOMIC); |
1020 | error->pinned_bo = kcalloc(cnt, sizeof(*error->pinned_bo), GFP_ATOMIC); |
886 | error->active_bo_count = kcalloc(cnt, sizeof(*error->active_bo_count), |
1021 | error->active_bo_count = kcalloc(cnt, sizeof(*error->active_bo_count), |
Line 890... | Line 1025... | ||
890 | 1025 | ||
891 | list_for_each_entry(vm, &dev_priv->vm_list, global_link) |
1026 | list_for_each_entry(vm, &dev_priv->vm_list, global_link) |
892 | i915_gem_capture_vm(dev_priv, error, vm, i++); |
1027 | i915_gem_capture_vm(dev_priv, error, vm, i++); |
Line -... | Line 1028... | ||
- | 1028 | } |
|
- | 1029 | ||
- | 1030 | /* Capture all registers which don't fit into another category. */ |
|
- | 1031 | static void i915_capture_reg_state(struct drm_i915_private *dev_priv, |
|
- | 1032 | struct drm_i915_error_state *error) |
|
- | 1033 | { |
|
- | 1034 | struct drm_device *dev = dev_priv->dev; |
|
- | 1035 | ||
- | 1036 | /* General organization |
|
- | 1037 | * 1. Registers specific to a single generation |
|
- | 1038 | * 2. Registers which belong to multiple generations |
|
- | 1039 | * 3. Feature specific registers. |
|
- | 1040 | * 4. Everything else |
|
- | 1041 | * Please try to follow the order. |
|
- | 1042 | */ |
|
- | 1043 | ||
- | 1044 | /* 1: Registers specific to a single generation */ |
|
- | 1045 | if (IS_VALLEYVIEW(dev)) { |
|
- | 1046 | error->ier = I915_READ(GTIER) | I915_READ(VLV_IER); |
|
- | 1047 | error->forcewake = I915_READ(FORCEWAKE_VLV); |
|
- | 1048 | } |
|
- | 1049 | ||
- | 1050 | if (IS_GEN7(dev)) |
|
- | 1051 | error->err_int = I915_READ(GEN7_ERR_INT); |
|
- | 1052 | ||
- | 1053 | if (IS_GEN6(dev)) { |
|
- | 1054 | error->forcewake = I915_READ(FORCEWAKE); |
|
- | 1055 | error->gab_ctl = I915_READ(GAB_CTL); |
|
- | 1056 | error->gfx_mode = I915_READ(GFX_MODE); |
|
- | 1057 | } |
|
- | 1058 | ||
- | 1059 | /* 2: Registers which belong to multiple generations */ |
|
- | 1060 | if (INTEL_INFO(dev)->gen >= 7) |
|
- | 1061 | error->forcewake = I915_READ(FORCEWAKE_MT); |
|
- | 1062 | ||
- | 1063 | if (INTEL_INFO(dev)->gen >= 6) { |
|
- | 1064 | error->derrmr = I915_READ(DERRMR); |
|
- | 1065 | error->error = I915_READ(ERROR_GEN6); |
|
- | 1066 | error->done_reg = I915_READ(DONE_REG); |
|
- | 1067 | } |
|
- | 1068 | ||
- | 1069 | /* 3: Feature specific registers */ |
|
- | 1070 | if (IS_GEN6(dev) || IS_GEN7(dev)) { |
|
- | 1071 | error->gam_ecochk = I915_READ(GAM_ECOCHK); |
|
- | 1072 | error->gac_eco = I915_READ(GAC_ECO_BITS); |
|
- | 1073 | } |
|
- | 1074 | ||
- | 1075 | /* 4: Everything else */ |
|
- | 1076 | if (HAS_HW_CONTEXTS(dev)) |
|
- | 1077 | error->ccid = I915_READ(CCID); |
|
- | 1078 | ||
- | 1079 | if (HAS_PCH_SPLIT(dev)) |
|
- | 1080 | error->ier = I915_READ(DEIER) | I915_READ(GTIER); |
|
- | 1081 | else { |
|
- | 1082 | if (IS_GEN2(dev)) |
|
- | 1083 | error->ier = I915_READ16(IER); |
|
- | 1084 | else |
|
- | 1085 | error->ier = I915_READ(IER); |
|
- | 1086 | } |
|
- | 1087 | ||
- | 1088 | /* 4: Everything else */ |
|
- | 1089 | error->eir = I915_READ(EIR); |
|
- | 1090 | error->pgtbl_er = I915_READ(PGTBL_ER); |
|
- | 1091 | ||
- | 1092 | i915_get_extra_instdone(dev, error->extra_instdone); |
|
- | 1093 | } |
|
- | 1094 | ||
- | 1095 | static void i915_error_capture_msg(struct drm_device *dev, |
|
- | 1096 | struct drm_i915_error_state *error, |
|
- | 1097 | bool wedged, |
|
- | 1098 | const char *error_msg) |
|
- | 1099 | { |
|
- | 1100 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 1101 | u32 ecode; |
|
- | 1102 | int ring_id = -1, len; |
|
- | 1103 | ||
- | 1104 | ecode = i915_error_generate_code(dev_priv, error, &ring_id); |
|
- | 1105 | ||
- | 1106 | len = scnprintf(error->error_msg, sizeof(error->error_msg), |
|
- | 1107 | "GPU HANG: ecode %d:0x%08x", ring_id, ecode); |
|
- | 1108 | ||
- | 1109 | if (ring_id != -1 && error->ring[ring_id].pid != -1) |
|
- | 1110 | len += scnprintf(error->error_msg + len, |
|
- | 1111 | sizeof(error->error_msg) - len, |
|
- | 1112 | ", in %s [%d]", |
|
- | 1113 | error->ring[ring_id].comm, |
|
- | 1114 | error->ring[ring_id].pid); |
|
- | 1115 | ||
- | 1116 | scnprintf(error->error_msg + len, sizeof(error->error_msg) - len, |
|
- | 1117 | ", reason: %s, action: %s", |
|
- | 1118 | error_msg, |
|
- | 1119 | wedged ? "reset" : "continue"); |
|
- | 1120 | } |
|
- | 1121 | ||
- | 1122 | static void i915_capture_gen_state(struct drm_i915_private *dev_priv, |
|
- | 1123 | struct drm_i915_error_state *error) |
|
- | 1124 | { |
|
- | 1125 | error->reset_count = i915_reset_count(&dev_priv->gpu_error); |
|
- | 1126 | error->suspend_count = dev_priv->suspend_count; |
|
893 | } |
1127 | } |
894 | 1128 | ||
895 | /** |
1129 | /** |
896 | * i915_capture_error_state - capture an error record for later analysis |
1130 | * i915_capture_error_state - capture an error record for later analysis |
897 | * @dev: drm device |
1131 | * @dev: drm device |
898 | * |
1132 | * |
899 | * Should be called when an error is detected (either a hang or an error |
1133 | * Should be called when an error is detected (either a hang or an error |
900 | * interrupt) to capture error state from the time of the error. Fills |
1134 | * interrupt) to capture error state from the time of the error. Fills |
901 | * out a structure which becomes available in debugfs for user level tools |
1135 | * out a structure which becomes available in debugfs for user level tools |
902 | * to pick up. |
1136 | * to pick up. |
- | 1137 | */ |
|
903 | */ |
1138 | void i915_capture_error_state(struct drm_device *dev, bool wedged, |
- | 1139 | const char *error_msg) |
|
904 | void i915_capture_error_state(struct drm_device *dev) |
1140 | { |
905 | { |
1141 | static bool warned; |
906 | struct drm_i915_private *dev_priv = dev->dev_private; |
1142 | struct drm_i915_private *dev_priv = dev->dev_private; |
907 | struct drm_i915_error_state *error; |
- | |
908 | unsigned long flags; |
- | |
909 | int pipe; |
- | |
910 | - | ||
911 | spin_lock_irqsave(&dev_priv->gpu_error.lock, flags); |
- | |
912 | error = dev_priv->gpu_error.first_error; |
- | |
913 | spin_unlock_irqrestore(&dev_priv->gpu_error.lock, flags); |
- | |
Line 914... | Line 1143... | ||
914 | if (error) |
1143 | struct drm_i915_error_state *error; |
915 | return; |
1144 | unsigned long flags; |
916 | 1145 | ||
917 | /* Account for pipe specific data like PIPE*STAT */ |
1146 | /* Account for pipe specific data like PIPE*STAT */ |
918 | error = kzalloc(sizeof(*error), GFP_ATOMIC); |
1147 | error = kzalloc(sizeof(*error), GFP_ATOMIC); |
919 | if (!error) { |
1148 | if (!error) { |
Line 920... | Line -... | ||
920 | DRM_DEBUG_DRIVER("out of memory, not capturing error state\n"); |
- | |
921 | return; |
- | |
922 | } |
- | |
923 | - | ||
924 | DRM_INFO("GPU crash dump saved to /sys/class/drm/card%d/error\n", |
- | |
925 | dev->primary->index); |
- | |
926 | DRM_INFO("GPU hangs can indicate a bug anywhere in the entire gfx stack, including userspace.\n"); |
- | |
927 | DRM_INFO("Please file a _new_ bug report on bugs.freedesktop.org against DRI -> DRM/Intel\n"); |
1149 | DRM_DEBUG_DRIVER("out of memory, not capturing error state\n"); |
928 | DRM_INFO("drm/i915 developers can then reassign to the right component if it's not a kernel issue.\n"); |
- | |
929 | DRM_INFO("The gpu crash dump is required to analyze gpu hangs, so please always attach it.\n"); |
- | |
930 | - | ||
931 | kref_init(&error->ref); |
- | |
932 | error->eir = I915_READ(EIR); |
- | |
933 | error->pgtbl_er = I915_READ(PGTBL_ER); |
- | |
934 | if (HAS_HW_CONTEXTS(dev)) |
- | |
935 | error->ccid = I915_READ(CCID); |
- | |
936 | - | ||
937 | if (HAS_PCH_SPLIT(dev)) |
- | |
938 | error->ier = I915_READ(DEIER) | I915_READ(GTIER); |
- | |
939 | else if (IS_VALLEYVIEW(dev)) |
- | |
940 | error->ier = I915_READ(GTIER) | I915_READ(VLV_IER); |
- | |
941 | else if (IS_GEN2(dev)) |
- | |
942 | error->ier = I915_READ16(IER); |
- | |
943 | else |
- | |
944 | error->ier = I915_READ(IER); |
- | |
945 | - | ||
946 | if (INTEL_INFO(dev)->gen >= 6) |
- | |
947 | error->derrmr = I915_READ(DERRMR); |
- | |
948 | - | ||
949 | if (IS_VALLEYVIEW(dev)) |
- | |
950 | error->forcewake = I915_READ(FORCEWAKE_VLV); |
- | |
951 | else if (INTEL_INFO(dev)->gen >= 7) |
- | |
952 | error->forcewake = I915_READ(FORCEWAKE_MT); |
- | |
953 | else if (INTEL_INFO(dev)->gen == 6) |
- | |
954 | error->forcewake = I915_READ(FORCEWAKE); |
- | |
955 | - | ||
956 | if (!HAS_PCH_SPLIT(dev)) |
- | |
957 | for_each_pipe(pipe) |
- | |
958 | error->pipestat[pipe] = I915_READ(PIPESTAT(pipe)); |
- | |
959 | - | ||
960 | if (INTEL_INFO(dev)->gen >= 6) { |
- | |
961 | error->error = I915_READ(ERROR_GEN6); |
- | |
962 | error->done_reg = I915_READ(DONE_REG); |
- | |
963 | } |
- | |
964 | - | ||
Line -... | Line 1150... | ||
- | 1150 | return; |
|
- | 1151 | } |
|
965 | if (INTEL_INFO(dev)->gen == 7) |
1152 | |
966 | error->err_int = I915_READ(GEN7_ERR_INT); |
1153 | kref_init(&error->ref); |
967 | 1154 | ||
Line 968... | Line 1155... | ||
968 | i915_get_extra_instdone(dev, error->extra_instdone); |
1155 | i915_capture_gen_state(dev_priv, error); |
Line 969... | Line 1156... | ||
969 | 1156 | i915_capture_reg_state(dev_priv, error); |
|
970 | i915_gem_capture_buffers(dev_priv, error); |
1157 | i915_gem_capture_buffers(dev_priv, error); |
Line -... | Line 1158... | ||
- | 1158 | i915_gem_record_fences(dev, error); |
|
- | 1159 | i915_gem_record_rings(dev, error); |
|
- | 1160 | ||
971 | i915_gem_record_fences(dev, error); |
1161 | do_gettimeofday(&error->time); |
972 | i915_gem_record_rings(dev, error); |
1162 | |
973 | 1163 | error->overlay = intel_overlay_capture_error_state(dev); |
|
974 | do_gettimeofday(&error->time); |
1164 | error->display = intel_display_capture_error_state(dev); |
975 | 1165 | ||
976 | error->overlay = intel_overlay_capture_error_state(dev); |
1166 | i915_error_capture_msg(dev, error, wedged, error_msg); |
Line 977... | Line 1167... | ||
977 | error->display = intel_display_capture_error_state(dev); |
1167 | DRM_INFO("%s\n", error->error_msg); |
978 | 1168 | ||
- | 1169 | spin_lock_irqsave(&dev_priv->gpu_error.lock, flags); |
|
- | 1170 | if (dev_priv->gpu_error.first_error == NULL) { |
|
- | 1171 | dev_priv->gpu_error.first_error = error; |
|
- | 1172 | error = NULL; |
|
- | 1173 | } |
|
- | 1174 | spin_unlock_irqrestore(&dev_priv->gpu_error.lock, flags); |
|
- | 1175 | ||
- | 1176 | if (error) { |
|
- | 1177 | i915_error_state_free(&error->ref); |
|
- | 1178 | return; |
|
- | 1179 | } |
|
979 | spin_lock_irqsave(&dev_priv->gpu_error.lock, flags); |
1180 | |
Line 980... | Line 1181... | ||
980 | if (dev_priv->gpu_error.first_error == NULL) { |
1181 | if (!warned) { |
981 | dev_priv->gpu_error.first_error = error; |
1182 | DRM_INFO("GPU hangs can indicate a bug anywhere in the entire gfx stack, including userspace.\n"); |
982 | error = NULL; |
1183 | DRM_INFO("Please file a _new_ bug report on bugs.freedesktop.org against DRI -> DRM/Intel\n"); |