Chris Wilson [Mon, 7 Nov 2016 11:01:28 +0000 (11:01 +0000)]
drm/i915: Limit Valleyview and earlier to only using mappable scanout
Valleyview appears to be limited to only scanning out from the first 512MiB
of the Global GTT. Lets presume that this behaviour was inherited from the
display block copied from g4x (not Ironlake) and all earlier generations
are similarly affected, though testing suggests different symptoms. For
simplicity, impose that these platforms must scanout from the mappable
region. (For extra simplicity, use HAS_GMCH_DISPLAY even though this
catches Cherryview which does not appear to be limited to the low
aperture for its scanout.)
v2: Use HAS_GMCH_DISPLAY() to more clearly convey my intent about
limiting this workaround to the old style of display engine.
v3: Update changelog to reflect testing by Ville Syrjälä
v4: Include the changes to the comments as well
Reported-by: Luis Botello <luis.botello.ortega@intel.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=98036 Fixes: 2efb813d5388 ("drm/i915: Fallback to using unmappable memory for scanout") Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Akash Goel <akash.goel@intel.com> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: <drm-intel-fixes@lists.freedesktop.org> # v4.9-rc1+ Link: http://patchwork.freedesktop.org/patch/msgid/20161107110128.28762-1-chris@chris-wilson.co.uk Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com
Chris Wilson [Mon, 7 Nov 2016 10:54:43 +0000 (10:54 +0000)]
drm/i915: Round tile chunks up for constructing partial VMAs
When we split a large object up into chunks for GTT faulting (because we
can't fit the whole object into the aperture) we have to align our cuts
with the fence registers. Each partial VMA must cover a complete set of
tile rows or the offset into each partial VMA is not aligned with the
whole image. Currently we enforce a minimum size on each partial VMA,
but this minimum size itself was not aligned to the tile row causing
distortion.
Reported-by: Andreas Reis <andreas.reis@gmail.com> Reported-by: Chris Clayton <chris2553@googlemail.com> Reported-by: Norbert Preining <preining@logic.at> Tested-by: Norbert Preining <preining@logic.at> Tested-by: Chris Clayton <chris2553@googlemail.com> Fixes: 03af84fe7f48 ("drm/i915: Choose partial chunksize based on tile row size") Fixes: a61007a83a46 ("drm/i915: Fix partial GGTT faulting") # enabling patch
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=98402
Testcase: igt/gem_mmap_gtt/medium-copy-odd Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Cc: Jani Nikula <jani.nikula@linux.intel.com> Cc: <drm-intel-fixes@lists.freedesktop.org> # v4.9-rc1+ Link: http://patchwork.freedesktop.org/patch/msgid/20161107105443.27855-1-chris@chris-wilson.co.uk Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Chris Wilson [Fri, 4 Nov 2016 16:12:41 +0000 (16:12 +0000)]
drm/i915: Remove the vma from the object list upon close
Currently, the vma is being unlink from the object lookup on destroy.
However, we are meant to be decoupling it upon close so that the user
cannot access the closed vma whilst it remains active on the GPU.
Lyude [Wed, 2 Nov 2016 01:06:30 +0000 (21:06 -0400)]
drm/i915: Reinit polling before hpd when resuming
Now that we don't run the connector reprobing from i915_drm_resume(), we
need to make it so we don't have to wait for reprobing to finish so that
we actually speed things up. In order to do this, we need to make sure
that i915_drm_resume() doesn't get blocked by i915_hpd_poll_init_work()
while trying to acquire the mode_config lock that
drm_kms_helper_poll_enable() needs to acquire.
The easiest way to do this is to just enable polling before hpd. This
shouldn't break anything since at that point we have everything else we
need for polling enabled.
As well, this should result in a rather significant improvement in how
quickly we can resume the system.
Signed-off-by: Lyude <lyude@redhat.com> Tested-by: David Weinehall <david.weinehall@linux.intel.com> Reviewed-by: David Weinehall <david.weinehall@linux.intel.com>
Testcase: analyze_suspend.py -config config/suspend-callgraph.cfg -filter i915
Lyude [Tue, 1 Nov 2016 21:31:32 +0000 (17:31 -0400)]
drm/i915: Remove redundant reprobe in i915_drm_resume
Weine's investigation on benchmarking the suspend/resume process pointed
out a lot of the time in suspend/resume is being spent reprobing. While
the reprobing process is a lengthy one for good reason, we don't need to
hold up the entire suspend/resume process while we wait for it to
finish. Luckily as it turns out, we already trigger a full connector
reprobe in i915_hpd_poll_init_work(), so we can just ditch reprobing in
i915_drm_resume() entirely.
This won't lead to less time spent resuming just yet since now the
bottleneck will be waiting for the mode_config lock in
drm_kms_helper_poll_enable(), since that will be held as long as
i915_hpd_poll_init_work() is reprobing all of the connectors. But we'll
address that in the next patch.
Signed-off-by: Lyude <lyude@redhat.com> Tested-by: David Weinehall <david.weinehall@linux.intel.com> Reviewed-by: David Weinehall <david.weinehall@linux.intel.com>
Testcase: analyze_suspend.py -config config/suspend-callgraph.cfg -filter i915
drm/i915/dp: Extend BDW DP audio workaround to GEN9 platforms
According to BSpec, cdclk for BDW has to be not less than 432 MHz with DP
audio enabled, port width x4, and link rate HBR2 (5.4 GHz). With cdclk less
than 432 MHz, enabling audio leads to pipe FIFO underruns and displays
cycling on/off.
Let's apply this work around to GEN9 platforms too, as it fixes the same
issue.
v2: Move drm_device to drm_i915_private conversion
According to BSpec, cdclk for BDW has to be not less than 432 MHz with DP
audio enabled, port width x4, and link rate HBR2 (5.4 GHz). With cdclk less
than 432 MHz, enabling audio leads to pipe FIFO underruns and displays
cycling on/off.
From BSpec:
"Display» BDW-SKL» dpr» [Register] DP_TP_CTL [BDW+,EXCLUDE(CHV)]
Workaround : Do not use DisplayPort with CDCLK less than 432 MHz, audio
enabled, port width x4, and link rate HBR2 (5.4 GHz), or else there may
be audio corruption or screen corruption."
Since, some DP configurations (e.g., MST) use port width x4 and HBR2
link rate, let's increase the cdclk to >= 432 MHz to enable audio for those
cases.
v4: Changed commit message
v3: Combine BDW pixel rate adjustments into a function (Jani)
v2: Restrict fix to BDW
Retain the set cdclk across modesets (Ville) Cc: stable@vger.kernel.org Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Jani Nikula <jani.nikula@intel.com> Signed-off-by: Jani Nikula <jani.nikula@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1478026080-2925-1-git-send-email-dhinakaran.pandiyan@intel.com
Chris Wilson [Fri, 4 Nov 2016 10:30:01 +0000 (10:30 +0000)]
drm/i915: Fix pages pin counting around swizzle quirk
commit bc0629a76726 ("drm/i915: Track pages pinned due to swizzling
quirk") fixed one problem, but revealed a whole lot more. The root cause
of the pin count mismatch for the swizzle quirk (for L-shaped memory on
gen3/4) was that we were incrementing the pages_pin_count upon getting
the backing pages but then overwriting the pages_pin_count to set it to
1 afterwards. With a little bit of adjustment to satisfy the GEM_BUG_ON
sanitychecks, the fix is to replace the explicit atomic_set with an
atomic_inc.
v2: Consistently use atomics (not mix atomics and helpers) within the
lowlevel get_pages routines. This makes the atomic operations much
clearer.
Chris Wilson [Thu, 3 Nov 2016 20:08:52 +0000 (20:08 +0000)]
drm/i915: Fix test on inputs for vma_compare()
When supplying a view to vma_compare() it is required that the supplied
i915_address_space is the global GTT. I tested the VMA instead (which is
the current position in the rbtree and maybe from any address space).
Reported-by: Matthew Auld <matthew.auld@intel.com> Tested-by: Matthew Auld <matthew.auld@intel.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=98579 Fixes: db6c2b4151f2 ("drm/i915: Store the vma in an rbtree...") Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Cc: Matthew Auld <matthew.auld@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20161103200852.23431-1-chris@chris-wilson.co.uk Reviewed-by: Matthew Auld <matthew.auld@intel.com>
Chris Wilson [Wed, 2 Nov 2016 17:50:47 +0000 (17:50 +0000)]
drm/i915/guc: Cache the client mapping
Use i915_gem_object_pin_map() for the guc client's lifetime to replace
the peristent kmap + frequent kmap_atomic with a permanent vmapping.
This avoids taking the obj->mm.lock mutex whilst inside irq context
later.
Mika Kuoppala [Tue, 1 Nov 2016 16:43:03 +0000 (18:43 +0200)]
drm/i915: Move hangcheck code out from i915_irq.c
Create new file for hangcheck specific code, intel_hangcheck.c,
and move all related code in it.
v2: s/intel_engine_hangcheck/intel_engine (Chris)
No functional changes.
Cc: Chris Wilson <chris@chris-wilson.co.uk> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1478018583-5816-1-git-send-email-mika.kuoppala@intel.com
Mika Kuoppala [Tue, 1 Nov 2016 13:27:36 +0000 (15:27 +0200)]
drm/i915/gtt: Fix pte clear range
Comparing pte index to a number of entries is wrong
when clearing a range of pte entries. Use end marker
of 'one past' to correctly point adequate number of
ptes to the scratch page.
v2: assert early instead of warning late (Chris)
v3: removed consts (Joonas)
Fixes: d209b9c3cd28 ("drm/i915/gtt: Split gen8_ppgtt_clear_pte_range")
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=98282 Cc: Chris Wilson <chris@chris-wilson.co.uk> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Cc: Michel Thierry <michel.thierry@intel.com> Cc: Michał Winiarski <michal.winiarski@intel.com> Reported-by: Mike Lothian <mike@fireburn.co.uk> Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Tested-by: Mike Lothian <mike@fireburn.co.uk> Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
Tvrtko Ursulin [Tue, 1 Nov 2016 14:44:10 +0000 (14:44 +0000)]
drm/i915: Allow shrinking of userptr objects once again
Commit 1bec9b0bda3d ("drm/i915/shrinker: Only shmemfs objects
are backed by swap") stopped considering the userptr objects
in shrinker callbacks.
Restore that so idle userptr objects can be discarded in order
to free up memory.
One change further to what was introduced in 1bec9b0bda3d is
to start considering userptr objects in oom but that should
also be a correct thing to do.
Ville Syrjälä [Mon, 31 Oct 2016 20:37:05 +0000 (22:37 +0200)]
drm/i915: Store struct intel_crtc * in {pipe,plane}_to_crtc_mapping[]
A lot of users of the {pipe,plane}_to_crtc_mapping[] will end up
casting the result to intel_crtc, so let's just store the intel_crtc
pointer in the first place.
Ville Syrjälä [Mon, 31 Oct 2016 20:37:01 +0000 (22:37 +0200)]
drm/i915: Pass dev_priv to skl_init_scalers()
Unify our approach to things by passing around dev_priv instead of dev.
While at it let's do some house cleaning: s/intel_foo/foo/ and move
things into tighter scope.
Chris Wilson [Sun, 30 Oct 2016 13:28:20 +0000 (13:28 +0000)]
drm/i915: Export a function to flush the context upon pinning
For legacy contexts we employ an optimisation to only flush the context
when binding into the global GTT. This avoids stalling on the GPU when
reloading an active context. Wrap this detail up into a helper and
export it for a potential third user. (Longer term, context pinning
needs to be reworked as the current handling of switch context pins too
late and so risks eviction and corrupting the request. Plans, plans,
plans.)
v2: Expand the comment explaining the optimisation for avoiding the
stall on active contexts.
drm/i915/gen9+: Use the watermarks from crtc_state for everything, v2.
There's no need to keep a duplicate skl_pipe_wm around any more,
everything can be discovered from crtc_state, which we pass around
correctly now even in case of plane disable.
The copy in intel_crtc->wm.skl.active is equal to
crtc_state->wm.skl.optimal after the atomic commit completes.
It's useful for two-step watermark programming, but not required for
gen9+ which does it in a single step. We can pull the old allocation
from old_crtc_state.
Move calculating minimum allocations to a helper, which cleans up the
code some more. The cursor is still allocated in advance because it
doesn't count towards data rate and should always be reserved.
changes since v1:
- Change comment to have a extra opening line. (Matt)
- Rebase to remove unused plane->pipe == pipe, handled by the iterator
now. (Paulo)
drm/i915/skl+: Remove data_rate from watermark struct, v2.
It's only used in one function, and can be calculated without caching it
in the global struct by using drm_atomic_crtc_state_for_each_plane_state.
There are loops over all planes, including planes that don't exist.
This is harmless, because data_rate will always be 0 for them and we
never program them when updating watermarks.
Changes since v1:
- Rename rate back to data_rate, and change array name to
plane_data_rate. (Matt)
- Remove whitespace. (Paulo)
drm/i915/gen9+: Use for_each_intel_plane_on_crtc in skl_print_wm_changes, v2.
Using for_each_intel_plane_on_crtc will allow us to find all allocations
that may have changed, not just the one added by the atomic state.
This will print changes to plane allocations for crtc's when some
planes are not added to the atomic state.
Changes since v1:
- Rephrase commit message. (Ville)
- Use plane->base.id and plane->name to kill off cursor special
case. (Ville)
- Add intel_crtc to prevent a line wrap. (Paulo)
- Line wrap debug messages.
drm/i915/gen9+: Use cstate plane mask instead of crtc->state.
I'm planning on getting rid of all obj->state dereferences,
and replace thhem with accessor functions.
Remove this one early, they're equivalent because removed
planes are already part of the state, else they could not
have been removed.
drm/i915/skl+: Prepare for removing data rate from skl watermark state, v2.
Caching is not required, drm_atomic_crtc_state_for_each_plane_state can
be used to inspect the states of all planes assigned to the CRTC even
if they are not part of _state, so we can just recalculate every time.
Changes since v1:
- Remove plane->pipe checks, they're implied by the macros.
- Split unrelated changes to a separate commit.
Chris Wilson [Tue, 1 Nov 2016 12:11:34 +0000 (12:11 +0000)]
drm/i915: Improve lockdep tracking for obj->mm.lock
The shrinker may appear to recurse into obj->mm.lock as the shrinker may
be called from a direct reclaim path whilst handling get_pages. We
filter out recursing on the same obj->mm.lock by inspecting
obj->mm.pages, but we do want to take the lock on a second object in
order to reap their pages. lockdep spots the recursion on the same
lockclass and needs annotation to avoid a false positive. To keep the
two paths distinct, create an enum to indicate which subclass of
obj->mm.lock we are using. This removes the false positive and avoids
masking real bugs.
Chris Wilson [Tue, 1 Nov 2016 11:54:00 +0000 (11:54 +0000)]
drm/i915: Store the vma in an rbtree under the object
With full-ppgtt one of the main bottlenecks is the lookup of the VMA
underneath the object. For execbuf there is merit in having a very fast
direct lookup of ctx:handle to the vma using a hashtree, but that still
leaves a large number of other lookups. One way to speed up the lookup
would be to use a rhashtable, but that requires extra allocations and
may exhibit poor worse case behaviour. An alternative is to use an
embedded rbtree, i.e. no extra allocations and deterministic behaviour,
but at the slight cost of O(lgN) lookups (instead of O(1) for
rhashtable). The major of such tree will be very shallow and so not much
slower, and still scales much, much better than the current unsorted
list.
v2: Bump vma_compare() to return a long, as we return the result of
comparing two pointers.
Chris Wilson [Tue, 1 Nov 2016 10:03:17 +0000 (10:03 +0000)]
drm/i915: Track pages pinned due to swizzling quirk
If we have a tiled object and an unknown CPU swizzle pattern, we pin the
pages to prevent the object from being swapped out (and us corrupting
the contents as we do not know the access pattern and so cannot convert
it to linear and back to tiled on reuse). This requires us to remember
to drop the extra pinning when freeing the object, or else we trigger
warnings about the pin leak. In commit fbbd37b36fa5 ("drm/i915: Move
object release to a freelist + worker"), the object free path was
deferred to a worker, but the unpinning of the quirk, along with marking
the object as reclaimable, was left on the immediate path (so that if
required we could reclaim the pages under memory pressure as early as
possible). However, this split introduced a bug where the pages were no
longer being unpinned if they were marked as unneeded.
Moving to a separate flag for tracking the quirked pin is overkill for
the bug (since we only have to interchange the two tests in
i915_gem_free_object) but it does reduce a complicated test on all
objects and provide a sanitycheck for uncommon code paths.
Chris Wilson [Tue, 1 Nov 2016 10:03:16 +0000 (10:03 +0000)]
drm/i915: Avoid accessing request->timeline outside of its lifetime
Whilst waiting on a request, we may do so without holding any locks or
any guards beyond a reference to the request. In order to avoid taking
locks within request deallocation, we drop references to its timeline
(via the context and ppgtt) upon retirement. We should avoid chasing
such pointers outside of their control, in particular we inspect the
request->timeline to see if we may restore the RPS waitboost for a
client. If we instead look at the engine->timeline, we will have similar
behaviour on both full-ppgtt and !full-ppgtt systems and reduce the
amount of reward we give towards stalling clients (i.e. only if the
client stalls and the GPU is uncontended does it reclaim its boost).
This restores behaviour back to pre-timelines, whilst fixing:
Chris Wilson [Tue, 1 Nov 2016 08:48:43 +0000 (08:48 +0000)]
drm/i915: Move the recently scanned objects to the tail after shrinking
During shrinking, we walk over the list of objects searching for
victims. Any that are not removed are put back into the global list.
Currently, they are put back in order (at the front) which means they
will be first to be scanned again. If we instead move them to the rear
of the list, we will scan new potential victims on the next pass and
waste less time rescanning unshrinkable objects. Normally the lists are
kept in rough order to shrinking (with object least frequently used at
the start), by moving just scanned objects to the rear we are
acknowledging that they are still in use.
Chris Wilson [Tue, 1 Nov 2016 08:48:42 +0000 (08:48 +0000)]
drm/i915: Discard objects from mm global_list after being shrunk
In the shrinker, we can safely remove an empty object (obj->mm.pages ==
NULL) after having discarded the pages because we are holding the
struct_mutex.
Chris Wilson [Tue, 1 Nov 2016 08:48:41 +0000 (08:48 +0000)]
drm/i915: Use the full hammer when shutting down the rcu tasks
To flush all call_rcu() tasks (here from i915_gem_free_object()) we need
to call rcu_barrier() (not synchronize_rcu()). If we don't then we may
still have objects being freed as we continue to teardown the driver -
in particular, the recently released rings may race with the memory
manager shutdown resulting in sporadic:
In particular note that the node was being poisoned as we inspected the
list, a clear indication that the object is being freed as we make the
assertion.
v2: Don't loop, just assert that we do all the work required as that
will be better at detecting further errors.
Fixes: fbbd37b36fa5 ("drm/i915: Move object release to a freelist + worker") Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20161101084843.3961-1-chris@chris-wilson.co.uk
Ville Syrjälä [Tue, 25 Oct 2016 15:58:03 +0000 (18:58 +0300)]
drm/i915: Reorganize sprite init
Kill the switch statement from the sprite init code and replace with a
more straightforward if ladder. Now each significant evolution of the
sprite hardware is in its own neat box.
Ville Syrjälä [Tue, 25 Oct 2016 15:58:02 +0000 (18:58 +0300)]
drm/i915: Bail if plane/crtc init fails
Due to the plane->index not getting readjusted in drm_plane_cleanup(),
we can't continue initialization of some plane/crtc init fails.
Well, we sort of could I suppose if we left all initialized planes on
the list, but that would expose those planes to userspace as well.
But for crtcs the situation is even worse since we assume that
pipe==crtc index occasionally, so we can't really deal with a partially
initialize set of crtcs.
So seems safest to just abort the entire thing if anything goes wrong.
All the failure paths here are kmalloc()s anyway, so it seems unlikely
we'd get very far if these start failing.
Ville Syrjälä [Tue, 25 Oct 2016 15:58:01 +0000 (18:58 +0300)]
drm/i915: Initialize planes in a reasonable order
The zpos magic sorting uses the object ID to solve conflicting zpos
values. Let's initialize our planes in an order that makes the object
IDs agree with the normal primary->sprites->cursor z order.
Ville Syrjälä [Tue, 25 Oct 2016 15:58:00 +0000 (18:58 +0300)]
drm/i915: Don't try to initialize sprite planes on pre-ilk
We don't currently implement support for sprite planes on pre-ilk
platforms, so let's leave num_sprites at 0 so that we don't get
spurious errors during driver init.
Chris Wilson [Mon, 31 Oct 2016 12:40:48 +0000 (12:40 +0000)]
drm/i915: Mark up obj->mm.lock for shrinker
As we may allocate from within the obj->mm.lock we may enter the
shrinker for direct reclaim. Operating on the current object is
prevented by checking for obj->mm.pages (which is only set as the last
operation in the allocation path). However, we need to identify the
single recursion of accessing another object's obj->mm.lock as the two
locks have identical class and so appear to be the same to lockdep,
convincing it that a deadlock is possible. Use mutex_lock_nested() to
remove the false positive.
Jani Nikula [Wed, 26 Oct 2016 16:11:32 +0000 (19:11 +0300)]
MAINTAINERS: drop dri-devel list for i915
In practice, none of the i915 developers Cc dri-devel for strictly i915
specific patches. Make MAINTAINERS reflect reality, and reduce random
i915 specific noise on dri-devel.
Also, we have a fairly large crowd reading and responding on intel-gfx,
and we're pretty good at involving dri-devel when that is appropriate.
Lyude [Wed, 26 Oct 2016 16:36:09 +0000 (12:36 -0400)]
drm/i915/vlv: Prevent enabling hpd polling in late suspend
One of the CI machines began to run into issues with the hpd poller
suddenly waking up in the midst of the late suspend phase. It looks like
this is getting caused by the fact we now deinitialize power wells in
late suspend, which means that intel_hpd_poll_init() gets called in late
suspend causing polling to get re-enabled. So, when deinitializing power
wells on valleyview we now refrain from enabling polling in the midst of
suspend.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=98040 Fixes: 19625e85c6ec ("drm/i915: Enable polling when we don't have hpd") Signed-off-by: Lyude <lyude@redhat.com> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Jani Saarinen <jani.saarinen@intel.com> Cc: Petry Latvala <petri.latvala@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Jani Nikula <jani.nikula@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1477499769-1966-1-git-send-email-lyude@redhat.com
Chris Wilson [Fri, 28 Oct 2016 12:58:58 +0000 (13:58 +0100)]
drm/i915: Enable multiple timelines
With the infrastructure converted over to tracking multiple timelines in
the GEM API whilst preserving the efficiency of using a single execution
timeline internally, we can now assign a separate timeline to every
context with full-ppgtt.
v2: Add a comment to indicate the xfer between timelines upon submission.
Chris Wilson [Fri, 28 Oct 2016 12:58:57 +0000 (13:58 +0100)]
drm/i915: Defer setting of global seqno on request to submission
Defer the assignment of the global seqno on a request to its submission.
In the next patch, we will only allocate the global seqno at that time,
here we are just enabling the wait-for-submission before wait-for-seqno
paths.
Chris Wilson [Fri, 28 Oct 2016 12:58:56 +0000 (13:58 +0100)]
drm/i915: Reserve space in the global seqno during request allocation
A restriction on our global seqno is that they cannot wrap, and that we
cannot use the value 0. This allows us to detect when a request has not
yet been submitted, its global seqno is still 0, and ensures that
hardware semaphores are monotonic as required by older hardware. To
meet these restrictions when we defer the assignment of the global
seqno, we must check that we have an available slot in the global seqno
space during request construction. If that test fails, we wait for all
requests to be completed and reset the hardware back to 0.
Chris Wilson [Fri, 28 Oct 2016 12:58:55 +0000 (13:58 +0100)]
drm/i915: Convert breadcrumbs spinlock to be irqsafe
The breadcrumbs are about to be used from within IRQ context sections
(e.g. nouveau signals a fence from an interrupt handler causing us to
submit a new request) and/or from bottom-half tasklets (i.e.
intel_lrc_irq_handler), therefore we need to employ the irqsafe spinlock
variants.
For example, deferring the request submission to the
intel_lrc_irq_handler generates this trace:
(This is split out of the defer global seqno allocation patch due to
realisation that we need a more complete conversion if we want to defer
request submission even further.)
v2: lockdep was warning about mixed SOFTIRQ contexts not HARDIRQ
contexts so we only need to use spin_lock_bh and not disable interrupts.
v3: We need full irq protection as we may be called from a third party
interrupt handler (via fences).
Chris Wilson [Fri, 28 Oct 2016 12:58:54 +0000 (13:58 +0100)]
drm/i915: Create a unique name for the context
This will be used for communicating issues with this context to
userspace, so we want to identify the parent process and the individual
context. Note that the name isn't quite unique, it makes the presumption
of there only being a single device fd per process.
Chris Wilson [Fri, 28 Oct 2016 12:58:53 +0000 (13:58 +0100)]
drm/i915: Move the global sync optimisation to the timeline
Currently we try to reduce the number of synchronisations (now the
number of requests we need to wait upon) by noting that if we have
earlier waited upon a request, all subsequent requests in the timeline
will be after the wait. This only applies to requests in this timeline,
as other timelines will not be ordered by that waiter.
Chris Wilson [Fri, 28 Oct 2016 12:58:52 +0000 (13:58 +0100)]
drm/i915: Defer breadcrumb emission
Move the actual emission of the breadcrumb for closing the request from
i915_add_request() to the submit callback. (It can be moved later when
required.) This allows us to defer the allocation of the global_seqno
from request construction to actual submission, allowing us to emit the
requests out of order (wrt to the order of their construction, they
still will only be executed one all of their dependencies are resolved
including that all earlier requests on their timeline have been
submitted.) We have to specialise how we then emit the request in order
to write into the preallocated space, rather than at the tail of the
ringbuffer (which will have been advanced by the addition of new
requests).
Chris Wilson [Fri, 28 Oct 2016 12:58:51 +0000 (13:58 +0100)]
drm/i915: Record space required for breadcrumb emission
In the next patch, we will use deferred breadcrumb emission. That requires
reserving sufficient space in the ringbuffer to emit the breadcrumb, which
first requires us to know how large the breadcrumb is.
Chris Wilson [Fri, 28 Oct 2016 12:58:50 +0000 (13:58 +0100)]
drm/i915: Rename ->emit_request to ->emit_breadcrumb
Now that the emission of the request tail and its submission to hardware
are two separate steps, engine->emit_request() is confusing.
engine->emit_request() is called to emit the breadcrumb commands for the
request into the ring, name it such (engine->emit_breadcrumb).
Chris Wilson [Fri, 28 Oct 2016 12:58:49 +0000 (13:58 +0100)]
drm/i915: Introduce a global_seqno for each request
Though we will have multiple timelines, we still have a single timeline
of execution. This we can use to provide an execution and retirement order
of requests. This keeps tracking execution of requests simple, and vital
for preserving a single waiter (i.e. so that we can order the waiters so
that only the earliest to wakeup need be woken). To accomplish this we
distinguish the seqno used to order requests per-context (external) and
that used internally for execution.
Chris Wilson [Fri, 28 Oct 2016 12:58:48 +0000 (13:58 +0100)]
drm/i915: Wait first for submission, before waiting for request completion
In future patches, we will no longer be able to wait on a static global
seqno and instead have to break our wait up into phases. First we wait
for the global seqno assignment (upon submission to hardware), and once
submitted we wait for the hardware to complete.
Chris Wilson [Fri, 28 Oct 2016 12:58:47 +0000 (13:58 +0100)]
drm/i915: Queue the idling context switch after all other timelines
Before suspend, we wait for the switch to the kernel context. In order
for all the other context images to be complete upon suspend, that
switch must be the last operation by the GPU (i.e. this idling request
must not overtake any pending requests). To make this request execute last,
we make it depend on every other inflight request.
Chris Wilson [Fri, 28 Oct 2016 12:58:46 +0000 (13:58 +0100)]
drm/i915: Combine seqno + tracking into a global timeline struct
Our timelines are more than just a seqno. They also provide an ordered
list of requests to be executed. Due to the restriction of handling
individual address spaces, we are limited to a timeline per address
space but we use a fence context per engine within.
Our first step to introducing independent timelines per context (i.e. to
allow each context to have a queue of requests to execute that have a
defined set of dependencies on other requests) is to provide a timeline
abstraction for the global execution queue.
Chris Wilson [Fri, 28 Oct 2016 12:58:45 +0000 (13:58 +0100)]
drm/i915: Restore nonblocking awaits for modesetting
After combining the dma-buf reservation object and the GEM reservation
object, we lost the ability to do a nonblocking wait on the i915 request
(as we blocked upon the reservation object during prepare_fb). We can
instead convert the reservation object into a fence upon which we can
asynchronously wait (including a forced timeout in case the DMA fence is
never signaled).
Chris Wilson [Fri, 28 Oct 2016 12:58:44 +0000 (13:58 +0100)]
drm/i915: Move GEM activity tracking into a common struct reservation_object
In preparation to support many distinct timelines, we need to expand the
activity tracking on the GEM object to handle more than just a request
per engine. We already use the struct reservation_object on the dma-buf
to handle many fence contexts, so integrating that into the GEM object
itself is the preferred solution. (For example, we can now share the same
reservation_object between every consumer/producer using this buffer and
skip the manual import/export via dma-buf.)
v2: Reimplement busy-ioctl (by walking the reservation object), postpone
the ABI change for another day. Similarly use the reservation object to
find the last_write request (if active and from i915) for choosing
display CS flips.
Caveats:
* busy-ioctl: busy-ioctl only reports on the native fences, it will not
warn of stalls (in set-domain-ioctl, pread/pwrite etc) if the object is
being rendered to by external fences. It also will not report the same
busy state as wait-ioctl (or polling on the dma-buf) in the same
circumstances. On the plus side, it does retain reporting of which
*i915* engines are engaged with this object.
* non-blocking atomic modesets take a step backwards as the wait for
render completion blocks the ioctl. This is fixed in a subsequent
patch to use a fence instead for awaiting on the rendering, see
"drm/i915: Restore nonblocking awaits for modesetting"
* dynamic array manipulation for shared-fences in reservation is slower
than the previous lockless static assignment (e.g. gem_exec_lut_handle
runtime on ivb goes from 42s to 66s), mainly due to atomic operations
(maintaining the fence refcounts).
* loss of object-level retirement callbacks, emulated by VMA retirement
tracking.
* minor loss of object-level last activity information from debugfs,
could be replaced with per-vma information if desired
Chris Wilson [Fri, 28 Oct 2016 12:58:43 +0000 (13:58 +0100)]
drm/i915: Use lockless object free
Having moved the locked phase of freeing an object to a separate worker,
we can now declare to the core that we only need the unlocked variant of
driver->gem_free_object, and can use the simple unreference internally.
Chris Wilson [Fri, 28 Oct 2016 12:58:42 +0000 (13:58 +0100)]
drm/i915: Move object release to a freelist + worker
We want to hide the latency of releasing objects and their backing
storage from the submission, so we move the actual free to a worker.
This allows us to switch to struct_mutex freeing of the object in the
next patch.
Furthermore, if we know that the object we are dereferencing remains valid
for the duration of our access, we can forgo the usual synchronisation
barriers and atomic reference counting. To ensure this we defer freeing
an object til after an RCU grace period, such that any lookup of the
object within an RCU read critical section will remain valid until
after we exit that critical section. We also employ this delay for
rate-limiting the serialisation on reallocation - we have to slow down
object creation in order to prevent resource starvation (in particular,
files).
v2: Return early in i915_gem_tiling() ioctl to skip over superfluous
work on error.
Chris Wilson [Fri, 28 Oct 2016 12:58:40 +0000 (13:58 +0100)]
drm/i915: Implement pwrite without struct-mutex
We only need struct_mutex within pwrite for a brief window where we need
to serialise with rendering and control our cache domains. Elsewhere we
can rely on the backing storage being pinned, and forgive userspace any
races against us.
Chris Wilson [Fri, 28 Oct 2016 12:58:39 +0000 (13:58 +0100)]
drm/i915: Implement pread without struct-mutex
We only need struct_mutex within pread for a brief window where we need
to serialise with rendering and control our cache domains. Elsewhere we
can rely on the backing storage being pinned, and forgive userspace any
races against us.
Chris Wilson [Fri, 28 Oct 2016 12:58:37 +0000 (13:58 +0100)]
drm/i915: Move object backing storage manipulation to its own locking
Break the allocation of the backing storage away from struct_mutex into
a per-object lock. This allows parallel page allocation, provided we can
do so outside of struct_mutex (i.e. set-domain-ioctl, pwrite, GTT
fault), i.e. before execbuf! The increased cost of the atomic counters
are hidden behind i915_vma_pin() for the typical case of execbuf, i.e.
as the object is typically bound between execbufs, the page_pin_count is
static. The cost will be felt around set-domain and pwrite, but offset
by the improvement from reduced struct_mutex contention.
Chris Wilson [Fri, 28 Oct 2016 12:58:36 +0000 (13:58 +0100)]
drm/i915: Pass around sg_table to get_pages/put_pages backend
The plan is to move obj->pages out from under the struct_mutex into its
own per-object lock. We need to prune any assumption of the struct_mutex
from the get_pages/put_pages backends, and to make it easier we pass
around the sg_table to operate on rather than indirectly via the obj.
Chris Wilson [Fri, 28 Oct 2016 12:58:35 +0000 (13:58 +0100)]
drm/i915: Refactor object page API
The plan is to make obtaining the backing storage for the object avoid
struct_mutex (i.e. use its own locking). The first step is to update the
API so that normal users only call pin/unpin whilst working on the
backing storage.
Chris Wilson [Fri, 28 Oct 2016 12:58:33 +0000 (13:58 +0100)]
drm/i915: Use a radixtree for random access to the object's backing storage
A while ago we switched from a contiguous array of pages into an sglist,
for that was both more convenient for mapping to hardware and avoided
the requirement for a vmalloc array of pages on every object. However,
certain GEM API calls (like pwrite, pread as well as performing
relocations) do desire access to individual struct pages. A quick hack
was to introduce a cache of the last access such that finding the
following page was quick - this works so long as the caller desired
sequential access. Walking backwards, or multiple callers, still hits a
slow linear search for each page. One solution is to store each
successful lookup in a radix tree.
v2: Rewrite building the radixtree for clarity, hopefully.
v3: Rearrange execbuf to avoid calling i915_gem_object_get_sg() from
within an atomic section and so relax the allocation context to a simple
GFP_KERNEL and mutex.
Chris Wilson [Fri, 28 Oct 2016 12:58:31 +0000 (13:58 +0100)]
drm/i915: Reuse the active golden render state batch
The golden render state is constant, but we recreate the batch setting
it up for every new context. If we keep that batch in a volatile cache
we can safely reuse it whenever we need to initialise a new context. We
mark the pages as purgeable and use the shrinker to recover pages from
the batch whenever we face memory pressues, recreating that batch afresh
on the next new context.
Chris Wilson [Fri, 28 Oct 2016 12:58:30 +0000 (13:58 +0100)]
drm/i915: Introduce an internal allocator for disposable private objects
Quite a few of our objects used for internal hardware programming do not
benefit from being swappable or from being zero initialised. As such
they do not benefit from using a shmemfs backing storage and since they
are internal and never directly exposed to the user, we do not need to
worry about providing a filp. For these we can use an
drm_i915_gem_object wrapper around a sg_table of plain struct page. They
are not swap backed and not automatically pinned. If they are reaped
by the shrinker, the pages are released and the contents discarded. For
the internal use case, this is fine as for example, ringbuffers are
pinned from being written by a request to be read by the hardware. Once
they are idle, they can be discarded entirely. As such they are a good
match for execlist ringbuffers and a small variety of other internal
objects.
In the first iteration, this is limited to the scratch batch buffers we
use (for command parsing and state initialisation).
v2: Allocate physically contiguous pages, where possible.
v3: Reduce maximum order on subsequent requests following an allocation
failure.
v4: Fix up mismatch between swiotlb segment size and page count (it
counts in 2k units, not 4k pages)
Chris Wilson [Fri, 28 Oct 2016 12:58:29 +0000 (13:58 +0100)]
drm/i915: Defer active reference until required
We only need the active reference to keep the object alive after the
handle has been deleted (so as to prevent a synchronous gem_close). Why
then pay the price of a kref on every execbuf when we can insert that
final active ref just in time for the handle deletion?
Chris Wilson [Fri, 28 Oct 2016 12:58:28 +0000 (13:58 +0100)]
drm/i915: Remove unused i915_gem_active_wait() in favour of _unlocked()
Since we only use the more generic unlocked variant, just rename it as
the normal i915_gem_active_wait(). The temporary cost is that we need to
always acquire the reference in a RCU safe manner, but the benefit is
that we will combine the common paths.
Chris Wilson [Fri, 28 Oct 2016 12:58:27 +0000 (13:58 +0100)]
drm/i915: Rearrange i915_wait_request() accounting with callers
Our low-level wait routine has evolved from our generic wait interface
that handled unlocked, RPS boosting, waits with time tracking. If we
push our GEM fence tracking to use reservation_objects (required for
handling multiple timelines), we lose the ability to pass the required
information down to i915_wait_request(). However, if we push the extra
functionality from i915_wait_request() to the individual callsites
(i915_gem_object_wait_rendering and i915_gem_wait_ioctl) that make use
of those extras, we can both simplify our low level wait and prepare for
extending the GEM interface for use of reservation_objects.
Chris Wilson [Fri, 28 Oct 2016 12:58:26 +0000 (13:58 +0100)]
drm/i915: Remove superfluous wait_for_error() from throttle-ioctl
The throttle-ioctl never touches the struct_mutex. It does, however, as
part of its ABI report whether the hardware is terminally wedged. For
that purposes, it only has to report the current state and not incur the
cost of checking/waiting every invocation, as we do not have to wait for
a reset before waiting on a request to ensure completion (that is baked
into the wait request implementation).