[platforms/drm] At safety checks for the properties
ClosedPublic

Authored by graesslin on Nov 10 2017, 7:40 PM.

Details

Summary

The AMS code accesses elements in a vector which might not be valid. This
change refactors the code to be more robust, especially the DrmPlane,
which started to crash after adding transformation support.

BUG: 386490

Diff Detail

Repository
R108 KWin
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.
graesslin created this revision.Nov 10 2017, 7:40 PM
Restricted Application added a project: KWin. · View Herald TranscriptNov 10 2017, 7:40 PM
Restricted Application added subscribers: kwin, plasma-devel. · View Herald Transcript
fvogt accepted this revision.Nov 11 2017, 10:48 AM

I tried this patch and kwin still crashes in QEMU, but at a different place now at least:

#0  KWin::DrmOutput::pixelSize (this=0x0) at /usr/src/debug/kwin-5.11.90git.20171108T174438~9df174483/plugins/platforms/drm/drm_output.cpp:162
#1  0x00007fffdcccfca9 in KWin::DrmCrtc::blank (this=0x555555889a10)
    at /usr/src/debug/kwin-5.11.90git.20171108T174438~9df174483/plugins/platforms/drm/drm_object_crtc.cpp:85
#2  0x00007fffdccd1398 in KWin::DrmOutput::~DrmOutput (this=0x555555843240, __in_chrg=<optimized out>)
    at /usr/src/debug/kwin-5.11.90git.20171108T174438~9df174483/plugins/platforms/drm/drm_output.cpp:68
#3  0x00007fffdccd1699 in KWin::DrmOutput::~DrmOutput (this=0x555555843240, __in_chrg=<optimized out>)
    at /usr/src/debug/kwin-5.11.90git.20171108T174438~9df174483/plugins/platforms/drm/drm_output.cpp:87
#4  0x00007fffdccc9912 in KWin::DrmBackend::updateOutputs (this=this@entry=0x5555557cb500)
    at /usr/src/debug/kwin-5.11.90git.20171108T174438~9df174483/plugins/platforms/drm/drm_backend.cpp:460
#5  0x00007fffdccca81d in KWin::DrmBackend::openDrm (this=0x5555557cb500)
    at /usr/src/debug/kwin-5.11.90git.20171108T174438~9df174483/plugins/platforms/drm/drm_backend.cpp:326
#6  0x00007ffff5a0ffec in QMetaObject::activate(QObject*, int, int, void**) () from /usr/lib64/libQt5Core.so.5
#7  0x00007ffff7b1c9e2 in KWin::LogindIntegration::hasSessionControlChanged (this=<optimized out>, _t1=<optimized out>, _t1@entry=true)
    at /usr/src/debug/kwin-5.11.90git.20171108T174438~9df174483/build/kwin_autogen/EWIEGA46WW/moc_logind.cpp:188

At this point export KWIN_DRM_NO_AMS=1 helps though and the session starts up. Unfortunately kwin_wayland gives up just after these messages:

kscreen.kwayland: Loading Wayland backend.
kscreen.kded: PowerDevil SuspendSession action not available!
kscreen.kwayland: Loading Wayland backend.
kwin_wayland: Couldn't find current GLX or EGL context.

and crashes somewhere in the destructors of Qt's global objects.

This revision is now accepted and ready to land.Nov 11 2017, 10:48 AM
graesslin updated this revision to Diff 22186.Nov 11 2017, 12:15 PM

Prevent the new reported crash

Restricted Application edited projects, added Plasma; removed KWin. · View Herald TranscriptNov 11 2017, 12:15 PM
fvogt accepted this revision.Nov 11 2017, 2:19 PM

Works. Instead of crashing I now get:

kwin_wayland_drm: Failed to initialize primary plane.
FATAL ERROR: backend failed to initialize, exiting now

BTW: There's a typo in the title.

fvogt added a comment.Nov 11 2017, 3:44 PM

Not quite sure whether it's related to this change, but I tried to debug the failure to init the primary plane and found this:

kwin_wayland_drm: Using Atomic Mode Setting.
kwin_wayland_drm: Number of planes: 2
kwin_wayland_drm: Atomic init for plane: 26
kwin_wayland_drm: 26: type' (id 6): 1
kwin_wayland_drm: "type"  has enums: QVector("Primary", "Cursor", "Overlay")
kwin_wayland_drm: Test all 3 possible enums:
kwin_wayland_drm: Enum 'Overlay': runtime-value = 0
kwin_wayland_drm: Enum 'Primary': runtime-value = 1
kwin_wayland_drm: Enum 'Cursor': runtime-value = 2
kwin_wayland_drm: => "type" with mapped enum value "Primary"
[...]
kwin_wayland_drm: Atomic init for plane: 27
kwin_wayland_drm: 27: type' (id 6): 2
kwin_wayland_drm: "type"  has enums: QVector("Primary", "Cursor", "Overlay")
kwin_wayland_drm: Test all 3 possible enums:
kwin_wayland_drm: Enum 'Overlay': runtime-value = 0
kwin_wayland_drm: Enum 'Primary': runtime-value = 1
kwin_wayland_drm: Enum 'Cursor': runtime-value = 2
kwin_wayland_drm: => "type" with mapped enum value "Cursor"

