[Intel-gfx] [PATCH 1/3] drm/i915: Make fb user dirty operation to invalidate frontbuffer

Vivi, Rodrigo rodrigo.vivi at intel.com
Tue Jul 7 13:23:46 PDT 2015


On Tue, 2015-07-07 at 13:24 +0200, Daniel Vetter wrote:
> On Mon, Jul 06, 2015 at 11:19:03PM +0000, Vivi, Rodrigo wrote:
> > On Mon, 2015-07-06 at 19:56 +0200, Daniel Vetter wrote:
> > > On Mon, Jul 06, 2015 at 02:11:55PM -0300, Paulo Zanoni wrote:
> > > > 2015-07-06 13:43 GMT-03:00 Vivi, Rodrigo <rodrigo.vivi at intel.com>:
> > > > > On Fri, 2015-07-03 at 09:10 +0200, Daniel Vetter wrote:
> > > > >> On Thu, Jul 02, 2015 at 04:41:32PM +0000, Vivi, Rodrigo wrote:
> > > > >> > On Thu, 2015-07-02 at 13:03 -0300, Paulo Zanoni wrote:
> > > > >> > > 2015-06-30 20:42 GMT-03:00 Rodrigo Vivi <rodrigo.vivi at intel.com>:
> > > > >> > > > Let's do a frontbuffer invalidation on dirty fb.
> > > > >> > > > To be used for DIRTYFB drm ioctl.
> > > > >> > > >
> > > > >> > > > This patch solves the biggest PSR known issue, that is
> > > > >> > > > missed screen updates during boot, mainly when there is a splash
> > > > >> > > > screen involved like plymouth.
> > > > >> > > >
> > > > >> > > > Plymoth will do a modeset over ioctl that flushes frontbuffer
> > > > >> > > > tracking and PSR gets back to work while it cannot track the
> > > > >> > > > screen updates and exit properly. However plymouth also uses
> > > > >> > > > a dirtyfb ioctl whenever updating the screen. So let's use it
> > > > >> > > > to invalidate PSR back again.
> > > > >> > > >
> > > > >> > > > v2: Remove ORIGIN_FB_DIRTY and use ORIGIN_GTT instead since dirty
> > > > >> > > >     callback is just called after few screen updates and not on
> > > > >> > > >     everyone as pointed by Daniel.
> > > > >> > > >
> > > > >> > > > Cc: Daniel Vetter <daniel.vetter at ffwll.ch>
> > > > >> > > > Signed-off-by: Rodrigo Vivi <rodrigo.vivi at intel.com>
> > > > >> > > > ---
> > > > >> > > >  drivers/gpu/drm/i915/intel_display.c | 18 ++++++++++++++++++
> > > > >> > > >  1 file changed, 18 insertions(+)
> > > > >> > > >
> > > > >> > > > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > > > >> > > > index 724b0e3..b55b1b6 100644
> > > > >> > > > --- a/drivers/gpu/drm/i915/intel_display.c
> > > > >> > > > +++ b/drivers/gpu/drm/i915/intel_display.c
> > > > >> > > > @@ -14393,9 +14393,27 @@ static int intel_user_framebuffer_create_handle(struct drm_framebuffer *fb,
> > > > >> > > >         return drm_gem_handle_create(file, &obj->base, handle);
> > > > >> > > >  }
> > > > >> > > >
> > > > >> > > > +static int intel_user_framebuffer_dirty(struct drm_framebuffer *fb,
> > > > >> > > > +                                              struct drm_file *file,
> > > > >> > > > +                                              unsigned flags, unsigned color,
> > > > >> > > > +                                              struct drm_clip_rect *clips,
> > > > >> > > > +                                              unsigned num_clips)
> > > > >> > >
> > > > >> > > You don't need the white space on the lines above, just the tabs.
> > > > >> > >
> > > > >> > > > +{
> > > > >> > > > +       struct drm_device *dev = fb->dev;
> > > > >> > > > +       struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
> > > > >> > > > +       struct drm_i915_gem_object *obj = intel_fb->obj;
> > > > >> > > > +
> > > > >> > > > +       mutex_lock(&dev->struct_mutex);
> > > > >> > > > +       intel_fb_obj_invalidate(obj, ORIGIN_GTT);
> > > > >> > >
> > > > >> > > As far as I understood from my brief investigation, the dirty IOCTL
> > > > >> > > just says "hey, I'm done writing on the memory, you can flush things
> > > > >> > > now", and if the user writes on the buffer again later, it will need
> > > > >> > > to call the dirty IOCTL again. So shouldn't we call
> > > > >> > > intel_fb_obj_flush(obj, false) here? It seems this was also pointed by
> > > > >> > > Daniel on the first review. It would be better because it would allow
> > > > >> > > us to actually keep PSR/FBC enabled.
> > > > >> >
> > > > >> > The flush caused by the dumb modeset ioctl is exactly what I want to
> > > > >> > revert here.
> > > > >> >
> > > > >> > Well, I just tested to double check here and flush makes me to miss
> > > > >> > screen updates. (triple checked with retired = true as well just in
> > > > >> > case)
> > > > >> >
> > > > >> > fbdev comes to place and invalidated frontbuffer, then plymouth does a
> > > > >> > flush that makes psr start working when it should continue disabled.
> > > > >> > Continue flushing it doesn't solve the problem, just ratify it.
> > > > >> >
> > > > >> > But beside the issue that it is solving I don't believe we want is a
> > > > >> > flush anyway. There is something writing directly to frontbuffer with no
> > > > >> > invalidation. The dirty call is supposed to be a damage call that
> > > > >> > actually tells something on the screen got written and needs to be
> > > > >> > updated if it hasn't still. In our cause this is exactly the frontbuffer
> > > > >> > invalidate, not the flush.
> > > > >> >
> > > > >> > The flush place would be after it really stopped doing something, but
> > > > >> > since I don't trust it I prefer to let it invalidated until next flip.
> > > > >>
> > > > >> See my review on the first round of this patch: dirtyfb _is_ a flush. If
> > > > >> it's not enough then there's some other problems still around.
> > > > >
> > > > > Well, the flush itself in the way it is defined is to flush frontbuffer
> > > > > bits and put power saving features back to work. PSR flush for instance
> > > > > doesn't exit on every flush. Only in the cases that we know HW tracking
> > > > > doesn't work.
> > > > >
> > > > > One possibility would be change PSR to respect that all flush always is
> > > > > invalidate (exit) + flush fb_bits. But I'm against this since PSR on
> > > > > core platforms doesn't have SW trackking ext and it wasn't implemented
> > > > > to be fully enabled/disabled every time.
> > > > >
> > > > > Another idea on this line is to make flushs know origins or at least a
> > > > > boolean to separate cases where flush must be handled as flush bits +
> > > > > continue working or invalidate + flush bits + start working again
> > > > >
> > > > > Please let me know what you think.
> > > > >
> > > > > But putting flushs on this dirty callback is currently useless because
> > > > > flush just tells psr to continue working without getting screen updates.
> > > > >
> > > > > Well, this is the most important discussion for now, but also even we
> > > > > change flush interface or only in PSR I'm not sure this will work.
> > > > >
> > > > > This dirty case happens in the middle of fbdev and when it gives control
> > > > > back to fbcon psr would be working without no one else invalidate or
> > > > > flushing it and we would miss screen updates anyway.
> > > > > But in this case I understand this is a hack and if we put the
> > > > > invalidate there I should also put a FIXME XXX explaining that...
> > > > 
> > > > Last week I discussed some of this with Rodrigo on IRC and we have
> > > > different interpretations on what the frontbuffer tracking calls mean.
> > > > Daniel, can you please clarify a few things?
> > > > 
> > > > One of the things I've discussed with Rodrigo is that I consider
> > > > invalidate+flush to be equivalent to just a flush call, while Rodrigo
> > > > sees both cases as different. Daniel, can you please clarify the
> > > > intentions of the frontbuffer tracking infrastructure here?
> > > 
> > > Yeah essentially flush without an invalidate is just a instantaneous
> > > invalidate+flush. invalidate just means "someone started to frontbuffer
> > > render and I have no idea at all when that will stop". Flush means
> > > "someone has done some frontbuffer rendering, make sure those updates land
> > > on the screen". So yeah Paulo's idea is correct.
> > 
> > Thanks for the clarification...
> > 
> > > 
> > > Problem is now that when we get a flip we also call flush, and for psr on
> > > big core that's probably not what we want since it can handle flips
> > > correctly, but not real frontbuffer flushes.
> > > 
> > > > One contradiction I see with the current code is that PSR does nothing
> > > > on flush() for BDW because it believes the HW tracking, but it does
> > > > psr_exit() on invalidate for every single case. If it relies on the HW
> > > > tracking, shouldn't it also do nothing on invalidate()? If it doesn't
> > > > rely on HW tracking, shouldn't it do something on flush()? If it
> > > > relies on just a few specific pieces of the HW tracking, shouldn't it
> > > > check enum fb_op_origin? The conclusion here is that the PSR code is
> > > > completely relying on having invalidate() calls before the flush() for
> > > > cases where it needs help from software.
> > > 
> > > Calling invalidate before flush isn't imo the right fix since usually
> > > (except when you have working hw tracking like fbc for gtt mmaps) you need
> > > to stop psr/fbc/whatever on invalidate. Whereas on flush you just need to
> > > make sure screen contents get to the screen.
> > > 
> > > I think the best option would be to wire up the fb_op_origin for flushes
> > > too, and then filter out ORIGIN_FLIP for psr (except for sprites on hsw)
> > > on big core.
> > 
> > Ok, this approach here works here when I have splash screen taking place
> > and X coming right after it. However we still have one issue that is
> > when it goes back to console.
> > 
> > fbdev on set_par invalidated front buffer, but then splash screen came
> > and flushed it, psr started working, then control gets back to fbdev and
> > nothing invalidates more so from this point on we miss many (if not all)
> > screen updates.
> > 
> > So we are going to a endless path where we could have many cases where
> > fbdev will be flushed with no reliable way to get invalidated again.
> > 
> > So, right now I just see 3 paths:
> > 1. invalidate instead of flush on fb dirty callback just to make sure
> > everything gets invalidated when using dumb ioctls
> > 2. change fbdev and all its clients to make a proper use of a dirty.
> > 3. change fbdev, fbcon to propagate console switch (KD_TEXT info) where
> > we would have a way to know exactly who is in control
> > 4. Introdoce IOCTLs for PSR and enable/disable it on DDX when we know
> > DDX has control.
> > 
> > I really don't like the idea to change fbdev scructures and its
> > clients...
> > 
> > Please let me know if you have other/better ideas and also what path you
> > prefer...
> 
> As I mentioned we're not the only ones with exactly this problem, udl &
> qxl have the same need for calling dirtyfb all over the place from fbdev
> hooks. qxl seems to have the more complete solution using a workqueue.

Yes, I agree. I just want to block PSR on this fbdev rework that is not
simple, involve many maintainers and it is not the main PSR use case.

> 
> What I'm still wondering about though is why we don't get an fbdev
> invalidate when switching back to the console. boot splash should be doing
> it's drawing on its own buffer, fbcon would switch back (which means a
> set_par call) and that should invalidate. I have no idea why we don't get
> this call in your setup ...

You were right.... I wasn't relying on set_par but it is actually called
on fbcon switch back, but the invalidate was happening only on the first
time because write_domain was already GTT. So with the following patch
we can solve the case where I press "Esc" key on the middle of splash
screen:
http://cgit.freedesktop.org/~vivijim/drm-intel/commit/?h=psr&id=ce7226054085080c10e53b82743a76e0593b785a


But I was facing also another issue with crypto pass and without any
splash and trace lead me to fbdev_restore_mode so another hack:
http://cgit.freedesktop.org/~vivijim/drm-intel/commit/?h=psr&id=9a7c3f7853a327a82551e335b6056b5e5362004a


All (an more) in
http://cgit.freedesktop.org/~vivijim/drm-intel/log/?h=psr
for now... while I'm not sure a flicker on fedora reported by community
is not reliably solved:

https://bugzilla.redhat.com/show_bug.cgi?id=1236303

Thanks,
Rodrigo.





> -Daniel



More information about the Intel-gfx mailing list