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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev