diff options
author | Dave Airlie <airlied@redhat.com> | 2017-12-03 18:40:35 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2017-12-03 19:56:53 -0500 |
commit | ca797d29cd63e7b71b4eea29aff3b1cefd1ecb59 (patch) | |
tree | db1ada69f713da68b43c828bd15f90e250f86ab7 /drivers/gpu/drm/i915/i915_gpu_error.c | |
parent | 2c1c55cb75a9c72f9726fabb8c3607947711a8df (diff) | |
parent | 010d118c20617021025a930bc8e90f371ab99da5 (diff) |
Merge tag 'drm-intel-next-2017-11-17-1' of git://anongit.freedesktop.org/drm/drm-intel into drm-next
More change sets for 4.16:
- Many improvements for selftests and other igt tests (Chris)
- Forcewake with PUNIT->PMIC bus fixes and robustness (Hans)
- Define an engine class for uABI (Tvrtko)
- Context switch fixes and improvements (Chris)
- GT powersavings and power gating simplification and fixes (Chris)
- Other general driver clean-ups (Chris, Lucas, Ville)
- Removing old, useless and/or bad workarounds (Chris, Oscar, Radhakrishna)
- IPS, pipe config, etc in preparation for another Fast Boot attempt (Maarten)
- OA perf fixes and support to Coffee Lake and Cannonlake (Lionel)
- Fixes around GPU fault registers (Michel)
- GEM Proxy (Tina)
- Refactor of Geminilake and Cannonlake plane color handling (James)
- Generalize transcoder loop (Mika Kahola)
- New HW Workaround for Cannonlake and Geminilake (Rodrigo)
- Resume GuC before using GEM (Chris)
- Stolen Memory handling improvements (Ville)
- Initialize entry in PPAT for older compilers (Chris)
- Other fixes and robustness improvements on execbuf (Chris)
- Improve logs of GEM_BUG_ON (Mika Kuoppala)
- Rework with massive rename of GuC functions and files (Sagar)
- Don't sanitize frame start delay if pipe is off (Ville)
- Cannonlake clock fixes (Rodrigo)
- Cannonlake HDMI 2.0 support (Rodrigo)
- Add a GuC doorbells selftest (Michel)
- Add might_sleep() check to our wait_for() (Chris)
Many GVT changes for 4.16:
- CSB HWSP update support (Weinan)
- GVT debug helpers, dyndbg and debugfs (Chuanxiao, Shuo)
- full virtualized opregion (Xiaolin)
- VM health check for sane fallback (Fred)
- workload submission code refactor for future enabling (Zhi)
- Updated repo URL in MAINTAINERS (Zhenyu)
- other many misc fixes
* tag 'drm-intel-next-2017-11-17-1' of git://anongit.freedesktop.org/drm/drm-intel: (260 commits)
drm/i915: Update DRIVER_DATE to 20171117
drm/i915: Add a policy note for removing workarounds
drm/i915/selftests: Report ENOMEM clearly for an allocation failure
Revert "drm/i915: Display WA #1133 WaFbcSkipSegments:cnl, glk"
drm/i915: Calculate g4x intermediate watermarks correctly
drm/i915: Calculate vlv/chv intermediate watermarks correctly, v3.
drm/i915: Pass crtc_state to ips toggle functions, v2
drm/i915: Pass idle crtc_state to intel_dp_sink_crc
drm/i915: Enable FIFO underrun reporting after initial fastset, v4.
drm/i915: Mark the userptr invalidate workqueue as WQ_MEM_RECLAIM
drm/i915: Add might_sleep() check to wait_for()
drm/i915/selftests: Add a GuC doorbells selftest
drm/i915/cnl: Extend HDMI 2.0 support to CNL.
drm/i915/cnl: Simplify dco_fraction calculation.
drm/i915/cnl: Don't blindly replace qdiv.
drm/i915/cnl: Fix wrpll math for higher freqs.
drm/i915/cnl: Fix, simplify and unify wrpll variable sizes.
drm/i915/cnl: Remove useless conversion.
drm/i915/cnl: Remove spurious central_freq.
drm/i915/selftests: exercise_ggtt may have nothing to do
...
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gpu_error.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gpu_error.c | 102 |
1 files changed, 82 insertions, 20 deletions
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 653fb69e7ecb..7481c8e1b5a8 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c | |||
@@ -30,6 +30,8 @@ | |||
30 | #include <generated/utsrelease.h> | 30 | #include <generated/utsrelease.h> |
31 | #include <linux/stop_machine.h> | 31 | #include <linux/stop_machine.h> |
32 | #include <linux/zlib.h> | 32 | #include <linux/zlib.h> |
33 | #include <drm/drm_print.h> | ||
34 | |||
33 | #include "i915_drv.h" | 35 | #include "i915_drv.h" |
34 | 36 | ||
35 | static const char *engine_str(int engine) | 37 | static const char *engine_str(int engine) |
@@ -175,6 +177,21 @@ static void i915_error_puts(struct drm_i915_error_state_buf *e, | |||
175 | #define err_printf(e, ...) i915_error_printf(e, __VA_ARGS__) | 177 | #define err_printf(e, ...) i915_error_printf(e, __VA_ARGS__) |
176 | #define err_puts(e, s) i915_error_puts(e, s) | 178 | #define err_puts(e, s) i915_error_puts(e, s) |
177 | 179 | ||
180 | static void __i915_printfn_error(struct drm_printer *p, struct va_format *vaf) | ||
181 | { | ||
182 | i915_error_vprintf(p->arg, vaf->fmt, *vaf->va); | ||
183 | } | ||
184 | |||
185 | static inline struct drm_printer | ||
186 | i915_error_printer(struct drm_i915_error_state_buf *e) | ||
187 | { | ||
188 | struct drm_printer p = { | ||
189 | .printfn = __i915_printfn_error, | ||
190 | .arg = e, | ||
191 | }; | ||
192 | return p; | ||
193 | } | ||
194 | |||
178 | #ifdef CONFIG_DRM_I915_COMPRESS_ERROR | 195 | #ifdef CONFIG_DRM_I915_COMPRESS_ERROR |
179 | 196 | ||
180 | struct compress { | 197 | struct compress { |
@@ -589,6 +606,21 @@ static void err_print_pciid(struct drm_i915_error_state_buf *m, | |||
589 | pdev->subsystem_device); | 606 | pdev->subsystem_device); |
590 | } | 607 | } |
591 | 608 | ||
609 | static void err_print_uc(struct drm_i915_error_state_buf *m, | ||
610 | const struct i915_error_uc *error_uc) | ||
611 | { | ||
612 | struct drm_printer p = i915_error_printer(m); | ||
613 | const struct i915_gpu_state *error = | ||
614 | container_of(error_uc, typeof(*error), uc); | ||
615 | |||
616 | if (!error->device_info.has_guc) | ||
617 | return; | ||
618 | |||
619 | intel_uc_fw_dump(&error_uc->guc_fw, &p); | ||
620 | intel_uc_fw_dump(&error_uc->huc_fw, &p); | ||
621 | print_error_obj(m, NULL, "GuC log buffer", error_uc->guc_log); | ||
622 | } | ||
623 | |||
592 | int i915_error_state_to_str(struct drm_i915_error_state_buf *m, | 624 | int i915_error_state_to_str(struct drm_i915_error_state_buf *m, |
593 | const struct i915_gpu_state *error) | 625 | const struct i915_gpu_state *error) |
594 | { | 626 | { |
@@ -763,8 +795,6 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, | |||
763 | 795 | ||
764 | print_error_obj(m, NULL, "Semaphores", error->semaphore); | 796 | print_error_obj(m, NULL, "Semaphores", error->semaphore); |
765 | 797 | ||
766 | print_error_obj(m, NULL, "GuC log buffer", error->guc_log); | ||
767 | |||
768 | if (error->overlay) | 798 | if (error->overlay) |
769 | intel_overlay_print_error_state(m, error->overlay); | 799 | intel_overlay_print_error_state(m, error->overlay); |
770 | 800 | ||
@@ -773,6 +803,7 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, | |||
773 | 803 | ||
774 | err_print_capabilities(m, &error->device_info); | 804 | err_print_capabilities(m, &error->device_info); |
775 | err_print_params(m, &error->params); | 805 | err_print_params(m, &error->params); |
806 | err_print_uc(m, &error->uc); | ||
776 | 807 | ||
777 | if (m->bytes == 0 && m->err) | 808 | if (m->bytes == 0 && m->err) |
778 | return m->err; | 809 | return m->err; |
@@ -831,6 +862,22 @@ static __always_inline void free_param(const char *type, void *x) | |||
831 | kfree(*(void **)x); | 862 | kfree(*(void **)x); |
832 | } | 863 | } |
833 | 864 | ||
865 | static void cleanup_params(struct i915_gpu_state *error) | ||
866 | { | ||
867 | #define FREE(T, x, ...) free_param(#T, &error->params.x); | ||
868 | I915_PARAMS_FOR_EACH(FREE); | ||
869 | #undef FREE | ||
870 | } | ||
871 | |||
872 | static void cleanup_uc_state(struct i915_gpu_state *error) | ||
873 | { | ||
874 | struct i915_error_uc *error_uc = &error->uc; | ||
875 | |||
876 | kfree(error_uc->guc_fw.path); | ||
877 | kfree(error_uc->huc_fw.path); | ||
878 | i915_error_object_free(error_uc->guc_log); | ||
879 | } | ||
880 | |||
834 | void __i915_gpu_state_free(struct kref *error_ref) | 881 | void __i915_gpu_state_free(struct kref *error_ref) |
835 | { | 882 | { |
836 | struct i915_gpu_state *error = | 883 | struct i915_gpu_state *error = |
@@ -857,7 +904,6 @@ void __i915_gpu_state_free(struct kref *error_ref) | |||
857 | } | 904 | } |
858 | 905 | ||
859 | i915_error_object_free(error->semaphore); | 906 | i915_error_object_free(error->semaphore); |
860 | i915_error_object_free(error->guc_log); | ||
861 | 907 | ||
862 | for (i = 0; i < ARRAY_SIZE(error->active_bo); i++) | 908 | for (i = 0; i < ARRAY_SIZE(error->active_bo); i++) |
863 | kfree(error->active_bo[i]); | 909 | kfree(error->active_bo[i]); |
@@ -866,9 +912,8 @@ void __i915_gpu_state_free(struct kref *error_ref) | |||
866 | kfree(error->overlay); | 912 | kfree(error->overlay); |
867 | kfree(error->display); | 913 | kfree(error->display); |
868 | 914 | ||
869 | #define FREE(T, x, ...) free_param(#T, &error->params.x); | 915 | cleanup_params(error); |
870 | I915_PARAMS_FOR_EACH(FREE); | 916 | cleanup_uc_state(error); |
871 | #undef FREE | ||
872 | 917 | ||
873 | kfree(error); | 918 | kfree(error); |
874 | } | 919 | } |
@@ -1172,11 +1217,13 @@ static void error_record_engine_registers(struct i915_gpu_state *error, | |||
1172 | 1217 | ||
1173 | if (INTEL_GEN(dev_priv) >= 6) { | 1218 | if (INTEL_GEN(dev_priv) >= 6) { |
1174 | ee->rc_psmi = I915_READ(RING_PSMI_CTL(engine->mmio_base)); | 1219 | ee->rc_psmi = I915_READ(RING_PSMI_CTL(engine->mmio_base)); |
1175 | ee->fault_reg = I915_READ(RING_FAULT_REG(engine)); | 1220 | if (INTEL_GEN(dev_priv) >= 8) { |
1176 | if (INTEL_GEN(dev_priv) >= 8) | ||
1177 | gen8_record_semaphore_state(error, engine, ee); | 1221 | gen8_record_semaphore_state(error, engine, ee); |
1178 | else | 1222 | ee->fault_reg = I915_READ(GEN8_RING_FAULT_REG); |
1223 | } else { | ||
1179 | gen6_record_semaphore_state(engine, ee); | 1224 | gen6_record_semaphore_state(engine, ee); |
1225 | ee->fault_reg = I915_READ(RING_FAULT_REG(engine)); | ||
1226 | } | ||
1180 | } | 1227 | } |
1181 | 1228 | ||
1182 | if (INTEL_GEN(dev_priv) >= 4) { | 1229 | if (INTEL_GEN(dev_priv) >= 4) { |
@@ -1559,15 +1606,25 @@ static void i915_capture_pinned_buffers(struct drm_i915_private *dev_priv, | |||
1559 | error->pinned_bo = bo; | 1606 | error->pinned_bo = bo; |
1560 | } | 1607 | } |
1561 | 1608 | ||
1562 | static void i915_gem_capture_guc_log_buffer(struct drm_i915_private *dev_priv, | 1609 | static void capture_uc_state(struct i915_gpu_state *error) |
1563 | struct i915_gpu_state *error) | ||
1564 | { | 1610 | { |
1565 | /* Capturing log buf contents won't be useful if logging was disabled */ | 1611 | struct drm_i915_private *i915 = error->i915; |
1566 | if (!dev_priv->guc.log.vma || (i915_modparams.guc_log_level < 0)) | 1612 | struct i915_error_uc *error_uc = &error->uc; |
1613 | |||
1614 | /* Capturing uC state won't be useful if there is no GuC */ | ||
1615 | if (!error->device_info.has_guc) | ||
1567 | return; | 1616 | return; |
1568 | 1617 | ||
1569 | error->guc_log = i915_error_object_create(dev_priv, | 1618 | error_uc->guc_fw = i915->guc.fw; |
1570 | dev_priv->guc.log.vma); | 1619 | error_uc->huc_fw = i915->huc.fw; |
1620 | |||
1621 | /* Non-default firmware paths will be specified by the modparam. | ||
1622 | * As modparams are generally accesible from the userspace make | ||
1623 | * explicit copies of the firmware paths. | ||
1624 | */ | ||
1625 | error_uc->guc_fw.path = kstrdup(i915->guc.fw.path, GFP_ATOMIC); | ||
1626 | error_uc->huc_fw.path = kstrdup(i915->huc.fw.path, GFP_ATOMIC); | ||
1627 | error_uc->guc_log = i915_error_object_create(i915, i915->guc.log.vma); | ||
1571 | } | 1628 | } |
1572 | 1629 | ||
1573 | /* Capture all registers which don't fit into another category. */ | 1630 | /* Capture all registers which don't fit into another category. */ |
@@ -1695,6 +1752,14 @@ static __always_inline void dup_param(const char *type, void *x) | |||
1695 | *(void **)x = kstrdup(*(void **)x, GFP_ATOMIC); | 1752 | *(void **)x = kstrdup(*(void **)x, GFP_ATOMIC); |
1696 | } | 1753 | } |
1697 | 1754 | ||
1755 | static void capture_params(struct i915_gpu_state *error) | ||
1756 | { | ||
1757 | error->params = i915_modparams; | ||
1758 | #define DUP(T, x, ...) dup_param(#T, &error->params.x); | ||
1759 | I915_PARAMS_FOR_EACH(DUP); | ||
1760 | #undef DUP | ||
1761 | } | ||
1762 | |||
1698 | static int capture(void *data) | 1763 | static int capture(void *data) |
1699 | { | 1764 | { |
1700 | struct i915_gpu_state *error = data; | 1765 | struct i915_gpu_state *error = data; |
@@ -1705,10 +1770,8 @@ static int capture(void *data) | |||
1705 | ktime_to_timeval(ktime_sub(ktime_get(), | 1770 | ktime_to_timeval(ktime_sub(ktime_get(), |
1706 | error->i915->gt.last_init_time)); | 1771 | error->i915->gt.last_init_time)); |
1707 | 1772 | ||
1708 | error->params = i915_modparams; | 1773 | capture_params(error); |
1709 | #define DUP(T, x, ...) dup_param(#T, &error->params.x); | 1774 | capture_uc_state(error); |
1710 | I915_PARAMS_FOR_EACH(DUP); | ||
1711 | #undef DUP | ||
1712 | 1775 | ||
1713 | i915_capture_gen_state(error->i915, error); | 1776 | i915_capture_gen_state(error->i915, error); |
1714 | i915_capture_reg_state(error->i915, error); | 1777 | i915_capture_reg_state(error->i915, error); |
@@ -1716,7 +1779,6 @@ static int capture(void *data) | |||
1716 | i915_gem_record_rings(error->i915, error); | 1779 | i915_gem_record_rings(error->i915, error); |
1717 | i915_capture_active_buffers(error->i915, error); | 1780 | i915_capture_active_buffers(error->i915, error); |
1718 | i915_capture_pinned_buffers(error->i915, error); | 1781 | i915_capture_pinned_buffers(error->i915, error); |
1719 | i915_gem_capture_guc_log_buffer(error->i915, error); | ||
1720 | 1782 | ||
1721 | error->overlay = intel_overlay_capture_error_state(error->i915); | 1783 | error->overlay = intel_overlay_capture_error_state(error->i915); |
1722 | error->display = intel_display_capture_error_state(error->i915); | 1784 | error->display = intel_display_capture_error_state(error->i915); |