summaryrefslogtreecommitdiff
path: root/src/gallium/winsys/nouveau
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2015-11-26 14:34:43 +1000
committerBen Skeggs <bskeggs@redhat.com>2015-12-22 13:24:05 +1000
commit323d4da372298900ce02293a682ba563ac29f4cb (patch)
treeb1c88e2101f095fdff42e86c28d066313b297283 /src/gallium/winsys/nouveau
parent6c1bfff66ca6dd9dac11507889ee17987bed31cb (diff)
nouveau: fix screen creation failure paths
The winsys layer would attempt to cleanup the nouveau_device if screen init failed, however, in most paths the pipe driver would have already destroyed it, resulting in accesses to freed memory etc. This commit fixes the problem by allowing the winsys to detect whether the pipe driver's destroy function needs to be called or not. Signed-off-by: Ben Skeggs <bskeggs@redhat.com> Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com> Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Tested-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Diffstat (limited to 'src/gallium/winsys/nouveau')
-rw-r--r--src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c b/src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c
index e117dfcd009..456530d7427 100644
--- a/src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c
+++ b/src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c
@@ -59,7 +59,7 @@ nouveau_drm_screen_create(int fd)
{
struct nouveau_device *dev = NULL;
struct nouveau_screen *(*init)(struct nouveau_device *);
- struct nouveau_screen *screen;
+ struct nouveau_screen *screen = NULL;
int ret, dupfd = -1;
pipe_mutex_lock(nouveau_screen_mutex);
@@ -117,7 +117,7 @@ nouveau_drm_screen_create(int fd)
}
screen = init(dev);
- if (!screen)
+ if (!screen || !screen->base.context_create)
goto err;
/* Use dupfd in hash table, to avoid errors if the original fd gets
@@ -130,10 +130,14 @@ nouveau_drm_screen_create(int fd)
return &screen->base;
err:
- if (dev)
- nouveau_device_del(&dev);
- else if (dupfd >= 0)
- close(dupfd);
+ if (screen) {
+ screen->base.destroy(&screen->base);
+ } else {
+ if (dev)
+ nouveau_device_del(&dev);
+ else if (dupfd >= 0)
+ close(dupfd);
+ }
pipe_mutex_unlock(nouveau_screen_mutex);
return NULL;
}