But then in initPrimaryPlane it is unable to find any plane with type == Primary.
If I set a breakpoint on KWin::DrmPlane::type(), every single call returns ::Overlay as m_props[0] is nullptr.

graesslin updated this revision to Diff 22200.Nov 11 2017, 6:43 PM

Fix stupid mistake, now starting should work again

Restricted Application edited projects, added KWin; removed Plasma. · View Herald TranscriptNov 11 2017, 6:43 PM
fvogt added a comment.Nov 11 2017, 8:25 PM

Ok, now both AMS and no-AMS cases result in the same crash.
libepoxy terminates kwin_wayland due to Couldn't find current GLX or EGL context:

#0  0x00007ffff4ee3260 in errx () from /lib64/libc.so.6
#1  0x00007ffff0c32c8c in ?? () from /usr/lib64/libepoxy.so.0
#2  0x00007ffff0c15d2d in ?? () from /usr/lib64/libepoxy.so.0
#3  0x00007ffff4b9fafa in KWin::ContrastShader::reset (this=this@entry=0x7fffb804c530)
    at /usr/src/debug/kwin-5.11.90git.20171111T192901~320602ae1/effects/backgroundcontrast/contrastshader.cpp:53
#4  0x00007ffff4b9fb43 in KWin::ContrastShader::~ContrastShader (this=0x7fffb804c530, __in_chrg=<optimized out>)
    at /usr/src/debug/kwin-5.11.90git.20171111T192901~320602ae1/effects/backgroundcontrast/contrastshader.cpp:43
#5  KWin::ContrastShader::~ContrastShader (this=0x7fffb804c530, __in_chrg=<optimized out>)
    at /usr/src/debug/kwin-5.11.90git.20171111T192901~320602ae1/effects/backgroundcontrast/contrastshader.cpp:44
#6  0x00007ffff4b9c581 in KWin::ContrastEffect::~ContrastEffect (this=0x5555562795a0, __in_chrg=<optimized out>)
    at /usr/src/debug/kwin-5.11.90git.20171111T192901~320602ae1/effects/backgroundcontrast/contrast.cpp:77
#7  0x00007ffff4b9c619 in KWin::ContrastEffect::~ContrastEffect (this=0x5555562795a0, __in_chrg=<optimized out>)
    at /usr/src/debug/kwin-5.11.90git.20171111T192901~320602ae1/effects/backgroundcontrast/contrast.cpp:78
#8  0x00007ffff7a7888b in KWin::EffectsHandlerImpl::unloadEffect (this=this@entry=0x555556153120, name=...)
    at /usr/src/debug/kwin-5.11.90git.20171111T192901~320602ae1/effects.cpp:1343
#9  0x00007ffff7a78b77 in KWin::EffectsHandlerImpl::reloadEffect (this=0x555556153120, effect=<optimized out>)
    at /usr/src/debug/kwin-5.11.90git.20171111T192901~320602ae1/effects.cpp:1410
#10 0x00007ffff4b9e6af in KWin::ContrastEffect::slotScreenGeometryChanged (this=0x5555562795a0)
    at /usr/src/debug/kwin-5.11.90git.20171111T192901~320602ae1/effects/backgroundcontrast/contrast.cpp:84
#11 0x00007ffff5a0feea in QMetaObject::activate(QObject*, int, int, void**) () from /usr/lib64/libQt5Core.so.5
#12 0x00007ffff74d4635 in KWin::EffectsHandler::screenGeometryChanged (this=<optimized out>, _t1=...)
    at /usr/src/debug/kwin-5.11.90git.20171111T192901~320602ae1/build/libkwineffects/kwineffects_autogen/EWIEGA46WW/moc_kwineffects.cpp:1555
#13 0x00007ffff7a71d2d in KWin::EffectsHandlerImpl::desktopResized (this=<optimized out>, size=...)
    at /usr/src/debug/kwin-5.11.90git.20171111T192901~320602ae1/effects.cpp:785
#14 0x00007ffff7a460c9 in KWin::Workspace::desktopResized (this=0x5555558f2ff0) at /usr/src/debug/kwin-5.11.90git.20171111T192901~320602ae1/geometry.cpp:87
#15 0x00007ffff5a0feea in QMetaObject::activate(QObject*, int, int, void**) () from /usr/lib64/libQt5Core.so.5
#16 0x00007fffdccc805c in KWin::DrmBackend::configurationChangeRequested (this=0x5555557c4dd0, config=0x555556181030)
    at /usr/src/debug/kwin-5.11.90git.20171111T192901~320602ae1/plugins/platforms/drm/drm_backend.cpp:534
#17 0x00007ffff5a0ffec in QMetaObject::activate(QObject*, int, int, void**) () from /usr/lib64/libQt5Core.so.5
#18 0x00007ffff6e11a9f in KWayland::Server::OutputManagementInterface::configurationChangeRequested(KWayland::Server::OutputConfigurationInterface*) ()
   from /usr/lib64/libKF5WaylandServer.so.5
