Re: [PATCH] drm/i915: Do NOT skip the first 4k of stolen memory for pre-allocated buffers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

On 05-04-18 15:26, Daniel Vetter wrote:
On Thu, Apr 5, 2018 at 1:47 PM, Hans de Goede <hdegoede@xxxxxxxxxx> wrote:
Hi,


On 05-04-18 09:14, Daniel Vetter wrote:

On Fri, Mar 30, 2018 at 02:27:15PM +0200, Hans de Goede wrote:

Before this commit the WaSkipStolenMemoryFirstPage workaround code was
skipping the first 4k by passing 4096 as start of the address range
passed
to drm_mm_init(). This means that calling drm_mm_reserve_node() to try
and
reserve the firmware framebuffer so that we can inherit it would always
fail, as the firmware framebuffer starts at address 0.

Commit d43537610470 ("drm/i915: skip the first 4k of stolen memory on
everything >= gen8") says in its commit message: "This is confirmed to
fix
Skylake screen flickering issues (probably caused by the fact that we
initialized a ring in the first page of stolen, but I didn't 100% confirm
this theory)."

Which suggests that it is safe to use the first page for a linear
framebuffer as the firmware is doing.

This commit always passes 0 as start to drm_mm_init() and works around
WaSkipStolenMemoryFirstPage in i915_gem_stolen_insert_node_in_range()
by insuring the start address passed by to drm_mm_insert_node_in_range()
is always 4k or more. All entry points to i915_gem_stolen.c go through
i915_gem_stolen_insert_node_in_range(), so that any newly allocated
objects such as ring-buffers will not be allocated in the first 4k.

The one exception is i915_gem_object_create_stolen_for_preallocated()
which directly calls drm_mm_reserve_node() which now will be able to
use the first 4k.

This fixes the i915 driver no longer being able to inherit the firmware
framebuffer on gen8+, which fixes the video output changing from the
vendor logo to a black screen as soon as the i915 driver is loaded
(on systems without fbcon).

Signed-off-by: Hans de Goede <hdegoede@xxxxxxxxxx>


I think this is worth a shot. The only explanation I can think of why the
GOP could get away with this and still follow the w/a is if it doesn't
have a 1:1 mapping between GGTT and stolen.


My guess is that the GOP does not care about the w/a because the w/a
states that the command-streamers sometimes do a spurious flush (write)
to the first page, and the command-streamers are not used until much
later, so the GOP is probably ignoring the w/a all together.

At least that is my theory.

Atm we do not know whether the GOP actually implements the wa or not.
That it doesn't care is just a conjecture, but we have no proof. On
previous platforms the 1:1 mapping did hold, but there's no
fundamental reason why it sitll does.

Atm we hardcode that
assumption in intel_alloc_initial_plane_obj by passing the base_aligned as
both the stolen_offset and the gtt_offset (but it's only the gtt_offset
really). And since we're not re-writing the ptes it's not noticeable.

I think to decide whether this is the right approach we should
double-check whether that 1:1 assumption really holds true: Either read
back the ggtt ptes and check their addresses (but iirc on some platforms
their write-only, readback doesn't work), or we also rewrite the ptes
again for preallocated stuff, like when binding a normal object into the
gtt. If either of these approaches confirms that those affected gen8+
machines still use the 1:1 mapping, then I'm happy to put my r-b on this
patch. If not, well then we at least know what to fix: We need to read out
the real stolen_offset, instead of making assumptions.


I'm happy to give this a try on one or more affected machines, I can e.g.
try this on both a skylake desktop and a cherry-trail based tablet.

But I'm clueless about the whole PTE stuff, so I'm going to need someone
to provide me with a patch following either approach. If readback of the
PTEs works on skylake / cherrytrail I guess that would be the best way.

Note to test this I'm currently booting the kernel with the machine's
UEFI vendor logo still being displayed when efifb kicks in. I've added:
"fbcon=vc:2-62" to the kernel commandline to make fbcon not bind to
VC0 / VC1, so that the framebuffer contents stays intact, combined with
the patch we are discussing now, this makes the vendor logo stay on
the screen all the way till GDM loads, which looks rather nice actually :)

And on shutdown we fall back to the original framebuffer and the vendor
logo is back again. I cannot see any corruption in the display at either
boot or shutdown time.

It shouldn't matter whether efifb takes over or not, it's still the
GOP's framebuffer we're taking over. Different content for sure, logo
is gone, but we only care about which pages we're using.

Right, I only mentioned this to explain that I'm not seeing any
(visible) corruption.

Wrt the code:
- (Re)binding happens by calling i915_vma_bind, if you put a call to
that at the end of the stolen_preallocated functions you should get
that. Ofc needs the logo still there so you can see it jump/get
mangled.
- GGTT PTEs for gen8+ are written through e.g. gen8_ggttt_insert_page
or gen8_ggtt_insert_entries (which takes the vma). Since we only care
about the first entry a readq(dev_priv->ggtt->gsm) is all we really
need. If it's all 0 then it's not working (since at least
_PAGE_PRESENT should be set, plus the physical address of a page in
stolen memory).

Ok, I will try to give this a shot, probably not before coming
Monday though.

I can do some patches for each of those, but a bit swamped. Also no
gen8 handy for testing I think to make sure it works, so would take a
few weeks probably.

I'll give this a shot myself first and attach the patch when I reply
with the testing results, so that you can verify that the patch works
as expected.

Regards,

Hans



Cheers, Daniel



Cheers, Daniel

---
   drivers/gpu/drm/i915/i915_gem_stolen.c | 15 ++++++---------
   1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c
b/drivers/gpu/drm/i915/i915_gem_stolen.c
index af915d041281..ad949cc30928 100644
--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
@@ -51,6 +51,10 @@ int i915_gem_stolen_insert_node_in_range(struct
drm_i915_private *dev_priv,
         if (!drm_mm_initialized(&dev_priv->mm.stolen))
                 return -ENODEV;
   +     /* WaSkipStolenMemoryFirstPage:bdw+ */
+       if (INTEL_GEN(dev_priv) >= 8 && start < 4096)
+               start = 4096;
+
         mutex_lock(&dev_priv->mm.stolen_lock);
         ret = drm_mm_insert_node_in_range(&dev_priv->mm.stolen, node,
                                           size, alignment, 0,
@@ -343,7 +347,6 @@ int i915_gem_init_stolen(struct drm_i915_private
*dev_priv)
   {
         resource_size_t reserved_base, stolen_top;
         resource_size_t reserved_total, reserved_size;
-       resource_size_t stolen_usable_start;
         mutex_init(&dev_priv->mm.stolen_lock);
   @@ -435,17 +438,11 @@ int i915_gem_init_stolen(struct drm_i915_private
*dev_priv)
                          (u64)resource_size(&dev_priv->dsm) >> 10,
                          ((u64)resource_size(&dev_priv->dsm) -
reserved_total) >> 10);
   -     stolen_usable_start = 0;
-       /* WaSkipStolenMemoryFirstPage:bdw+ */
-       if (INTEL_GEN(dev_priv) >= 8)
-               stolen_usable_start = 4096;
-
         dev_priv->stolen_usable_size =
-               resource_size(&dev_priv->dsm) - reserved_total -
stolen_usable_start;
+               resource_size(&dev_priv->dsm) - reserved_total;
         /* Basic memrange allocator for stolen space. */
-       drm_mm_init(&dev_priv->mm.stolen, stolen_usable_start,
-                   dev_priv->stolen_usable_size);
+       drm_mm_init(&dev_priv->mm.stolen, 0,
dev_priv->stolen_usable_size);
         return 0;
   }
--
2.17.0.rc2

_______________________________________________
Intel-gfx mailing list
Intel-gfx@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/intel-gfx






_______________________________________________
Intel-gfx mailing list
Intel-gfx@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/intel-gfx




[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux