Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f1ad5a1f authored by Oscar Mateo's avatar Oscar Mateo Committed by Daniel Vetter
Browse files

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: default avatarOscar Mateo <oscar.mateo@intel.com>
Reviewed-by: default avatarDamien Lespiau <damien.lespiau@intel.com>
[danvet: Checkpatch.]
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent e1fee72c
Loading
Loading
Loading
Loading
+22 −4
Original line number Original line Diff line number Diff line
@@ -392,10 +392,10 @@ static int execlists_context_queue(struct intel_engine_cs *ring,
				   struct intel_context *to,
				   struct intel_context *to,
				   u32 tail)
				   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;
	struct drm_i915_private *dev_priv = ring->dev->dev_private;
	unsigned long flags;
	unsigned long flags;
	bool was_empty;
	int num_elements = 0;


	req = kzalloc(sizeof(*req), GFP_KERNEL);
	req = kzalloc(sizeof(*req), GFP_KERNEL);
	if (req == NULL)
	if (req == NULL)
@@ -410,9 +410,27 @@ static int execlists_context_queue(struct intel_engine_cs *ring,


	spin_lock_irqsave(&ring->execlist_lock, flags);
	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);
	list_add_tail(&req->execlist_link, &ring->execlist_queue);
	if (was_empty)
	if (num_elements == 0)
		execlists_context_unqueue(ring);
		execlists_context_unqueue(ring);


	spin_unlock_irqrestore(&ring->execlist_lock, flags);
	spin_unlock_irqrestore(&ring->execlist_lock, flags);