summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOscar Mateo <oscar.mateo@intel.com>2014-07-24 17:04:41 +0100
committerDaniel Vetter <daniel.vetter@ffwll.ch>2014-08-14 22:44:04 +0200
commitf1ad5a1fd4127b3a5e21b8f5ef7f1921a5d3063e (patch)
treee2adc3826c1d539acb569535937947253f8cc07d
parente1fee72c2ea2e9c0c6e6743d32a6832f21337d6c (diff)
downloadop-kernel-dev-f1ad5a1fd4127b3a5e21b8f5ef7f1921a5d3063e.zip
op-kernel-dev-f1ad5a1fd4127b3a5e21b8f5ef7f1921a5d3063e.tar.gz
drm/i915/bdw: Help out the ctx switch interrupt handler
If we receive a storm of requests for the same context (see gem_storedw_loop_*) we might end up iterating over too many elements in interrupt time, looking for contexts to squash together. Instead, share the burden by giving more intelligence to the queue function. At most, the interrupt will iterate over three elements. Signed-off-by: Oscar Mateo <oscar.mateo@intel.com> Reviewed-by: Damien Lespiau <damien.lespiau@intel.com> [danvet: Checkpatch.] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--drivers/gpu/drm/i915/intel_lrc.c26
1 files changed, 22 insertions, 4 deletions
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 0f1b6b2..6f6c5a9 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -392,10 +392,10 @@ static int execlists_context_queue(struct intel_engine_cs *ring,
struct intel_context *to,
u32 tail)
{
- struct intel_ctx_submit_request *req = NULL;
+ struct intel_ctx_submit_request *req = NULL, *cursor;
struct drm_i915_private *dev_priv = ring->dev->dev_private;
unsigned long flags;
- bool was_empty;
+ int num_elements = 0;
req = kzalloc(sizeof(*req), GFP_KERNEL);
if (req == NULL)
@@ -410,9 +410,27 @@ static int execlists_context_queue(struct intel_engine_cs *ring,
spin_lock_irqsave(&ring->execlist_lock, flags);
- was_empty = list_empty(&ring->execlist_queue);
+ list_for_each_entry(cursor, &ring->execlist_queue, execlist_link)
+ if (++num_elements > 2)
+ break;
+
+ if (num_elements > 2) {
+ struct intel_ctx_submit_request *tail_req;
+
+ tail_req = list_last_entry(&ring->execlist_queue,
+ struct intel_ctx_submit_request,
+ execlist_link);
+
+ if (to == tail_req->ctx) {
+ WARN(tail_req->elsp_submitted != 0,
+ "More than 2 already-submitted reqs queued\n");
+ list_del(&tail_req->execlist_link);
+ queue_work(dev_priv->wq, &tail_req->work);
+ }
+ }
+
list_add_tail(&req->execlist_link, &ring->execlist_queue);
- if (was_empty)
+ if (num_elements == 0)
execlists_context_unqueue(ring);
spin_unlock_irqrestore(&ring->execlist_lock, flags);
OpenPOWER on IntegriCloud