diff mbox

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

Message ID 1435707722-2152-1-git-send-email-rodrigo.vivi@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Rodrigo Vivi June 30, 2015, 11:42 p.m. UTC
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@ffwll.ch>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

Comments

Chris Wilson July 1, 2015, 8:04 a.m. UTC | #1
On Tue, Jun 30, 2015 at 04:42:00PM -0700, Rodrigo Vivi wrote:
> 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@ffwll.ch>
> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

Will it ever grow the ability to handle clip rects? I can detect the
presence of the syscall and call it appropriately, but I don't want to
have to start tracking frontbuffer damage unless there's a significant
advantage in doing so (to offset the cost of the tracking).
-Chris
Daniel Vetter July 1, 2015, 1:19 p.m. UTC | #2
On Wed, Jul 01, 2015 at 09:04:08AM +0100, Chris Wilson wrote:
> On Tue, Jun 30, 2015 at 04:42:00PM -0700, Rodrigo Vivi wrote:
> > 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@ffwll.ch>
> > Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> 
> Will it ever grow the ability to handle clip rects? I can detect the
> presence of the syscall and call it appropriately, but I don't want to
> have to start tracking frontbuffer damage unless there's a significant
> advantage in doing so (to offset the cost of the tracking).

For now this is just for generic userspace using the dumb mmap ioctls,
which does already dirty everything. For gem/i915 userspace the existing
frontbuffer tracking rules will still apply.

I think the damage rect will only be useful for psr2 single-shot uploads,
but we need to do some serious hacks using debug rects to pull this off -
the hw wants to be way to helpful and gets in the way. And I think for
that usecase it only makes sense to supply the overall per-crtc damage
rect in an atomic flip. Tracking damage for frontbuffer rendering probably
won't be worth it anytime soon at all.

In short: Nothing to worry about yet for a long time ;-)
-Daniel
Chris Wilson July 1, 2015, 1:21 p.m. UTC | #3
On Wed, Jul 01, 2015 at 03:19:31PM +0200, Daniel Vetter wrote:
> On Wed, Jul 01, 2015 at 09:04:08AM +0100, Chris Wilson wrote:
> > On Tue, Jun 30, 2015 at 04:42:00PM -0700, Rodrigo Vivi wrote:
> > > 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@ffwll.ch>
> > > Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > 
> > Will it ever grow the ability to handle clip rects? I can detect the
> > presence of the syscall and call it appropriately, but I don't want to
> > have to start tracking frontbuffer damage unless there's a significant
> > advantage in doing so (to offset the cost of the tracking).
> 
> For now this is just for generic userspace using the dumb mmap ioctls,
> which does already dirty everything. For gem/i915 userspace the existing
> frontbuffer tracking rules will still apply.

But they are inadequate for the map/set-domain scanout once and write
through the GTT for umpteen seconds, which can happen quite frequenctly.

In that situation, we behave exactly like fbdev/dumb fb.
-Chris
Daniel Vetter July 1, 2015, 2:09 p.m. UTC | #4
On Wed, Jul 01, 2015 at 02:21:40PM +0100, Chris Wilson wrote:
> On Wed, Jul 01, 2015 at 03:19:31PM +0200, Daniel Vetter wrote:
> > On Wed, Jul 01, 2015 at 09:04:08AM +0100, Chris Wilson wrote:
> > > On Tue, Jun 30, 2015 at 04:42:00PM -0700, Rodrigo Vivi wrote:
> > > > 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@ffwll.ch>
> > > > Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > > 
> > > Will it ever grow the ability to handle clip rects? I can detect the
> > > presence of the syscall and call it appropriately, but I don't want to
> > > have to start tracking frontbuffer damage unless there's a significant
> > > advantage in doing so (to offset the cost of the tracking).
> > 
> > For now this is just for generic userspace using the dumb mmap ioctls,
> > which does already dirty everything. For gem/i915 userspace the existing
> > frontbuffer tracking rules will still apply.
> 
> But they are inadequate for the map/set-domain scanout once and write
> through the GTT for umpteen seconds, which can happen quite frequenctly.
> 
> In that situation, we behave exactly like fbdev/dumb fb.

