[Nouveau] [mesa PATCH] nouveau: fix double free when nvXX_screen_create fails
Marcin Slusarz
marcin.slusarz at gmail.com
Fri Dec 2 10:46:59 PST 2011
When nvXX_screen_create fails, it destroys winsys object,
so nouveau_drm_screen_create should not try to destroy it again.
Note: This is a candidate for the 7.11 branch.
---
src/gallium/drivers/nv50/nv50_screen.c | 7 +++++--
src/gallium/drivers/nvc0/nvc0_screen.c | 7 +++++--
src/gallium/drivers/nvfx/nvfx_screen.c | 6 ++++--
.../winsys/nouveau/drm/nouveau_drm_winsys.c | 10 ++++++----
4 files changed, 20 insertions(+), 10 deletions(-)
diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c
index 3cd5fdf..156054b 100644
--- a/src/gallium/drivers/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nv50/nv50_screen.c
@@ -22,6 +22,7 @@
#include "util/u_format.h"
#include "util/u_format_s3tc.h"
+#include "util/u_simple_screen.h"
#include "pipe/p_screen.h"
#include "nv50_context.h"
@@ -310,9 +311,12 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
unsigned i, base;
screen = CALLOC_STRUCT(nv50_screen);
- if (!screen)
+ if (!screen) {
+ ws->destroy(ws);
return NULL;
+ }
pscreen = &screen->base.base;
+ pscreen->winsys = ws;
screen->base.sysmem_bindings = PIPE_BIND_CONSTANT_BUFFER;
@@ -323,7 +327,6 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
chan = screen->base.channel;
chan->user_private = screen;
- pscreen->winsys = ws;
pscreen->destroy = nv50_screen_destroy;
pscreen->context_create = nv50_create;
pscreen->is_format_supported = nv50_screen_is_format_supported;
diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c b/src/gallium/drivers/nvc0/nvc0_screen.c
index 79c3e36..9268a7a 100644
--- a/src/gallium/drivers/nvc0/nvc0_screen.c
+++ b/src/gallium/drivers/nvc0/nvc0_screen.c
@@ -22,6 +22,7 @@
#include "util/u_format.h"
#include "util/u_format_s3tc.h"
+#include "util/u_simple_screen.h"
#include "pipe/p_screen.h"
#include "vl/vl_decoder.h"
@@ -376,9 +377,12 @@ nvc0_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
unsigned i;
screen = CALLOC_STRUCT(nvc0_screen);
- if (!screen)
+ if (!screen) {
+ ws->destroy(ws);
return NULL;
+ }
pscreen = &screen->base.base;
+ pscreen->winsys = ws;
screen->base.sysmem_bindings = PIPE_BIND_CONSTANT_BUFFER;
@@ -390,7 +394,6 @@ nvc0_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
chan = screen->base.channel;
chan->user_private = screen;
- pscreen->winsys = ws;
pscreen->destroy = nvc0_screen_destroy;
pscreen->context_create = nvc0_create;
pscreen->is_format_supported = nvc0_screen_is_format_supported;
diff --git a/src/gallium/drivers/nvfx/nvfx_screen.c b/src/gallium/drivers/nvfx/nvfx_screen.c
index f56c697..4085ec7 100644
--- a/src/gallium/drivers/nvfx/nvfx_screen.c
+++ b/src/gallium/drivers/nvfx/nvfx_screen.c
@@ -469,10 +469,13 @@ nvfx_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
unsigned eng3d_class = 0;
int ret, i;
- if (!screen)
+ if (!screen) {
+ ws->destroy(ws);
return NULL;
+ }
pscreen = &screen->base.base;
+ pscreen->winsys = ws;
ret = nouveau_screen_init(&screen->base, dev);
if (ret) {
@@ -484,7 +487,6 @@ nvfx_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
chan->user_private = screen;
chan->flush_notify = nvfx_channel_flush_notify;
- pscreen->winsys = ws;
pscreen->destroy = nvfx_screen_destroy;
pscreen->get_param = nvfx_screen_get_param;
pscreen->get_shader_param = nvfx_screen_get_shader_param;
diff --git a/src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c b/src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c
index 7d7a276..d7a6bf7 100644
--- a/src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c
+++ b/src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c
@@ -30,6 +30,7 @@ nouveau_drm_screen_create(int fd)
struct nouveau_winsys *nvws;
struct pipe_winsys *ws;
struct nouveau_device *dev = NULL;
+ struct pipe_screen *screen;
struct pipe_screen *(*init)(struct pipe_winsys *,
struct nouveau_device *);
int ret;
@@ -68,11 +69,12 @@ nouveau_drm_screen_create(int fd)
ws = &nvws->base;
ws->destroy = nouveau_drm_destroy_winsys;
- nvws->pscreen = init(ws, dev);
- if (!nvws->pscreen) {
- ws->destroy(ws);
+ screen = init(ws, dev);
+ if (!screen)
+ /* winsys was destroyed by init */
return NULL;
- }
+
+ nvws->pscreen = screen;
return nvws->pscreen;
}
--
1.7.8.rc3
More information about the Nouveau
mailing list