From: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
To: Khaled Almahallawy <khaled.almahallawy@intel.com>
Cc: intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org,
Uma Shankar <uma.shankar@intel.com>,
Jani Nikula <jani.nikula@intel.com>
Subject: Re: [RFC PATCH] drm/i915/display: Prevent NV12 Y-plane allocation from stealing userspace planes
Date: Thu, 12 Feb 2026 13:47:41 +0200 [thread overview]
Message-ID: <aY293Q8lcThgXIds@intel.com> (raw)
In-Reply-To: <20260212004852.1920270-1-khaled.almahallawy@intel.com>
On Wed, Feb 11, 2026 at 04:48:52PM -0800, Khaled Almahallawy wrote:
> 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)
>
I think the actual bug is that we unlink the nv12 planes after
plane_atomic_check(). unlink_nv12_plane() will then clobber
some things in the crtc state that was set up by
plane_atomic_check().
So we perhaps want something like this:
diff --git a/drivers/gpu/drm/i915/display/intel_plane.c b/drivers/gpu/drm/i915/display/intel_plane.c
index 3dc2ed52147f..98d0255b8b18 100644
--- a/drivers/gpu/drm/i915/display/intel_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_plane.c
@@ -441,6 +441,8 @@ void intel_plane_set_invisible(struct intel_crtc_state *crtc_state,
{
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
+ unlink_nv12_plane(crtc_state, plane_state);
+
crtc_state->active_planes &= ~BIT(plane->id);
crtc_state->scaled_planes &= ~BIT(plane->id);
crtc_state->nv12_planes &= ~BIT(plane->id);
@@ -1513,6 +1515,9 @@ static void unlink_nv12_plane(struct intel_crtc_state *crtc_state,
struct intel_display *display = to_intel_display(plane_state);
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
+ if (!plane_state->planar_linked_plane)
+ return;
+
plane_state->planar_linked_plane = NULL;
if (!plane_state->is_y_plane)
@@ -1550,8 +1555,7 @@ static int icl_check_nv12_planes(struct intel_atomic_state *state,
if (plane->pipe != crtc->pipe)
continue;
- if (plane_state->planar_linked_plane)
- unlink_nv12_plane(crtc_state, plane_state);
+ unlink_nv12_plane(crtc_state, plane_state);
}
if (!crtc_state->nv12_planes)
With that we could perhaps even drop the second unlink_nv12_plane()
call, but haven't really thought through the details...
> 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.
I do have a patch in some branch that changes the Y plane
selection to use 'enabled_planes' instead of 'active_planes'
which is equivalent to this. It is perhaps the slightly more
logical approach but it could result some specific usage
scenarios losing NV12 scanout capability. IIRC I also had
some unsolved issue with that approach, which is why I never
even sent out the patch.
> 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 <uma.shankar@intel.com>
> Cc: Jani Nikula <jani.nikula@intel.com>
> Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
> Signed-off-by: Khaled Almahallawy <khaled.almahallawy@intel.com>
> ---
> 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
--
Ville Syrjälä
Intel
next prev parent reply other threads:[~2026-02-12 11:47 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-12 0:48 [RFC PATCH] drm/i915/display: Prevent NV12 Y-plane allocation from stealing userspace planes Khaled Almahallawy
2026-02-12 1:54 ` ✗ CI.checkpatch: warning for " Patchwork
2026-02-12 1:55 ` ✓ CI.KUnit: success " Patchwork
2026-02-12 2:29 ` ✓ Xe.CI.BAT: " Patchwork
2026-02-12 11:47 ` Ville Syrjälä [this message]
2026-02-12 20:55 ` [RFC PATCH] " Almahallawy, Khaled
2026-02-13 7:44 ` ✗ Xe.CI.FULL: failure for " Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aY293Q8lcThgXIds@intel.com \
--to=ville.syrjala@linux.intel.com \
--cc=intel-gfx@lists.freedesktop.org \
--cc=intel-xe@lists.freedesktop.org \
--cc=jani.nikula@intel.com \
--cc=khaled.almahallawy@intel.com \
--cc=uma.shankar@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox