[gem] Replace ring throttling hack with actual time measurement.
parent
54fa32cdfe
commit
d6f7968577
|
@ -154,6 +154,7 @@ i915_add_request(struct drm_device *dev)
|
||||||
DRM_DEBUG("%d\n", seqno);
|
DRM_DEBUG("%d\n", seqno);
|
||||||
|
|
||||||
request->seqno = seqno;
|
request->seqno = seqno;
|
||||||
|
request->emitted_jiffies = jiffies;
|
||||||
list_add_tail(&request->list, &dev_priv->mm.request_list);
|
list_add_tail(&request->list, &dev_priv->mm.request_list);
|
||||||
|
|
||||||
return seqno;
|
return seqno;
|
||||||
|
@ -966,34 +967,38 @@ i915_dispatch_gem_execbuffer(struct drm_device *dev,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Throttle our rendering by waiting until the ring has completed our requests
|
||||||
* Kludge -- wait for almost all rendering to complete
|
* emitted over 20 msec ago.
|
||||||
* before queuing more. This uses interrupts, so the wakeup
|
*
|
||||||
* occurs without any delay.
|
* This should get us reasonable parallelism between CPU and GPU but also
|
||||||
|
* relatively low latency when blocking on a particular request to finish.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
i915_gem_wait_space(struct drm_device *dev)
|
i915_gem_ring_throttle(struct drm_device *dev)
|
||||||
{
|
{
|
||||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||||
drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
|
|
||||||
struct drm_i915_gem_object *obj_priv, *last_priv = NULL;
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
mutex_lock(&dev->struct_mutex);
|
mutex_lock(&dev->struct_mutex);
|
||||||
while (ring->space + 1024 < dev_priv->ring.Size &&
|
while (!list_empty(&dev_priv->mm.request_list)) {
|
||||||
!list_empty(&dev_priv->mm.active_list)) {
|
struct drm_i915_gem_request *request;
|
||||||
obj_priv = list_first_entry(&dev_priv->mm.active_list,
|
|
||||||
struct drm_i915_gem_object,
|
request = list_first_entry(&dev_priv->mm.request_list,
|
||||||
list);
|
struct drm_i915_gem_request,
|
||||||
if (obj_priv == last_priv)
|
list);
|
||||||
break;
|
|
||||||
drm_gem_object_reference(obj_priv->obj);
|
/* Break out if we're close enough. */
|
||||||
ret = i915_gem_object_wait_rendering(obj_priv->obj);
|
if (jiffies_to_msecs(jiffies - request->emitted_jiffies) < 20) {
|
||||||
drm_gem_object_unreference(obj_priv->obj);
|
mutex_unlock(&dev->struct_mutex);
|
||||||
if (ret)
|
return 0;
|
||||||
break;
|
}
|
||||||
last_priv = obj_priv;
|
|
||||||
i915_kernel_lost_context(dev);
|
/* Wait on the last request if not. */
|
||||||
|
ret = i915_wait_request(dev, request->seqno);
|
||||||
|
if (ret != 0) {
|
||||||
|
mutex_unlock(&dev->struct_mutex);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mutex_unlock(&dev->struct_mutex);
|
mutex_unlock(&dev->struct_mutex);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1019,7 +1024,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
|
||||||
#endif
|
#endif
|
||||||
i915_kernel_lost_context(dev);
|
i915_kernel_lost_context(dev);
|
||||||
|
|
||||||
ret = i915_gem_wait_space(dev);
|
ret = i915_gem_ring_throttle(dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
|
|
@ -331,6 +331,9 @@ struct drm_i915_gem_request {
|
||||||
/** GEM sequence number associated with this request. */
|
/** GEM sequence number associated with this request. */
|
||||||
uint32_t seqno;
|
uint32_t seqno;
|
||||||
|
|
||||||
|
/** Time at which this request was emitted, in jiffies. */
|
||||||
|
unsigned long emitted_jiffies;
|
||||||
|
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue