Plymouth flicker-free shutdown side-effect

João Paulo Rechi Vita jprvita at gmail.com
Tue Jan 8 03:17:13 UTC 2019


Hello Hans!

On Thu, Jan 3, 2019 at 6:32 AM Hans de Goede <hdegoede at redhat.com> wrote:
>
> Hello João,
>
> On 01-01-19 02:08, João Paulo Rechi Vita wrote:
> > Hello Hans,
> >
> > Firstly, thanks for your flicker-free boot work, it is really nice to
> > finally see a completely smooth boot process on the Linux desktop.
> >
> > I've been integrating your work on Endless, where we do not want to
> > show the BGRT graphics for the entirety of the boot process, but use a
> > fully Endless-branded splash animation instead.
>
> Interesting have you seen my recent work on integration the BGRT
> with plymouth for reporting some sort of process:
> https://hansdegoede.livejournal.com/19673.html
>
> This is still under development and doing a fade-over into something
> without the vendor branding has been considered, can you (privately)
> share a video of what your boot looks like? And have you added code
> to plymouth to do a fade-over in this case, or is the transition
> from the BGRT screen to the endless branded screen done in a single
> frame update?
>

Yes, I've seen your BGRT theme and even got it running on Endless at
some point. It looks very smooth, but as I mentioned we are going for
a Endless-only branding experience as much as possible.

We are not doing any sort of fade-over, but simply starting our
regular splash animation (based on two-step with a few modifications,
as we don't implement any progress support and simply show the end
animation at zero percent) in a single frame update.  That said, the
idea of starting from the BGRT frame and cross-fading into something
else is actually pretty great.

I've uploaded two videos of how things look like at the moment (with
autologin enabled, which is not the default setting but is what I had
when I shot the videos some time ago):

1. during boot: https://vimeo.com/309563224
2. during shutdown: https://vimeo.com/309564189

> > With your kernel
> > changes to have fbcon defer its setup, have efifb copy the BGRT
> > graphics to the framebuffer, the flicker-free changes to grub, shim
> > and Plymouth, and and passing i915.fastboot=1 on the kernel command
> > line, I'm able to have a 100% flicker-free boot process.
> >
> > That being said these also bring a side-effect that makes the shutdown
> > process very unpleasant. After X is shut down the BGRT logo will be
> > displayed for a moment, then the shutdown splash will be shown, and
> > finally the BGRT logo will be displayed for a moment again before the
> > machine powers off. Before the flicker-free changes, this would be a
> > clblack text console with a blinking cursor on the first character
> > position, but with these changes the console was never setup and the
> > BGRT logo is still on the TTY frame buffer.
>
> Right, so the problem here is that the i915 driver needs *some* framebuffer
> to scanout, so here is what is happening:
>
> Phase 1: Firmware / grub: Firmware displays its splash, grub leaves everything alone
>
> Phase 2: EFIFB: EFIFB rebuilds firmware splash from BGRT ACPI table in case something hosed it,
> also some firmwares do not show the BGRT themselves at all (also dependend on fastboot settings)
>
> Phase 3: i915 driver takes over, with a recent kernel it will re-use the framebuffer set
> up by the firmware (GOP) and it will preserve its contents. This framebuffer is kept around
> by i915 as a fallback framebuffer
>
> Phase 4: Plymouth loads installs its own framebuffer
>
> Phase 5: Plymouth - gdm (*) transition step 1, plymouth is told to stop, but not exit before
> gdm starts, on stop plymouth drops its master rights, but its framebuffer is still in
> use and will be used until another one is installed; *or* plymouth closed the drm fd
> (or exits).
>
> Phase 6: Plymouth - gdm transition step 2, gdm installs its own framebuffer then
> tell plymouth it is ok to quit now.
>
> Phase 7: gdm -> user session transition. This works the same as plymouth -> gdm, gdm
> drops its master rights, but keeps the framebuffer around to allow for a smooth transition
> this is currently done based on a timeout since user-sessions have no way to signal gdm
> that they have installed their own framebuffer.
>
> Phase 8: User session runs using its own framebuffer(s)
>
> Phase 9: Shutdown step 1: The user session exits, without doing anything to guarantee a
> smooth transition. The i915 driver now looses the framebuffer it is scanning out and
> falls back to the framebuffer it inherited from the firmware/GOP, which contains the BGRT
> logo. This is the first BGRT flash you are seeing
>
> Phase 10: Shutdown step 2: plymouth takes over, installs its own framebuffer.
>
> Phase 11: Shutdown complete, ready to reboot. Plymouth gets killed just before, releasing
> its framebuffer, i915 again goes to the fallback framebuffer (it has to scan out something)
> this is the second BGRT flash you are seeing
>
> I hope this helps explain what you are seeing. There is another issue, at least when
> using gdm from GNOME-3.30 or newer. The latest GDM kills the greeter-session when the
> user-session has started to free up about 300M of RAM. But if the user now logs out,
> then gdm needs some time to restart leading to an experience similar to the shutdown
> (on the switch to VT1 the BGRT logo will show until the greeter starts).
>
> This is why for now I've chosen to integrate the BGRT logo into the plymouth theme,
> then all these transitions become smooth since on shutdown we go:
> user-fb -> fallback-fb -> plymouth-fb -> fallback-fb
> and both the fallback-fb and plymouth-fb have the BGRT on them so the transition
> looks smooth.  Also keeping the BGRT logo around until just before gdm starts
> makes it showing again when loging out seem normal.
>
> Note that using the BGRT is a workaround and you could dd the endless splash screen
> to the fb somewhere during boot to do a similar workaround for your problem.
>

