]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.2-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 22 Sep 2019 08:18:07 +0000 (10:18 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 22 Sep 2019 08:18:07 +0000 (10:18 +0200)
added patches:
drm-amd-display-allow-cursor-async-updates-for-framebuffer-swaps.patch
drm-amd-display-don-t-replace-the-dc_state-for-fast-updates.patch
drm-amd-display-skip-determining-update-type-for-async-updates.patch

queue-5.2/drm-amd-display-allow-cursor-async-updates-for-framebuffer-swaps.patch [new file with mode: 0644]
queue-5.2/drm-amd-display-don-t-replace-the-dc_state-for-fast-updates.patch [new file with mode: 0644]
queue-5.2/drm-amd-display-skip-determining-update-type-for-async-updates.patch [new file with mode: 0644]
queue-5.2/series

diff --git a/queue-5.2/drm-amd-display-allow-cursor-async-updates-for-framebuffer-swaps.patch b/queue-5.2/drm-amd-display-allow-cursor-async-updates-for-framebuffer-swaps.patch
new file mode 100644 (file)
index 0000000..f8acc6a
--- /dev/null
@@ -0,0 +1,61 @@
+From e16e37efb4c9eb7bcb9dab756c975040c5257e98 Mon Sep 17 00:00:00 2001
+From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Date: Mon, 10 Jun 2019 08:47:57 -0400
+Subject: drm/amd/display: Allow cursor async updates for framebuffer swaps
+
+From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+
+commit e16e37efb4c9eb7bcb9dab756c975040c5257e98 upstream.
+
+[Why]
+We previously allowed framebuffer swaps as async updates for cursor
+planes but had to disable them due to a bug in DRM with async update
+handling and incorrect ref counting. The check to block framebuffer
+swaps has been added to DRM for a while now, so this check is redundant.
+
+The real fix that allows this to properly in DRM has also finally been
+merged and is getting backported into stable branches, so dropping
+this now seems to be the right time to do so.
+
+[How]
+Drop the redundant check for old_fb != new_fb.
+
+With the proper fix in DRM, this should also fix some cursor stuttering
+issues with xf86-video-amdgpu since it double buffers the cursor.
+
+IGT tests that swap framebuffers (-varying-size for example) should
+also pass again.
+
+Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Acked-by: Alex Deucher <alexander.deucher@amd.com>
+Reviewed-by: David Francis <david.francis@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |   10 ----------
+ 1 file changed, 10 deletions(-)
+
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -4209,20 +4209,10 @@ static int dm_plane_atomic_check(struct
+ static int dm_plane_atomic_async_check(struct drm_plane *plane,
+                                      struct drm_plane_state *new_plane_state)
+ {
+-      struct drm_plane_state *old_plane_state =
+-              drm_atomic_get_old_plane_state(new_plane_state->state, plane);
+-
+       /* Only support async updates on cursor planes. */
+       if (plane->type != DRM_PLANE_TYPE_CURSOR)
+               return -EINVAL;
+-      /*
+-       * DRM calls prepare_fb and cleanup_fb on new_plane_state for
+-       * async commits so don't allow fb changes.
+-       */
+-      if (old_plane_state->fb != new_plane_state->fb)
+-              return -EINVAL;
+-
+       return 0;
+ }
diff --git a/queue-5.2/drm-amd-display-don-t-replace-the-dc_state-for-fast-updates.patch b/queue-5.2/drm-amd-display-don-t-replace-the-dc_state-for-fast-updates.patch
new file mode 100644 (file)
index 0000000..75949f5
--- /dev/null
@@ -0,0 +1,103 @@
+From bd200d190f45b62c006d1ad0a63eeffd87db7a47 Mon Sep 17 00:00:00 2001
+From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Date: Wed, 31 Jul 2019 10:33:54 -0400
+Subject: drm/amd/display: Don't replace the dc_state for fast updates
+
+From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+
+commit bd200d190f45b62c006d1ad0a63eeffd87db7a47 upstream.
+
+[Why]
+DRM private objects have no hw_done/flip_done fencing mechanism on their
+own and cannot be used to sequence commits accordingly.
+
+When issuing commits that don't touch the same set of hardware resources
+like page-flips on different CRTCs we can run into the issue below
+because of this:
+
+1. Client requests non-blocking Commit #1, has a new dc_state #1,
+state is swapped, commit tail is deferred to work queue
+
+2. Client requests non-blocking Commit #2, has a new dc_state #2,
+state is swapped, commit tail is deferred to work queue
+
+3. Commit #2 work starts, commit tail finishes,
+atomic state is cleared, dc_state #1 is freed
+
+4. Commit #1 work starts,
+commit tail encounters null pointer deref on dc_state #1
+
+In order to change the DC state as in the private object we need to
+ensure that we wait for all outstanding commits to finish and that
+any other pending commits must wait for the current one to finish as
+well.
+
+We do this for MEDIUM and FULL updates. But not for FAST updates, nor
+would we want to since it would cause stuttering from the delays.
+
+FAST updates that go through dm_determine_update_type_for_commit always
+create a new dc_state and lock the DRM private object if there are
+any changed planes.
+
+We need the old state to validate, but we don't actually need the new
+state here.
+
+[How]
+If the commit isn't a full update then the use after free can be
+resolved by simply discarding the new state entirely and retaining
+the existing one instead.
+
+With this change the sequence above can be reexamined. Commit #2 will
+still free Commit #1's reference, but before this happens we actually
+added an additional reference as part of Commit #2.
+
+If an update comes in during this that needs to change the dc_state
+it will need to wait on Commit #1 and Commit #2 to finish. Then it'll
+swap the state, finish the work in commit tail and drop the last
+reference on Commit #2's dc_state.
+
+Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=204181
+Fixes: 004b3938e637 ("drm/amd/display: Check scaling info when determing update type")
+
+Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Acked-by: Alex Deucher <alexander.deucher@amd.com>
+Reviewed-by: David Francis <david.francis@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |   23 ++++++++++++++++++++++
+ 1 file changed, 23 insertions(+)
+
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -6860,6 +6860,29 @@ static int amdgpu_dm_atomic_check(struct
+                       ret = -EINVAL;
+                       goto fail;
+               }
++      } else {
++              /*
++               * The commit is a fast update. Fast updates shouldn't change
++               * the DC context, affect global validation, and can have their
++               * commit work done in parallel with other commits not touching
++               * the same resource. If we have a new DC context as part of
++               * the DM atomic state from validation we need to free it and
++               * retain the existing one instead.
++               */
++              struct dm_atomic_state *new_dm_state, *old_dm_state;
++
++              new_dm_state = dm_atomic_get_new_state(state);
++              old_dm_state = dm_atomic_get_old_state(state);
++
++              if (new_dm_state && old_dm_state) {
++                      if (new_dm_state->context)
++                              dc_release_state(new_dm_state->context);
++
++                      new_dm_state->context = old_dm_state->context;
++
++                      if (old_dm_state->context)
++                              dc_retain_state(old_dm_state->context);
++              }
+       }
+       /* Must be success */
diff --git a/queue-5.2/drm-amd-display-skip-determining-update-type-for-async-updates.patch b/queue-5.2/drm-amd-display-skip-determining-update-type-for-async-updates.patch
new file mode 100644 (file)
index 0000000..8ab6743
--- /dev/null
@@ -0,0 +1,76 @@
+From 43d10d30df156f7834fa91aecb69614fefc8bb0a Mon Sep 17 00:00:00 2001
+From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Date: Wed, 31 Jul 2019 09:45:16 -0400
+Subject: drm/amd/display: Skip determining update type for async updates
+
+From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+
+commit 43d10d30df156f7834fa91aecb69614fefc8bb0a upstream.
+
+[Why]
+By passing through the dm_determine_update_type_for_commit for atomic
+commits that can be done asynchronously we are incurring a
+performance penalty by locking access to the global private object
+and holding that access until the end of the programming sequence.
+
+This is also allocating a new large dc_state on every access in addition
+to retaining all the references on each stream and plane until the end
+of the programming sequence.
+
+[How]
+Shift the determination for async update before validation. Return early
+if it's going to be an async update.
+
+Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Acked-by: Alex Deucher <alexander.deucher@amd.com>
+Reviewed-by: David Francis <david.francis@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |   27 ++++++++++++++++------
+ 1 file changed, 20 insertions(+), 7 deletions(-)
+
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -6788,6 +6788,26 @@ static int amdgpu_dm_atomic_check(struct
+       if (ret)
+               goto fail;
++      if (state->legacy_cursor_update) {
++              /*
++               * This is a fast cursor update coming from the plane update
++               * helper, check if it can be done asynchronously for better
++               * performance.
++               */
++              state->async_update =
++                      !drm_atomic_helper_async_check(dev, state);
++
++              /*
++               * Skip the remaining global validation if this is an async
++               * update. Cursor updates can be done without affecting
++               * state or bandwidth calcs and this avoids the performance
++               * penalty of locking the private state object and
++               * allocating a new dc_state.
++               */
++              if (state->async_update)
++                      return 0;
++      }
++
+       /* Check scaling and underscan changes*/
+       /* TODO Removed scaling changes validation due to inability to commit
+        * new stream into context w\o causing full reset. Need to
+@@ -6840,13 +6860,6 @@ static int amdgpu_dm_atomic_check(struct
+                       ret = -EINVAL;
+                       goto fail;
+               }
+-      } else if (state->legacy_cursor_update) {
+-              /*
+-               * This is a fast cursor update coming from the plane update
+-               * helper, check if it can be done asynchronously for better
+-               * performance.
+-               */
+-              state->async_update = !drm_atomic_helper_async_check(dev, state);
+       }
+       /* Must be success */
index 5152a31918bb5709648ee0ddd2e0b90e7df0d534..d8fcab34acbb9c6b6e3222f394f8f29d58687197 100644 (file)
@@ -3,3 +3,6 @@ smb3-fix-unmount-hang-in-open_shroot.patch
 phy-qcom-qmp-raise-qcom_qmp_phy_enable-polling-delay.patch
 phy-qcom-qmp-correct-ready-status-again.patch
 net-ibmvnic-free-reset-work-of-removed-device-from-q.patch
+drm-amd-display-allow-cursor-async-updates-for-framebuffer-swaps.patch
+drm-amd-display-skip-determining-update-type-for-async-updates.patch
+drm-amd-display-don-t-replace-the-dc_state-for-fast-updates.patch