Skip to content

Commit bb8624d

Browse files
vsyrjalamlankhorst
authored andcommitted
drm/i915: Use vblank worker to unpin old legacy cursor fb safely
The cursor hardware only does sync updates, and thus the hardware will be scanning out from the old fb until the next start of vblank. So in order to make the legacy cursor fastpath actually safe we should not unpin the old fb until we're sure the hardware has ceased accessing it. The simplest approach is to just use a vblank work here to do the delayed unpin. Not 100% sure it's a good idea to put this onto the same high priority vblank worker as eg. our timing critical gamma updates. But let's keep it simple for now, and it we later discover that this is causing problems we can think about adding a lower priority worker for such things. This patch is slightly reworked by Maarten Cc: Maarten Lankhorst <[email protected]> Signed-off-by: Ville Syrjälä <[email protected]> Signed-off-by: Maarten Lankhorst <[email protected]> Reviewed-by: Uma Shankar <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 12f84e8 commit bb8624d

File tree

3 files changed

+30
-2
lines changed

3 files changed

+30
-2
lines changed

drivers/gpu/drm/i915/display/intel_cursor.c

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,17 @@ static bool intel_cursor_format_mod_supported(struct drm_plane *_plane,
761761
return format == DRM_FORMAT_ARGB8888;
762762
}
763763

764+
static void intel_cursor_unpin_work(struct kthread_work *base)
765+
{
766+
struct drm_vblank_work *work = to_drm_vblank_work(base);
767+
struct intel_plane_state *plane_state =
768+
container_of(work, typeof(*plane_state), unpin_work);
769+
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
770+
771+
intel_plane_unpin_fb(plane_state);
772+
intel_plane_destroy_state(&plane->base, &plane_state->uapi);
773+
}
774+
764775
static int
765776
intel_legacy_cursor_update(struct drm_plane *_plane,
766777
struct drm_crtc *_crtc,
@@ -904,14 +915,25 @@ intel_legacy_cursor_update(struct drm_plane *_plane,
904915

905916
intel_psr_unlock(crtc_state);
906917

907-
intel_plane_unpin_fb(old_plane_state);
918+
if (old_plane_state->ggtt_vma != new_plane_state->ggtt_vma) {
919+
drm_vblank_work_init(&old_plane_state->unpin_work, &crtc->base,
920+
intel_cursor_unpin_work);
921+
922+
drm_vblank_work_schedule(&old_plane_state->unpin_work,
923+
drm_crtc_accurate_vblank_count(&crtc->base) + 1,
924+
false);
925+
926+
old_plane_state = NULL;
927+
} else {
928+
intel_plane_unpin_fb(old_plane_state);
929+
}
908930

909931
out_free:
910932
if (new_crtc_state)
911933
intel_crtc_destroy_state(&crtc->base, &new_crtc_state->uapi);
912934
if (ret)
913935
intel_plane_destroy_state(&plane->base, &new_plane_state->uapi);
914-
else
936+
else if (old_plane_state)
915937
intel_plane_destroy_state(&plane->base, &old_plane_state->uapi);
916938
return ret;
917939

drivers/gpu/drm/i915/display/intel_display.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
#include "intel_crtc_state_dump.h"
6969
#include "intel_cursor_regs.h"
7070
#include "intel_cx0_phy.h"
71+
#include "intel_cursor.h"
7172
#include "intel_ddi.h"
7273
#include "intel_de.h"
7374
#include "intel_display_driver.h"
@@ -7020,6 +7021,8 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
70207021
continue;
70217022

70227023
intel_crtc_disable_planes(state, crtc);
7024+
7025+
drm_vblank_work_flush_all(&crtc->base);
70237026
}
70247027

70257028
/* Only disable port sync and MST slaves */

drivers/gpu/drm/i915/display/intel_display_types.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,9 @@ struct intel_plane_state {
744744
struct intel_fb_view view;
745745
u32 phys_dma_addr; /* for cursor_needs_physical */
746746

747+
/* for legacy cursor fb unpin */
748+
struct drm_vblank_work unpin_work;
749+
747750
/* Plane pxp decryption state */
748751
bool decrypt;
749752

0 commit comments

Comments
 (0)