Thanks for such a detailed explanation. I had been able to figure out
parts of the whole picture, but I had not realized the fallback
framebuffer behavior in i915 -- I thought we were switching back to
efifb somehow.

And now that you mentioned the GDM problem I realized we are hitting
it as well, even though we are not based on GDM 3.30, but 3.26.2.1.
But we have it setup to not keep the greeter around, so the BGRT logo
is shown until the greeter starts again. This invalidates my
workaround of dd'ing something to /dev/fb0 on gdm.service's ExecStop.

> But there is a proper way to fix this, which is to allow applications to
> unref a framebuffer rather then removing it. In this case the kernel would no
> longer accept the framebuffer handle from userspace (and untie it from the drm fd)
> but keep it around until a new framebuffer is installed. This would also avoid the
> need for the complex stop plymouth, wait for gdm to install new fb, exit plymouth
> shenanigans we need to do atm.
>
> Rob Clark has written a patch for this, but it did not get merged since there were
> no immediate userspace uses for it back when this was first submitted:
>
> https://www.spinics.net/lists/dri-devel/msg140912.html
>
> I believe now would be a good time to dust-off this patch and to teach mutter
> to call the unref ioctl on the last shown framebuffer when it exits, so that
> that stays around until something else installs a new framebuffer.
>

Yes, that seems like the way to go moving forward, and reading the
discussion there also helped clear up how this whole things works. But
since having this new API in the kernel and then updating all the
different clients to use the new API will take some time, I'm still
trying to come up with a workaround.

In addition to what I had mentioned previously (calling dd from GDM's
stop routine or clearing efifb's fb), I've also tried to keep track of
the fb device associated with the drm card used by Plymouth's drm
plugin, and clearing it by shamelessly writing zeros to the fbdev when
the plugin is activated, right after the loop the sets scan-out
buffers on all the heads. But in addition to being super hackish, that
didn't really work on my quick attempt, so I'm leaving that option
aside.

Alternatively, I started looking at having a clear framebuffer to use
as a fallback in i915. Clearing the buffer on probe is the easy
solution, but it introduces a black screen in the boot process again,
although this time for a much shorter period than doing it in efifb.
Also, the clearing appears to happen when the display is modesetting
when i915.fastboot=0, so we only really see it for a very short period
after the screen is back on before Plymouth's splash takes over.
Unless you have a better suggestion (as it would be nice to be able to
set i915.fastboot=1 at least on specific hw where we test and know it
does not cause problems), I'll probably carry that workaround
downstream until a better solution is merged upstream.

I've also investigated clearing the fallback framebuffer when
DRM_IOCTL_MODE_SETCRTC gets called for the first time, but I'm not
familiar enough with DRM to figure that out.

> Regards,
>
> Hans
>
>
>
> *) I know Endless is (was?) not using gdm, not sure how this works for you

We are using GDM, what we are not using yet is Wayland.. Still on the
old X.org for now.

Thanks again for the throughout explanation,

Best regards,



--
João Paulo Rechi Vita
http://about.me/jprvita


More information about the plymouth mailing list