All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
To: Maarten Lankhorst <dev@lankhorst.se>
Cc: intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org
Subject: Re: [PATCH 12/14] drm/xe: Use the correct stolen offset in initial FB readout
Date: Tue, 19 May 2026 15:26:06 +0300	[thread overview]
Message-ID: <agxW3n83Oywqz9Hi@intel.com> (raw)
In-Reply-To: <86e155fd-1cc1-4249-b59e-80fc5d081fa3@lankhorst.se>

On Mon, May 18, 2026 at 10:16:55PM +0200, Maarten Lankhorst wrote:
> Hello,
> 
> Den 2026-05-18 kl. 15:59, skrev Ville Syrjälä:
> > On Mon, May 18, 2026 at 11:27:46AM +0200, Maarten Lankhorst wrote:
> >> Hey Ville,
> >>
> >> Den 2026-05-11 kl. 23:41, skrev Ville Syrjala:
> >>> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> >>>
> >>> The current assumption that the initial FB offset into stolen and
> >>> GGTT are the same is completely wrong for MTL+. On these platforms
> >>> the GOP always places the FB at start of stolen, but then maps it
> >>> to the top of GGTT.
> >>>
> >>> Read the correct phys_base from the PTE so that we at least take
> >>> over the correct part of the physical memory.
> >>>
> >>> The GGTT offset is more annoying to deal with there. The horrible
> >>> ggtt->start and GUC_GGTT_TOP hacks prevent us from even keeping the
> >>> original GGTT mapping (ggtt->start blocks pre-MTL hardware and
> >>> GUC_GGTT_TOP blcoks MTL+). For now just hack this and remap the
> >>> FB to live at ggtt->start. On MTL+ this might even work correctly
> >>> since we're unlikely to overlap with the original mapping. But on
> >>> earlier platforms we're guaranteed to have an overlap if the FB
> >>> is larger than ggtt->start. Such an overlap will cause visible
> >>> glitches on the screen as the PTEs get overwritten while the
> >>> display hardware is still using them for scanout.
> >>>
> >>> On i915 we don't have the ggtt->start hack and thus can always
> >>> bind the FB to actual start of GGTT. i915 does have the equivalent
> >>> of GUC_GGTT_TOP so it can't leave the mapping to the end of GGTT
> >>> either sadly.
> >>>
> >>> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> >>> ---
> >>>  drivers/gpu/drm/xe/display/xe_initial_plane.c | 35 +++++++++++++++----
> >>>  1 file changed, 28 insertions(+), 7 deletions(-)
> >>>
> >>> diff --git a/drivers/gpu/drm/xe/display/xe_initial_plane.c b/drivers/gpu/drm/xe/display/xe_initial_plane.c
> >>> index d0a9f8599096..da44f6d1a5f8 100644
> >>> --- a/drivers/gpu/drm/xe/display/xe_initial_plane.c
> >>> +++ b/drivers/gpu/drm/xe/display/xe_initial_plane.c
> >>> @@ -42,6 +42,7 @@ initial_plane_bo(struct xe_device *xe,
> >>>  {
> >>>  	struct xe_tile *tile0 = xe_device_get_root_tile(xe);
> >>>  	struct xe_bo *bo;
> >>> +	dma_addr_t dma_addr;
> >>>  	resource_size_t phys_base;
> >>>  	u32 base, size, flags;
> >>>  	u64 page_size = xe->info.vram_flags & XE_VRAM_FLAGS_NEED64K ? SZ_64K : SZ_4K;
> >>> @@ -64,7 +65,8 @@ initial_plane_bo(struct xe_device *xe,
> >>>  			return NULL;
> >>>  		}
> >>>  
> >>> -		phys_base = pte & ~(page_size - 1);
> >>> +		dma_addr = pte & ~(page_size - 1);
> >>> +		phys_base = dma_addr;
> >>>  
> >>>  		flags |= XE_BO_FLAG_VRAM0;
> >>>  
> >>> @@ -78,10 +80,6 @@ initial_plane_bo(struct xe_device *xe,
> >>>  				&phys_base);
> >>>  			return NULL;
> >>>  		}
> >>> -
> >>> -		drm_dbg_kms(&xe->drm,
> >>> -			    "Using phys_base=%pa, based on initial plane programming\n",
> >>> -			    &phys_base);
> >>>  	} else {
> >>>  		struct ttm_resource_manager *stolen;
> >>>  		u64 pte;
> >>> @@ -99,11 +97,29 @@ initial_plane_bo(struct xe_device *xe,
> >>>  			return NULL;
> >>>  		}
> >>>  
> >>> -		phys_base = base;
> >>> +		dma_addr = pte & ~(page_size - 1);
> >>> +		phys_base = dma_addr - xe_ttm_stolen_gpu_offset(xe);
> >>> +
> >>>  		flags |= XE_BO_FLAG_STOLEN;
> >>>  	}
> >>>  
> >>> -	bo = xe_bo_create_pin_map_at_novm(xe, tile0, size, phys_base, phys_base,
> >>> +	drm_dbg_kms(&xe->drm,
> >>> +		    "Initial plane dma_addr=%pa phys_base=%pa\n",
> >>> +		    &dma_addr, &phys_base);
> >>> +
> >>> +	/*
> >>> +	 * Pin to xe_ggtt_start() to avoid conflicting with
> >>> +	 * the horrible ggtt->start and GUC_GGTT_TOP hacks.
> >>> +	 *
> >>> +	 * FIXME this is complete crap. To do this properly we
> >>> +	 * need to prevent the original PTEs from being overwritten
> >>> +	 * while bindind to the new address. Any overlap between
> >>> +	 * the old and new ranges will corrupt the old PTEs that
> >>> +	 * the display hardware is currently using for scanout.
> >>> +	 */
> >>> +	base = xe_ggtt_start(tile0->mem.ggtt);
> >>
> >> The comment is mostly accurate in describing your solution. You have all
> >> the pieces to know which part of GGTT are allocatable. Only
> >> xe_ggtt_size() bytes starting at xe_ggtt_start() are allocatable.
> >> This is because xe also supports VF's, which only has a part of the GGTT
> >> usable.
> > 
> > We don't care about VFs here. But ggtt->start != 0 also for the PF for
> > whatever silly reason.
> > 
> >>
> >> ggtt->start can be adjusted at runtime when the VF is migrated to a new
> >> location. I'm open for better solutions that are still O(1).
> >> See xe_ggtt_shift_nodes() for some details, or read through the SR-IOV
> >> documentation of the xe module.
> >>
> >> The previous assumption used GGTT address == physical address on all
> >> platforms, which was accurate at the time it was written. Judging from
> >> the comments it now breaks on MTL.
> > 
> > It is also broken on older platforms due to that ggtt->start mess.
> > Clearly none of this has ever worked correctly.
> > 
> >>
> >> Fortunately, you can derive the exact address of the current allocation.
> >> That makes it easy to handle this correctly. Can you extend
> >> xe_ggtt_insert_node() with a start + end argument, or create
> >> xe_ggtt_insert_node_at() that has those arguments?
> >>
> >> If you then reserve the current allocation in advance, the workaround
> >> that required creating xe_ggtt_insert_bo_at() can then be removed.
> >>
> >> After the BO is mapped, it's safe to call xe_ggtt_node_remove() on the
> >> current location with invalidate set to false. The contents will be
> >> cleared by xe_ggtt_init() later on during the init sequence.
> > 
> > If you really want to fix this properly then just get rid of those
> > ggtt->start and GUC_GGTT_TOP hacks and allow the code to just insert
> > the node at the same location where the GOP placed it. Then we wouldn't
> > need any stupid hacks here.
> 
> I'm aware that it may not seem entirely optimal to not allow <1%
> of 4096 MiB GGTT to be used because it may be problematic in some cases,
> causing hard to debug issues.
> 
> Fortunately GGTT exhaustion is not really a problem on xe and it's safe to
> just reserve the problematic regions. It's definitely a trade-off, but one
> I feel has the right balance for the right reasons.

I don't really care whether we allow the use of those parts of ggtt
or not. But the way the exclusion is implemented is just bad. I think
the correct thing here would be to initialize the drm_mm for the full
ggtt range, and then permanently reserve the bits we don't want to
use. This way the display code doesn't have to know these silly
implementation details.

It would also fix xe_ggtt_initial_clear() to actually clear the
entire ggtt instead of leaving stale PTEs hanging around for the
reserved ranges.

> 
> Additionally, even if it may appear to work at first. It can prove
> problematic in a variety of ways.
> 
> Userspace can directly map the initial FB into its address space and
> manipulate it directly. Can you say with certainty GuC will never
> access it, even if there's a GPU hang?

Userspace specifies everything in terms of ppgtt addresses. How would
those get magically translated to ggtt addresses?

> 
> Additionally, on suspend/resume the kernel will backup/restore between
> normal memory and VRAM. Or perhaps in other paths as well that I haven't
> even thought of. 
> 
> In the tradeoff where we no longer reserve start and GUC_GGTT_TOP,
> you would have to perform a lot of testing for no benefit.
> 
> It's a lot easier to reserve the accessible bits of the first mapping,
> create a second mapping, point the frame pointer there and never think
> about it again.

If you want to reserve them go ahead, but do it in a way that doesn't
leak the implementation details all over the place. Ie. I don't want
the display code to know anything about this mess.

-- 
Ville Syrjälä
Intel

  reply	other threads:[~2026-05-19 12:26 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-11 21:41 [PATCH 00/14] drm/{i915,xe}: BIOS FB takeover fixes Ville Syrjala
2026-05-11 21:41 ` [PATCH 01/14] drm/i915: Disable the plane if initial plane config readout failed Ville Syrjala
2026-05-12 10:25   ` Jani Nikula
2026-05-11 21:41 ` [PATCH 02/14] drm/i915/fbdev: Extract bios_fb_ok() Ville Syrjala
2026-05-12 10:29   ` Jani Nikula
2026-05-11 21:41 ` [PATCH 03/14] drm/i915: Throw away the BIOS fb if has the wrong depth/bpp Ville Syrjala
2026-05-12 10:33   ` Jani Nikula
2026-05-11 21:41 ` [PATCH 04/14] drm/i915: Introduce intel_bo_fbdev_bios_fb_ok() Ville Syrjala
2026-05-11 21:41 ` [PATCH 05/14] drm/i915: Use drm_dbg_kms() for initial FB debugs Ville Syrjala
2026-05-12 10:40   ` Jani Nikula
2026-05-11 21:41 ` [PATCH 06/14] drm/xe: Do the initial FB size alignment earlier Ville Syrjala
2026-05-11 21:41 ` [PATCH 07/14] drm/xe/ggtt: Decouple lmem/stolen physcial offset from GGTT offset Ville Syrjala
2026-05-11 21:41 ` [PATCH 08/14] drm/xe: Print a debug message if we have no stolen for the initial FB Ville Syrjala
2026-05-12 10:45   ` Jani Nikula
2026-05-11 21:41 ` [PATCH 09/14] drm/xe: Abstract the initial FB PTE checks a bit Ville Syrjala
2026-05-12 10:48   ` Jani Nikula
2026-05-18  8:15   ` Maarten Lankhorst
2026-05-18 13:46     ` Ville Syrjälä
2026-05-11 21:41 ` [PATCH 10/14] drm/xe: Check the PTE local memory bit for initial FB in stolen Ville Syrjala
2026-05-11 21:41 ` [PATCH 11/14] drm/xe: s/bar2/lmembar/ Ville Syrjala
2026-05-12 10:49   ` Jani Nikula
2026-05-11 21:41 ` [PATCH 12/14] drm/xe: Use the correct stolen offset in initial FB readout Ville Syrjala
2026-05-18  9:27   ` Maarten Lankhorst
2026-05-18 13:59     ` Ville Syrjälä
2026-05-18 20:16       ` Maarten Lankhorst
2026-05-19 12:26         ` Ville Syrjälä [this message]
2026-05-19 14:23           ` Jani Nikula
2026-05-11 21:41 ` [PATCH 13/14] drm/i915: Fix BIOS FB memory region name debug prints Ville Syrjala
2026-05-11 21:41 ` [PATCH 14/14] drm/i915: Print the phys_base in addition to the dma_addr for the BIOS FB Ville Syrjala
2026-05-11 22:27 ` ✓ i915.CI.BAT: success for drm/{i915,xe}: BIOS FB takeover fixes Patchwork
2026-05-12  7:02 ` ✓ i915.CI.Full: " Patchwork
2026-05-12  9:02 ` ✓ CI.KUnit: " Patchwork
2026-05-12 10:12 ` ✓ Xe.CI.BAT: " Patchwork
2026-05-12 18:47 ` ✗ Xe.CI.FULL: failure " 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=agxW3n83Oywqz9Hi@intel.com \
    --to=ville.syrjala@linux.intel.com \
    --cc=dev@lankhorst.se \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=intel-xe@lists.freedesktop.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.