aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_debugfs.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2013-09-25 12:34:55 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-10-03 14:01:30 -0400
commit094f9a54e35500739da185cdb78f2e92fc379458 (patch)
tree52487590c65d652f6915308746eacad8fb1aceec /drivers/gpu/drm/i915/i915_debugfs.c
parentcbb47d179fb345c579cd8cd884693903fceed26a (diff)
drm/i915: Fix __wait_seqno to use true infinite timeouts
When we switched to always using a timeout in conjunction with wait_seqno, we lost the ability to detect missed interrupts. Since, we have had issues with interrupts on a number of generations, and they are required to be delivered in a timely fashion for a smooth UX, it is important that we do log errors found in the wild and prevent the display stalling for upwards of 1s every time the seqno interrupt is missed. Rather than continue to fix up the timeouts to work around the interface impedence in wait_event_*(), open code the combination of wait_event[_interruptible][_timeout], and use the exposed timer to poll for seqno should we detect a lost interrupt. v2: In order to satisfy the debug requirement of logging missed interrupts with the real world requirments of making machines work even if interrupts are hosed, we revert to polling after detecting a missed interrupt. v3: Throw in a debugfs interface to simulate broken hw not reporting interrupts. v4: s/EGAIN/EAGAIN/ (Imre) Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Imre Deak <imre.deak@intel.com> [danvet: Don't use the struct typedef in new code.] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_debugfs.c')
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c68
1 files changed, 68 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index fcfa98844ccc..bc5c04d5890f 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1897,6 +1897,72 @@ DEFINE_SIMPLE_ATTRIBUTE(i915_ring_stop_fops,
1897 i915_ring_stop_get, i915_ring_stop_set, 1897 i915_ring_stop_get, i915_ring_stop_set,
1898 "0x%08llx\n"); 1898 "0x%08llx\n");
1899 1899
1900static int
1901i915_ring_missed_irq_get(void *data, u64 *val)
1902{
1903 struct drm_device *dev = data;
1904 struct drm_i915_private *dev_priv = dev->dev_private;
1905
1906 *val = dev_priv->gpu_error.missed_irq_rings;
1907 return 0;
1908}
1909
1910static int
1911i915_ring_missed_irq_set(void *data, u64 val)
1912{
1913 struct drm_device *dev = data;
1914 struct drm_i915_private *dev_priv = dev->dev_private;
1915 int ret;
1916
1917 /* Lock against concurrent debugfs callers */
1918 ret = mutex_lock_interruptible(&dev->struct_mutex);
1919 if (ret)
1920 return ret;
1921 dev_priv->gpu_error.missed_irq_rings = val;
1922 mutex_unlock(&dev->struct_mutex);
1923
1924 return 0;
1925}
1926
1927DEFINE_SIMPLE_ATTRIBUTE(i915_ring_missed_irq_fops,
1928 i915_ring_missed_irq_get, i915_ring_missed_irq_set,
1929 "0x%08llx\n");
1930
1931static int
1932i915_ring_test_irq_get(void *data, u64 *val)
1933{
1934 struct drm_device *dev = data;
1935 struct drm_i915_private *dev_priv = dev->dev_private;
1936
1937 *val = dev_priv->gpu_error.test_irq_rings;
1938
1939 return 0;
1940}
1941
1942static int
1943i915_ring_test_irq_set(void *data, u64 val)
1944{
1945 struct drm_device *dev = data;
1946 struct drm_i915_private *dev_priv = dev->dev_private;
1947 int ret;
1948
1949 DRM_DEBUG_DRIVER("Masking interrupts on rings 0x%08llx\n", val);
1950
1951 /* Lock against concurrent debugfs callers */
1952 ret = mutex_lock_interruptible(&dev->struct_mutex);
1953 if (ret)
1954 return ret;
1955
1956 dev_priv->gpu_error.test_irq_rings = val;
1957 mutex_unlock(&dev->struct_mutex);
1958
1959 return 0;
1960}
1961
1962DEFINE_SIMPLE_ATTRIBUTE(i915_ring_test_irq_fops,
1963 i915_ring_test_irq_get, i915_ring_test_irq_set,
1964 "0x%08llx\n");
1965
1900#define DROP_UNBOUND 0x1 1966#define DROP_UNBOUND 0x1
1901#define DROP_BOUND 0x2 1967#define DROP_BOUND 0x2
1902#define DROP_RETIRE 0x4 1968#define DROP_RETIRE 0x4
@@ -2290,6 +2356,8 @@ static struct i915_debugfs_files {
2290 {"i915_min_freq", &i915_min_freq_fops}, 2356 {"i915_min_freq", &i915_min_freq_fops},
2291 {"i915_cache_sharing", &i915_cache_sharing_fops}, 2357 {"i915_cache_sharing", &i915_cache_sharing_fops},
2292 {"i915_ring_stop", &i915_ring_stop_fops}, 2358 {"i915_ring_stop", &i915_ring_stop_fops},
2359 {"i915_ring_missed_irq", &i915_ring_missed_irq_fops},
2360 {"i915_ring_test_irq", &i915_ring_test_irq_fops},
2293 {"i915_gem_drop_caches", &i915_drop_caches_fops}, 2361 {"i915_gem_drop_caches", &i915_drop_caches_fops},
2294 {"i915_error_state", &i915_error_state_fops}, 2362 {"i915_error_state", &i915_error_state_fops},
2295 {"i915_next_seqno", &i915_next_seqno_fops}, 2363 {"i915_next_seqno", &i915_next_seqno_fops},