The driver automatically allocates a Y-plane (4A/5A) when userspace
configures an NV12 surface. The allocation loop doesn't check if a
candidate plane is already configured by userspace in the same atomic
commit, causing conflict as observed in this i915_display_info:

  [PLANE:124:plane 4A]: type=OVL
      uapi: [FB:566] AB24 little-endian (0x34324241),0x0,1920x1280, 
visible=visible
      planar: Linked to [PLANE:34:plane 1A] as a Y plane
      hw: [FB:564] NV12 little-endian (0x3231564e),0x0,1920x1080, visible=yes

Plane 4A's uapi state shows userspace's AB24 framebuffer, but the hw
state shows it was reprogrammed with the NV12 Y-plane.

Example triggered by experiment with IGT test to commit NV12 + multiple
AB24 planes:

  === Testing with NV12 primary + 3 ABGR8888 overlays ===
    Plane 0 (Primary): NV12 1920x1080 at (0, 0)
    Plane 1 (Overlay 0): ABGR8888 1920x1280 (fullscreen) at (0, 0)
    Plane 2 (Overlay 1): ABGR8888 1920x1280 (fullscreen) at (0, 0)
    Plane 3 (Overlay 2): ABGR8888 1920x1280 (fullscreen) at (0, 0)
    TEST_ONLY passed, committing...
    Atomic commit SUCCEEDED

The bug triggers a kernel WARNING in unlink_nv12_plane():
  WARNING: drivers/gpu/drm/i915/display/intel_plane.c:1521
  drm_WARN_ON(plane_state->uapi.visible)

Fix by checking uapi.fb before allocating a Y-plane. If set, userspace
configured this plane, so skip to the next candidate. This enables
graceful fallback (4A busy -> try 5A) rather than the current
behavior that steals planes from userspace.

IGT test and kernel fix generated with assistance from Claude Sonnet 4.5
through an iterative process. The following is a summary of the prompts
used:

IGT test generation prompt:
Need an IGT test to:
1. Reproduce the NV12 + multiple AB24 plane allocation conflict
2. Work across different GPU vendors (not Intel-specific)
3. Discover hardware limits through iteration (not hardcoded)
4. Test atomic commit behavior with mixed formats
5. Validate driver properly rejects invalid configurations
6. Help debug plane allocation issues (interactive inspection)

Kernel fix debug process:
1. Explained NV12 UV->Y plane linking mechanism (link_nv12_planes)
2. Traced Y-plane selection algorithm and hardware constraints
3. Analyzed i915_display_info output showing uapi vs hw state mismatch
4. Triggered kernel WARNING in unlink_nv12_plane() confirming the bug
5. Traced kernel logs through atomic commit sequence
6. Identified root cause: Y-plane allocation checks uapi.crtc, but that's
   set later during plane validation. uapi.fb is set earlier during state
   setup, making it the correct indicator of userspace configuration
7. Evaluated uapi.fb vs uapi.visible for detection timing
8. Initially suggested rejecting commit with -EINVAL, but decided graceful
   fallback with continue is better - allows trying alternate Y-planes
   (4A busy -> 5A) instead of failing entire atomic commit
9. Validated fix prevents plane stealing while allowing alternate Y-plane

Cc: Uma Shankar <[email protected]>
Cc: Jani Nikula <[email protected]>
Cc: Ville Syrjala <[email protected]>
Signed-off-by: Khaled Almahallawy <[email protected]>
---
 drivers/gpu/drm/i915/display/intel_plane.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_plane.c 
b/drivers/gpu/drm/i915/display/intel_plane.c
index 3dc2ed52147f..57d1a9cd226e 100644
--- a/drivers/gpu/drm/i915/display/intel_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_plane.c
@@ -1578,6 +1578,10 @@ static int icl_check_nv12_planes(struct 
intel_atomic_state *state,
                        if (IS_ERR(y_plane_state))
                                return PTR_ERR(y_plane_state);
 
+                       /* Reject if this Y-plane is being configured by 
userspace */
+                       if (y_plane_state->uapi.fb)
+                               continue;
+
                        break;
                }
 
-- 
2.43.0

Reply via email to