wlserver: anti-fd exhaustion measures.

If we only take the first commit, we leave a bunch in the queue, which
makes us that much more likely to run out of FDs when importing the
myriad of buffer referenced coming from a non-vsynced client. Fixes
crashes with vblank_mode=0 glxgears after the recent changes.

We were always subject to such crashes, just getting lucky/fast before.
This commit is contained in:
Pierre-Loup A. Griffais 2020-01-13 22:09:55 -08:00
parent fb49601138
commit 901103af3f
2 changed files with 19 additions and 12 deletions

View file

@ -350,6 +350,13 @@ ensure_win_resources (Display *dpy, win *w)
int fdCopy = dup( w->dmabuf_attribs.fd[0] );
if ( fdCopy == -1 )
{
w->dmabuf_attribs_valid = False;
close( w->dmabuf_attribs.fd[0] );
return;
}
w->fb_id = drm_fbid_from_dmabuf( &g_DRM, &w->dmabuf_attribs );
assert( w->fb_id != 0 );
@ -779,18 +786,10 @@ paint_all (Display *dpy)
if (drawDebugInfo)
paint_debug_info(dpy);
for ( int i = 0; i < k_nMaxLayers; i++ )
if ( BIsNested() == false )
{
bool bHasSeenZero = false;
if ( pipeline.layerBindings[ i ].tex == 0 )
if ( pipeline.layerBindings[ 0 ].fbid == 0 )
{
bHasSeenZero = true;
}
else if ( bHasSeenZero == true )
{
// We have a hole in this binding that will cause GPU crashes.
// TODO write compacting code here
return;
}
}
@ -1635,6 +1634,9 @@ void check_new_wayland_res(void)
// Existing data here hasn't been consumed - need to consume the dma-buf fd
close(w->dmabuf_attribs.fd[0]);
}
assert( newEntry.attribs.fd[0] != -1 );
w->dmabuf_attribs = newEntry.attribs;
w->dmabuf_attribs_valid = True;

View file

@ -67,9 +67,14 @@ static void xwayland_surface_role_commit(struct wlr_surface *wlr_surface) {
bool result = False;
result = wlr_texture_to_dmabuf( tex, &dmabuf_attribs );
if (result == False)
assert( result == true );
if ( result == false || dmabuf_attribs.fd[0] == -1 )
{
//
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
wlr_surface_send_frame_done( wlr_surface, &now );
return;
}
gpuvis_trace_printf( "xwayland_surface_role_commit wlr_surface %p\n", wlr_surface );