Yeah you can use it to flush gtt of course too. And there I'd just
defensively flush the entire fb until we've grown more clueful in the
kernel. But for forntbuffer flushing I don't expect that to ever happen
for i915. It makes more sense ofc for udl/qxl and others where uploads are
really expensive.
-Daniel
Chris Wilson July 1, 2015, 2:26 p.m. UTC | #5
On Wed, Jul 01, 2015 at 04:09:19PM +0200, Daniel Vetter wrote:
> On Wed, Jul 01, 2015 at 02:21:40PM +0100, Chris Wilson wrote:
> > On Wed, Jul 01, 2015 at 03:19:31PM +0200, Daniel Vetter wrote:
> > > On Wed, Jul 01, 2015 at 09:04:08AM +0100, Chris Wilson wrote:
> > > > On Tue, Jun 30, 2015 at 04:42:00PM -0700, Rodrigo Vivi wrote:
> > > > > 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@ffwll.ch>
> > > > > Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > > > 
> > > > Will it ever grow the ability to handle clip rects? I can detect the
> > > > presence of the syscall and call it appropriately, but I don't want to
> > > > have to start tracking frontbuffer damage unless there's a significant
> > > > advantage in doing so (to offset the cost of the tracking).
> > > 
> > > For now this is just for generic userspace using the dumb mmap ioctls,
> > > which does already dirty everything. For gem/i915 userspace the existing
> > > frontbuffer tracking rules will still apply.
> > 
> > But they are inadequate for the map/set-domain scanout once and write
> > through the GTT for umpteen seconds, which can happen quite frequenctly.
> > 
> > In that situation, we behave exactly like fbdev/dumb fb.
> 
> Yeah you can use it to flush gtt of course too. And there I'd just
> defensively flush the entire fb until we've grown more clueful in the
> kernel. But for forntbuffer flushing I don't expect that to ever happen
> for i915. It makes more sense ofc for udl/qxl and others where uploads are
> really expensive.

Ha, I thought that MIPI was going off in this direction precisely
because high pixel count displays only transferring the dirty regions is
a big power saving. Likewise I expect at some point, there will be a
chipset mode to only portions of the framebuffer out of the chip local
cache across the bus.

I want to make sure we are not going to shoot ourselves in the foot and
can forward-proof the design so that we can easily detect if we want to
use cliprects.

An easy way would be to return the number of rectangles pushed by
dirtyfb i.e. if dirtyfb(fb, .num_rects=1)== 0 I know that it just pushes
the whole framebuffer everytime and need not track damage.

The ABI would be negative error return on failure, 0 or postive value on
success, where the positive value is the number of rects pushed (which
should be identical to the user request on success). Dumb users then
don't need to care as they can either always request full fb flushes or
always push rects.
-Chris
Paulo Zanoni July 2, 2015, 4:03 p.m. UTC | #6
2015-06-30 20:42 GMT-03:00 Rodrigo Vivi <rodrigo.vivi@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@ffwll.ch>
> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@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.

Also, don't forget that switching to intel_fb_obj_flush() will allow
you to kill the struct_mutex lock.

BTW, I'm also looking forward to see the IGT test suggested by Daniel :)

> +       mutex_unlock(&dev->struct_mutex);
> +
> +       return 0;
> +}
> +
>  static const struct drm_framebuffer_funcs intel_fb_funcs = {
>         .destroy = intel_user_framebuffer_destroy,
>         .create_handle = intel_user_framebuffer_create_handle,
> +       .dirty = intel_user_framebuffer_dirty,
>  };
>
>  static
> --
> 2.1.0
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Rodrigo Vivi July 2, 2015, 4:41 p.m. UTC | #7
On Thu, 2015-07-02 at 13:03 -0300, Paulo Zanoni wrote:
> 2015-06-30 20:42 GMT-03:00 Rodrigo Vivi <rodrigo.vivi@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@ffwll.ch>

> > Signed-off-by: Rodrigo Vivi <rodrigo.vivi@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.

> 

> Also, don't forget that switching to intel_fb_obj_flush() will allow

> you to kill the struct_mutex lock.

> 

> BTW, I'm also looking forward to see the IGT test suggested by Daniel :)

> 

> > +       mutex_unlock(&dev->struct_mutex);

> > +

> > +       return 0;

> > +}

> > +

> >  static const struct drm_framebuffer_funcs intel_fb_funcs = {

> >         .destroy = intel_user_framebuffer_destroy,

> >         .create_handle = intel_user_framebuffer_create_handle,

> > +       .dirty = intel_user_framebuffer_dirty,

> >  };

> >

> >  static

> > --

> > 2.1.0

> >

> > _______________________________________________

> > Intel-gfx mailing list

> > Intel-gfx@lists.freedesktop.org

> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx

> 

> 

>
Daniel Vetter July 3, 2015, 7:10 a.m. UTC | #8
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@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@ffwll.ch>
> > > Signed-off-by: Rodrigo Vivi <rodrigo.vivi@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.
-Daniel
Rodrigo Vivi July 6, 2015, 4:43 p.m. UTC | #9
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@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@ffwll.ch>

> > > > Signed-off-by: Rodrigo Vivi <rodrigo.vivi@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...


> -Daniel
Paulo Zanoni July 6, 2015, 5:11 p.m. UTC | #10
2015-07-06 13:43 GMT-03:00 Vivi, Rodrigo <rodrigo.vivi@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@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@ffwll.ch>
>> > > > Signed-off-by: Rodrigo Vivi <rodrigo.vivi@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?

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.

