aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_gem.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem.c')
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c70
1 files changed, 58 insertions, 12 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 6d2180cf3da..c8a5b04bc8d 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1869,34 +1869,82 @@ i915_gem_check_olr(struct intel_ring_buffer *ring, u32 seqno)
1869 return ret; 1869 return ret;
1870} 1870}
1871 1871
1872/**
1873 * __wait_seqno - wait until execution of seqno has finished
1874 * @ring: the ring expected to report seqno
1875 * @seqno: duh!
1876 * @interruptible: do an interruptible wait (normally yes)
1877 * @timeout: in - how long to wait (NULL forever); out - how much time remaining
1878 *
1879 * Returns 0 if the seqno was found within the alloted time. Else returns the
1880 * errno with remaining time filled in timeout argument.
1881 */
1872static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno, 1882static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno,
1873 bool interruptible) 1883 bool interruptible, struct timespec *timeout)
1874{ 1884{
1875 drm_i915_private_t *dev_priv = ring->dev->dev_private; 1885 drm_i915_private_t *dev_priv = ring->dev->dev_private;
1876 int ret = 0; 1886 struct timespec before, now, wait_time={1,0};
1887 unsigned long timeout_jiffies;
1888 long end;
1889 bool wait_forever = true;
1877 1890
1878 if (i915_seqno_passed(ring->get_seqno(ring), seqno)) 1891 if (i915_seqno_passed(ring->get_seqno(ring), seqno))
1879 return 0; 1892 return 0;
1880 1893
1881 trace_i915_gem_request_wait_begin(ring, seqno); 1894 trace_i915_gem_request_wait_begin(ring, seqno);
1895
1896 if (timeout != NULL) {
1897 wait_time = *timeout;
1898 wait_forever = false;
1899 }
1900
1901 timeout_jiffies = timespec_to_jiffies(&wait_time);
1902
1882 if (WARN_ON(!ring->irq_get(ring))) 1903 if (WARN_ON(!ring->irq_get(ring)))
1883 return -ENODEV; 1904 return -ENODEV;
1884 1905
1906 /* Record current time in case interrupted by signal, or wedged * */
1907 getrawmonotonic(&before);
1908
1885#define EXIT_COND \ 1909#define EXIT_COND \
1886 (i915_seqno_passed(ring->get_seqno(ring), seqno) || \ 1910 (i915_seqno_passed(ring->get_seqno(ring), seqno) || \
1887 atomic_read(&dev_priv->mm.wedged)) 1911 atomic_read(&dev_priv->mm.wedged))
1912 do {
1913 if (interruptible)
1914 end = wait_event_interruptible_timeout(ring->irq_queue,
1915 EXIT_COND,
1916 timeout_jiffies);
1917 else
1918 end = wait_event_timeout(ring->irq_queue, EXIT_COND,
1919 timeout_jiffies);
1888 1920
1889 if (interruptible) 1921 if (atomic_read(&dev_priv->mm.wedged))
1890 ret = wait_event_interruptible(ring->irq_queue, 1922 end = -EAGAIN;
1891 EXIT_COND); 1923 } while (end == 0 && wait_forever);
1892 else 1924
1893 wait_event(ring->irq_queue, EXIT_COND); 1925 getrawmonotonic(&now);
1894 1926
1895 ring->irq_put(ring); 1927 ring->irq_put(ring);
1896 trace_i915_gem_request_wait_end(ring, seqno); 1928 trace_i915_gem_request_wait_end(ring, seqno);
1897#undef EXIT_COND 1929#undef EXIT_COND
1898 1930
1899 return ret; 1931 if (timeout) {
1932 struct timespec sleep_time = timespec_sub(now, before);
1933 *timeout = timespec_sub(*timeout, sleep_time);
1934 }
1935
1936 switch (end) {
1937 case -EAGAIN: /* Wedged */
1938 case -ERESTARTSYS: /* Signal */
1939 return (int)end;
1940 case 0: /* Timeout */
1941 if (timeout)
1942 set_normalized_timespec(timeout, 0, 0);
1943 return -ETIME;
1944 default: /* Completed */
1945 WARN_ON(end < 0); /* We're not aware of other errors */
1946 return 0;
1947 }
1900} 1948}
1901 1949
1902/** 1950/**
@@ -1920,9 +1968,7 @@ i915_wait_request(struct intel_ring_buffer *ring,
1920 if (ret) 1968 if (ret)
1921 return ret; 1969 return ret;
1922 1970
1923 ret = __wait_seqno(ring, seqno, dev_priv->mm.interruptible); 1971 ret = __wait_seqno(ring, seqno, dev_priv->mm.interruptible, NULL);
1924 if (atomic_read(&dev_priv->mm.wedged))
1925 ret = -EAGAIN;
1926 1972
1927 return ret; 1973 return ret;
1928} 1974}
@@ -3002,7 +3048,7 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file)
3002 if (seqno == 0) 3048 if (seqno == 0)
3003 return 0; 3049 return 0;
3004 3050
3005 ret = __wait_seqno(ring, seqno, true); 3051 ret = __wait_seqno(ring, seqno, true, NULL);
3006 if (ret == 0) 3052 if (ret == 0)
3007 queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, 0); 3053 queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, 0);
3008 3054