Skip to content

Commit

Permalink
drm/i915/scheduler: Boost priorities for flips
Browse files Browse the repository at this point in the history
Boost the priority of any rendering required to show the next pageflip
as we want to avoid missing the vblank by being delayed by invisible
workload. We prioritise avoiding jank and jitter in the GUI over
starving background tasks.

v2: Descend dma_fence_array when boosting priorities.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20161114204105.29171-10-chris@chris-wilson.co.uk
  • Loading branch information
Chris Wilson committed Nov 14, 2016
1 parent 9f792eb commit 6b5e90f
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 0 deletions.
5 changes: 5 additions & 0 deletions drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -3091,6 +3091,11 @@ int i915_gem_object_wait(struct drm_i915_gem_object *obj,
unsigned int flags,
long timeout,
struct intel_rps_client *rps);
int i915_gem_object_wait_priority(struct drm_i915_gem_object *obj,
unsigned int flags,
int priority);
#define I915_PRIORITY_DISPLAY I915_PRIORITY_MAX

int __must_check
i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj,
bool write);
Expand Down
65 changes: 65 additions & 0 deletions drivers/gpu/drm/i915/i915_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "intel_drv.h"
#include "intel_frontbuffer.h"
#include "intel_mocs.h"
#include <linux/dma-fence-array.h>
#include <linux/reservation.h>
#include <linux/shmem_fs.h>
#include <linux/slab.h>
Expand Down Expand Up @@ -434,6 +435,70 @@ i915_gem_object_wait_reservation(struct reservation_object *resv,
return timeout;
}

static void __fence_set_priority(struct dma_fence *fence, int prio)
{
struct drm_i915_gem_request *rq;
struct intel_engine_cs *engine;

if (!dma_fence_is_i915(fence))
return;

rq = to_request(fence);
engine = rq->engine;
if (!engine->schedule)
return;

engine->schedule(rq, prio);
}

static void fence_set_priority(struct dma_fence *fence, int prio)
{
/* Recurse once into a fence-array */
if (dma_fence_is_array(fence)) {
struct dma_fence_array *array = to_dma_fence_array(fence);
int i;

for (i = 0; i < array->num_fences; i++)
__fence_set_priority(array->fences[i], prio);
} else {
__fence_set_priority(fence, prio);
}
}

int
i915_gem_object_wait_priority(struct drm_i915_gem_object *obj,
unsigned int flags,
int prio)
{
struct dma_fence *excl;

if (flags & I915_WAIT_ALL) {
struct dma_fence **shared;
unsigned int count, i;
int ret;

ret = reservation_object_get_fences_rcu(obj->resv,
&excl, &count, &shared);
if (ret)
return ret;

for (i = 0; i < count; i++) {
fence_set_priority(shared[i], prio);
dma_fence_put(shared[i]);
}

kfree(shared);
} else {
excl = reservation_object_get_excl_rcu(obj->resv);
}

if (excl) {
fence_set_priority(excl, prio);
dma_fence_put(excl);
}
return 0;
}

/**
* Waits for rendering to the object to be completed
* @obj: i915 gem object
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/i915/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -14799,6 +14799,8 @@ intel_prepare_plane_fb(struct drm_plane *plane,
GFP_KERNEL);
if (ret < 0)
return ret;

i915_gem_object_wait_priority(obj, 0, I915_PRIORITY_DISPLAY);
}

if (plane->type == DRM_PLANE_TYPE_CURSOR &&
Expand Down

0 comments on commit 6b5e90f

Please sign in to comment.