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] ); 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 ); w->fb_id = drm_fbid_from_dmabuf( &g_DRM, &w->dmabuf_attribs );
assert( w->fb_id != 0 ); assert( w->fb_id != 0 );
@ -779,18 +786,10 @@ paint_all (Display *dpy)
if (drawDebugInfo) if (drawDebugInfo)
paint_debug_info(dpy); paint_debug_info(dpy);
for ( int i = 0; i < k_nMaxLayers; i++ ) if ( BIsNested() == false )
{ {
bool bHasSeenZero = false; if ( pipeline.layerBindings[ 0 ].fbid == 0 )
if ( pipeline.layerBindings[ i ].tex == 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; 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 // Existing data here hasn't been consumed - need to consume the dma-buf fd
close(w->dmabuf_attribs.fd[0]); close(w->dmabuf_attribs.fd[0]);
} }
assert( newEntry.attribs.fd[0] != -1 );
w->dmabuf_attribs = newEntry.attribs; w->dmabuf_attribs = newEntry.attribs;
w->dmabuf_attribs_valid = True; 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; bool result = False;
result = wlr_texture_to_dmabuf( tex, &dmabuf_attribs ); 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 ); gpuvis_trace_printf( "xwayland_surface_role_commit wlr_surface %p\n", wlr_surface );