#19 0x00007fffe73cf6bd in ?? () from /usr/lib64/libffi.so.7
#20 0x00007fffe73cebcf in ?? () from /usr/lib64/libffi.so.7
#21 0x00007fffede090ab in ?? () from /usr/lib64/libwayland-server.so.0
#22 0x00007fffede058ef in ?? () from /usr/lib64/libwayland-server.so.0
#23 0x00007fffede07282 in wl_event_loop_dispatch () from /usr/lib64/libwayland-server.so.0
#24 0x00007ffff6dd652e in KWayland::Server::Display::Private::dispatch() () from /usr/lib64/libKF5WaylandServer.so.5

and kwin_wayland doesn't handle the call to exit well as it crashes during global object destruction:

#0  0x00007fffd67abcf0 in ?? ()
#1  0x00007fffdccdf29b in KWin::DrmSurfaceBuffer::releaseGbm (this=0x5555560c2280)
    at /usr/src/debug/kwin-5.11.90git.20171111T192901~320602ae1/plugins/platforms/drm/drm_buffer_gbm.cpp:64
#2  KWin::DrmSurfaceBuffer::~DrmSurfaceBuffer (this=0x5555560c2280, __in_chrg=<optimized out>)
    at /usr/src/debug/kwin-5.11.90git.20171111T192901~320602ae1/plugins/platforms/drm/drm_buffer_gbm.cpp:59
#3  0x00007fffdccdf379 in KWin::DrmSurfaceBuffer::~DrmSurfaceBuffer (this=0x5555560c2280, __in_chrg=<optimized out>)
    at /usr/src/debug/kwin-5.11.90git.20171111T192901~320602ae1/plugins/platforms/drm/drm_buffer_gbm.cpp:60
#4  0x00007fffdccd160b in KWin::DrmOutput::~DrmOutput (this=0x555555899eb0, __in_chrg=<optimized out>)
    at /usr/src/debug/kwin-5.11.90git.20171111T192901~320602ae1/plugins/platforms/drm/drm_output.cpp:75
#5  0x00007fffdccd1679 in KWin::DrmOutput::~DrmOutput (this=0x555555899eb0, __in_chrg=<optimized out>)
    at /usr/src/debug/kwin-5.11.90git.20171111T192901~320602ae1/plugins/platforms/drm/drm_output.cpp:87
#6  0x00007fffdccc704f in qDeleteAll<KWin::DrmOutput* const*> (end=<optimized out>, begin=0x5555558bb388) at /usr/include/qt5/QtCore/qalgorithms.h:320
#7  qDeleteAll<QVector<KWin::DrmOutput*> > (c=...) at /usr/include/qt5/QtCore/qalgorithms.h:328
#8  KWin::DrmBackend::~DrmBackend (this=0x5555557c4f00, __in_chrg=<optimized out>)
    at /usr/src/debug/kwin-5.11.90git.20171111T192901~320602ae1/plugins/platforms/drm/drm_backend.cpp:91
#9  0x00007fffdccc7319 in KWin::DrmBackend::~DrmBackend (this=0x5555557c4f00, __in_chrg=<optimized out>)
    at /usr/src/debug/kwin-5.11.90git.20171111T192901~320602ae1/plugins/platforms/drm/drm_backend.cpp:97

I found a workaround for the no GLX or EGL context crash: rm /usr/lib64/qt5/plugins/kf5/kded/kscreen.so + this patch results in a working wayland session in QEMU again.

In combination that looks like kscreen sends a request to KWin which is stupid. Resulting in KWin losing the OpenGL context and then epoxy crashing. So we have two problems here: one being the incorrect request from KScreen, the other the fact that KWin ends up with no context. Anyway looks to me like I can push at least this patch as it improves the situation.

Ok, I figured out why the context is not current any more. We seem to get a mode change request from KScreen, which results in the DRMBackend updating a screen, the EGLBackend recreates the EGLSurface but didn't pass it to the parent class which tried to make a context current on the no longer existing surface. Thus making the context current failed. Uploading new patch.

graesslin updated this revision to Diff 22208.Nov 12 2017, 7:47 AM

Update the eglsurface in AbstractEglBackend if it changed

Restricted Application edited projects, added Plasma; removed KWin. · View Herald TranscriptNov 12 2017, 7:47 AM
fvogt added a comment.Nov 12 2017, 8:57 PM

Works, plasma starts fine OOTB now!
However:

  1. KScreen configures a way too high resolution (1920x1080 instead of 1024x768 like on X
  2. On virtio, the screen freezes completely and not even switching back to consoles works before killing kwin_wayland
  3. On qxl, the screen flashes in a way that could probably induce seizures in non-living objects

I don't remember seeing any of those issues before AMS got added.
Only issue 1 disappears with KWIN_DRM_NO_AMS=1.

In D8752#166896, @fvogt wrote:

I don't remember seeing any of those issues before AMS got added.
Only issue 1 disappears with KWIN_DRM_NO_AMS=1.

The problem is not ams, but that KWin learned how to change resolution when kscreen requests it. So the question is why does kscreen request a wrong resolution? @sebas any ideas?

This revision was automatically updated to reflect the committed changes.