[Mesa-dev] Bug#651370: libgl1-mesa-glx: need close on exec for dri device

Michel Dänzer daenzer at debian.org
Thu Dec 8 01:06:20 PST 2011


On Mit, 2011-12-07 at 23:43 -0600, David Fries wrote: 
> Package: libgl1-mesa-glx
> 
> Version: 7.11-6
> Severity: normal
> Tags: patch
> 
> When dri is used the character device /dev/dri/card0 is opened.  That
> file descriptor should be set with the close on exec file as currently
> those resources are not released until it is closed, and exec causes
> those resources to be leaked until the process terminates.  This was
> an extra problem for the program I'm working with as it will exec
> itself to start fresh and change modes, but will tie up additional
> OpenGL resources each time it does so.
> 
> Here's a patch that will open it with O_CLOEXEC if available or set
> the FD_CLOEXEC flag otherwise.  It almost seems like there should be a
> common function such as open_wr_cloexec that will make sure and set
> the flag, but I didn't see an appropriate header file to put it in.

Can you create a patch against upstream Git with git format-patch and
send it to the mesa-dev mailing list (CC'd) for review?


> diff -upr /tmp/mesa-7.11/src/egl/drivers/dri2/platform_wayland.c mesa-7.11/src/egl/drivers/dri2/platform_wayland.c
> --- /tmp/mesa-7.11/src/egl/drivers/dri2/platform_wayland.c	2011-07-08 20:37:09.000000000 -0500
> +++ mesa-7.11/src/egl/drivers/dri2/platform_wayland.c	2011-12-07 21:28:10.000000000 -0600
> @@ -734,17 +734,25 @@ drm_handle_device(void *data, struct wl_
>  {
>     struct dri2_egl_display *dri2_dpy = data;
>     drm_magic_t magic;
> +#ifdef O_CLOEXEC
> +   int flags = O_RDWR | O_CLOEXEC;
> +#else
> +   int flags = O_RDWR;
> +#endif
>  
>     dri2_dpy->device_name = strdup(device);
>     if (!dri2_dpy->device_name)
>        return;
>  
> -   dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR);
> +   dri2_dpy->fd = open(dri2_dpy->device_name, flags);
>     if (dri2_dpy->fd == -1) {
>        _eglLog(_EGL_WARNING, "wayland-egl: could not open %s (%s)",
>  	      dri2_dpy->device_name, strerror(errno));
>        return;
>     }
> +#ifndef O_CLOEXEC
> +   fcntl(dri2_dpy->fd, F_SETFD, fcntl(dri2_dpy->fd, F_GETFD) | FD_CLOEXEC);
> +#endif
>  
>     drmGetMagic(dri2_dpy->fd, &magic);
>     wl_drm_authenticate(dri2_dpy->wl_drm, magic);
> diff -upr /tmp/mesa-7.11/src/egl/drivers/dri2/platform_x11.c mesa-7.11/src/egl/drivers/dri2/platform_x11.c
> --- /tmp/mesa-7.11/src/egl/drivers/dri2/platform_x11.c	2011-12-07 20:53:39.000000000 -0600
> +++ mesa-7.11/src/egl/drivers/dri2/platform_x11.c	2011-12-07 21:28:09.000000000 -0600
> @@ -961,6 +961,11 @@ static EGLBoolean
>  dri2_initialize_x11_dri2(_EGLDriver *drv, _EGLDisplay *disp)
>  {
>     struct dri2_egl_display *dri2_dpy;
> +#ifdef O_CLOEXEC
> +   int flags = O_RDWR | O_CLOEXEC;
> +#else
> +   int flags = O_RDWR;
> +#endif
>  
>     drv->API.CreateWindowSurface = dri2_create_window_surface;
>     drv->API.CreatePixmapSurface = dri2_create_pixmap_surface;
> @@ -997,19 +1002,16 @@ dri2_initialize_x11_dri2(_EGLDriver *drv
>     if (!dri2_load_driver(disp))
>        goto cleanup_conn;
>  
> -#ifdef O_CLOEXEC
> -   dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR | O_CLOEXEC);
> -#else
> -   dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR);
> -   if (dri2_dpy->fd >= 0)
> -      fcntl(dri2_dpy->fd, F_SETFD, fcntl(dri2_dpy->fd, F_GETFD) | FD_CLOEXEC);
> -#endif
> +   dri2_dpy->fd = open(dri2_dpy->device_name, flags);
>     if (dri2_dpy->fd == -1) {
>        _eglLog(_EGL_WARNING,
>  	      "DRI2: could not open %s (%s)", dri2_dpy->device_name,
>                strerror(errno));
>        goto cleanup_driver;
>     }
> +#ifndef O_CLOEXEC
> +   fcntl(dri2_dpy->fd, F_SETFD, fcntl(dri2_dpy->fd, F_GETFD) | FD_CLOEXEC);
> +#endif
>  
>     if (dri2_dpy->conn) {
>        if (!dri2_authenticate(disp))
> diff -upr /tmp/mesa-7.11/src/gallium/state_trackers/egl/drm/native_drm.c mesa-7.11/src/gallium/state_trackers/egl/drm/native_drm.c
> --- /tmp/mesa-7.11/src/gallium/state_trackers/egl/drm/native_drm.c	2011-07-14 12:42:59.000000000 -0500
> +++ mesa-7.11/src/gallium/state_trackers/egl/drm/native_drm.c	2011-12-07 21:28:09.000000000 -0600
> @@ -302,11 +302,20 @@ native_create_display(void *dpy, boolean
>  {
>     struct gbm_gallium_drm_device *gbm;
>     int fd;
> +#ifdef O_CLOEXEC
> +   int flags = O_RDWR | O_CLOEXEC;
> +#else
> +   int flags = O_RDWR;
> +#endif
>  
>     gbm = dpy;
>  
>     if (gbm == NULL) {
> -      fd = open("/dev/dri/card0", O_RDWR);
> +      fd = open("/dev/dri/card0", flags);
> +#ifndef O_CLOEXEC
> +      if (fd != -1)
> +         fcntl(fd, F_SETFD, fcntl(dri2_dpy->fd, F_GETFD) | FD_CLOEXEC);
> +#endif
>        gbm = gbm_gallium_drm_device(gbm_create_device(fd));
>     }
>  
> diff -upr /tmp/mesa-7.11/src/gallium/state_trackers/egl/fbdev/native_fbdev.c mesa-7.11/src/gallium/state_trackers/egl/fbdev/native_fbdev.c
> --- /tmp/mesa-7.11/src/gallium/state_trackers/egl/fbdev/native_fbdev.c	2011-07-08 20:37:09.000000000 -0500
> +++ mesa-7.11/src/gallium/state_trackers/egl/fbdev/native_fbdev.c	2011-12-07 21:28:09.000000000 -0600
> @@ -514,16 +514,24 @@ native_create_display(void *dpy, boolean
>  {
>     struct native_display *ndpy;
>     int fd;
> +#ifdef O_CLOEXEC
> +   int flags = O_RDWR | O_CLOEXEC;
> +#else
> +   int flags = O_RDWR;
> +#endif
>  
>     /* well, this makes fd 0 being ignored */
>     if (!dpy) {
> -      fd = open("/dev/fb0", O_RDWR);
> +      fd = open("/dev/fb0", flags);
>     }
>     else {
>        fd = dup((int) pointer_to_intptr(dpy));
>     }
>     if (fd < 0)
>        return NULL;
> +#ifndef O_CLOEXEC
> +   fcntl(fd, F_SETFD, fcntl(dri2_dpy->fd, F_GETFD) | FD_CLOEXEC);
> +#endif
>  
>     ndpy = fbdev_display_create(fd, fbdev_event_handler);
>     if (!ndpy)
> diff -upr /tmp/mesa-7.11/src/gallium/state_trackers/egl/wayland/native_drm.c mesa-7.11/src/gallium/state_trackers/egl/wayland/native_drm.c
> --- /tmp/mesa-7.11/src/gallium/state_trackers/egl/wayland/native_drm.c	2011-07-08 20:37:09.000000000 -0500
> +++ mesa-7.11/src/gallium/state_trackers/egl/wayland/native_drm.c	2011-12-07 21:28:09.000000000 -0600
> @@ -146,17 +146,25 @@ drm_handle_device(void *data, struct wl_
>  {
>     struct wayland_drm_display *drmdpy = data;
>     drm_magic_t magic;
> +#ifdef O_CLOEXEC
> +   int flags = O_RDWR | O_CLOEXEC;
> +#else
> +   int flags = O_RDWR;
> +#endif
>  
>     drmdpy->device_name = strdup(device);
>     if (!drmdpy->device_name)
>        return;
>  
> -   drmdpy->fd = open(drmdpy->device_name, O_RDWR);
> +   drmdpy->fd = open(drmdpy->device_name, flags);
>     if (drmdpy->fd == -1) {
>        _eglLog(_EGL_WARNING, "wayland-egl: could not open %s (%s)",
>                drmdpy->device_name, strerror(errno));
>        return;
>     }
> +#ifndef O_CLOEXEC
> +   fcntl(drmdpy->fd, F_SETFD, fcntl(dri2_dpy->fd, F_GETFD) | FD_CLOEXEC);
> +#endif
>  
>     drmGetMagic(drmdpy->fd, &magic);
>     wl_drm_authenticate(drmdpy->wl_drm, magic);
> diff -upr /tmp/mesa-7.11/src/gallium/state_trackers/egl/x11/x11_screen.c mesa-7.11/src/gallium/state_trackers/egl/x11/x11_screen.c
> --- /tmp/mesa-7.11/src/gallium/state_trackers/egl/x11/x11_screen.c	2011-07-08 20:37:09.000000000 -0500
> +++ mesa-7.11/src/gallium/state_trackers/egl/x11/x11_screen.c	2011-12-07 21:28:09.000000000 -0600
> @@ -260,16 +260,24 @@ x11_screen_enable_dri2(struct x11_screen
>     if (xscr->dri_fd < 0) {
>        int fd;
>        drm_magic_t magic;
> +#ifdef O_CLOEXEC
> +      int flags = O_RDWR | O_CLOEXEC;
> +#else
> +      int flags = O_RDWR;
> +#endif
>  
>        /* get the driver name and the device name first */
>        if (!x11_screen_probe_dri2(xscr, NULL, NULL))
>           return -1;
>  
> -      fd = open(xscr->dri_device, O_RDWR);
> +      fd = open(xscr->dri_device, flags);
>        if (fd < 0) {
>           _eglLog(_EGL_WARNING, "failed to open %s", xscr->dri_device);
>           return -1;
>        }
> +#ifndef O_CLOEXEC
> +      fcntl(fd, F_SETFD, fcntl(dri2_dpy->fd, F_GETFD) | FD_CLOEXEC);
> +#endif
>  
>        memset(&magic, 0, sizeof(magic));
>        if (drmGetMagic(fd, &magic)) {
> diff -upr /tmp/mesa-7.11/src/glx/dri2_glx.c mesa-7.11/src/glx/dri2_glx.c
> --- /tmp/mesa-7.11/src/glx/dri2_glx.c	2011-07-08 20:37:10.000000000 -0500
> +++ mesa-7.11/src/glx/dri2_glx.c	2011-12-07 21:28:09.000000000 -0600
> @@ -815,6 +815,11 @@ dri2CreateScreen(int screen, struct glx_
>     char *driverName, *deviceName;
>     drm_magic_t magic;
>     int i;
> +#ifdef O_CLOEXEC
> +   int flags = O_RDWR | O_CLOEXEC;
> +#else
> +   int flags = O_RDWR;
> +#endif
>  
>     psc = Xmalloc(sizeof *psc);
>     if (psc == NULL)
> @@ -859,11 +864,14 @@ dri2CreateScreen(int screen, struct glx_
>        goto handle_error;
>     }
>  
> -   psc->fd = open(deviceName, O_RDWR);
> +   psc->fd = open(deviceName, flags);
>     if (psc->fd < 0) {
>        ErrorMessageF("failed to open drm device: %s\n", strerror(errno));
>        goto handle_error;
>     }
> +#ifndef O_CLOEXEC
> +   fcntl(psc->fd, F_SETFD, fcntl(dri2_dpy->fd, F_GETFD) | FD_CLOEXEC);
> +#endif
>  
>     if (drmGetMagic(psc->fd, &magic)) {
>        ErrorMessageF("failed to get magic\n");



-- 
Earthling Michel Dänzer           |                   http://www.amd.com
Libre software enthusiast         |          Debian, X and DRI developer


More information about the mesa-dev mailing list