Also, we've been discussing a boot splash screen, and, according to
what you said, it's supposed to be using the dumb interfaces, right?
So I see that the dumb mmap is just a gem_mmap() to our driver. But
PSR is supposed to get disabled after GTT mmaps. Why is it not
disabled in this case? That is because we don't get the invalidate
call after the mmap, right? If we require an invalidate on the dirty
ioctl, it means that PSR is enabled even though it is GTT mmapped...
That's supposed to be wrong, right? Shouldn't the mmap IOCTL force an
invalidate?

>
>
>> -Daniel
>
Daniel Vetter July 6, 2015, 5:56 p.m. UTC | #11
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@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@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@ffwll.ch>
> >> > > > Signed-off-by: Rodrigo Vivi <rodrigo.vivi@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.

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.
 
> Also, we've been discussing a boot splash screen, and, according to
> what you said, it's supposed to be using the dumb interfaces, right?
> So I see that the dumb mmap is just a gem_mmap() to our driver. But
> PSR is supposed to get disabled after GTT mmaps. Why is it not
> disabled in this case? That is because we don't get the invalidate
> call after the mmap, right? If we require an invalidate on the dirty
> ioctl, it means that PSR is enabled even though it is GTT mmapped...
> That's supposed to be wrong, right? Shouldn't the mmap IOCTL force an
> invalidate?

Yeah dumb mmap users are supposed to call dirtyfb after each draw call.

i915 userspace could start doing the same to mark the gtt mmap invalidate
as done since we don't have any point where we stop it right now with an
i915 ioctl. And to be able to work together with set_domain(GTT) it really
needs to be a flush in ->dirty()
-Daniel
Rodrigo Vivi July 6, 2015, 11:19 p.m. UTC | #12
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@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@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@ffwll.ch>

> > >> > > > Signed-off-by: Rodrigo Vivi <rodrigo.vivi@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...


Thanks,
Rodrigo.
>  

> > Also, we've been discussing a boot splash screen, and, according to

> > what you said, it's supposed to be using the dumb interfaces, right?

> > So I see that the dumb mmap is just a gem_mmap() to our driver. But

> > PSR is supposed to get disabled after GTT mmaps. Why is it not

> > disabled in this case? That is because we don't get the invalidate

> > call after the mmap, right? If we require an invalidate on the dirty

> > ioctl, it means that PSR is enabled even though it is GTT mmapped...

> > That's supposed to be wrong, right? Shouldn't the mmap IOCTL force an

> > invalidate?

> 

> Yeah dumb mmap users are supposed to call dirtyfb after each draw call.

> 

> i915 userspace could start doing the same to mark the gtt mmap invalidate

> as done since we don't have any point where we stop it right now with an

> i915 ioctl. And to be able to work together with set_domain(GTT) it really

> needs to be a flush in ->dirty()

> -Daniel
Daniel Vetter July 7, 2015, 11:24 a.m. UTC | #13
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@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@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@ffwll.ch>
> > > >> > > > Signed-off-by: Rodrigo Vivi <rodrigo.vivi@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.

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 ...
-Daniel
Rodrigo Vivi July 7, 2015, 8:23 p.m. UTC | #14
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@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@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@ffwll.ch>

> > > > >> > > > Signed-off-by: Rodrigo Vivi <rodrigo.vivi@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
Daniel Vetter July 8, 2015, 9:05 a.m. UTC | #15
On Tue, Jul 07, 2015 at 08:23:46PM +0000, Vivi, Rodrigo wrote:
> 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@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@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@ffwll.ch>
> > > > > >> > > > Signed-off-by: Rodrigo Vivi <rodrigo.vivi@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

Oops I've accidentally broken this even worse with 

commit 031b698a77a70a6c394568034437b5486a44e868
Author: Daniel Vetter <daniel.vetter@ffwll.ch>
Date:   Fri Jun 26 19:35:16 2015 +0200

    drm/i915: Unconditionally do fb tracking invalidate in set_domain

This commit fixes this exact bug (already in gtt write domain), but
unfortunately only for the set_domain ioctl, not for fbcon.

We really just need an fb invalidate in there, no need for the if.

> 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

Excellent catch, we definitely need that one too.
-Daniel

> 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
>
diff mbox

Patch

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)
+{
+	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);
+	mutex_unlock(&dev->struct_mutex);
+
+	return 0;
+}
+
 static const struct drm_framebuffer_funcs intel_fb_funcs = {
 	.destroy = intel_user_framebuffer_destroy,
 	.create_handle = intel_user_framebuffer_create_handle,
+	.dirty = intel_user_framebuffer_dirty,
 };
 
 static