mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-04-28 02:10:37 +02:00
winsys/radeon: fix a race condition in initialization of radeon_winsys::screen
Create the screen in the winsys while the mutex is locked. This also results in a nice code cleanup! Reviewed-by: Michel Dänzer <michel.daenzer@amd.com> Reviewed-by: Christian König <christian.koenig@amd.com>
This commit is contained in:
parent
ac330d4130
commit
3b0b44f7de
9 changed files with 39 additions and 114 deletions
|
|
@ -119,19 +119,9 @@ pipe_r300_create_screen(int fd)
|
|||
{
|
||||
#if _EGL_PIPE_R300
|
||||
struct radeon_winsys *sws;
|
||||
struct pipe_screen *screen;
|
||||
|
||||
sws = radeon_drm_winsys_create(fd);
|
||||
if (!sws)
|
||||
return NULL;
|
||||
|
||||
screen = r300_screen_create(sws);
|
||||
if (!screen)
|
||||
return NULL;
|
||||
|
||||
screen = debug_screen_wrap(screen);
|
||||
|
||||
return screen;
|
||||
sws = radeon_drm_winsys_create(fd, r300_screen_create);
|
||||
return sws ? debug_screen_wrap(sws->screen) : NULL;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
|
|
@ -142,19 +132,9 @@ pipe_r600_create_screen(int fd)
|
|||
{
|
||||
#if _EGL_PIPE_R600
|
||||
struct radeon_winsys *rw;
|
||||
struct pipe_screen *screen;
|
||||
|
||||
rw = radeon_drm_winsys_create(fd);
|
||||
if (!rw)
|
||||
return NULL;
|
||||
|
||||
screen = r600_screen_create(rw);
|
||||
if (!screen)
|
||||
return NULL;
|
||||
|
||||
screen = debug_screen_wrap(screen);
|
||||
|
||||
return screen;
|
||||
rw = radeon_drm_winsys_create(fd, r600_screen_create);
|
||||
return rw ? debug_screen_wrap(rw->screen) : NULL;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
|
|
@ -165,19 +145,9 @@ pipe_radeonsi_create_screen(int fd)
|
|||
{
|
||||
#if _EGL_PIPE_RADEONSI
|
||||
struct radeon_winsys *rw;
|
||||
struct pipe_screen *screen;
|
||||
|
||||
rw = radeon_drm_winsys_create(fd);
|
||||
if (!rw)
|
||||
return NULL;
|
||||
|
||||
screen = radeonsi_screen_create(rw);
|
||||
if (!screen)
|
||||
return NULL;
|
||||
|
||||
screen = debug_screen_wrap(screen);
|
||||
|
||||
return screen;
|
||||
rw = radeon_drm_winsys_create(fd, radeonsi_screen_create);
|
||||
return rw ? debug_screen_wrap(rw->screen) : NULL;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -8,19 +8,9 @@ static struct pipe_screen *
|
|||
create_screen(int fd)
|
||||
{
|
||||
struct radeon_winsys *sws;
|
||||
struct pipe_screen *screen;
|
||||
|
||||
sws = radeon_drm_winsys_create(fd);
|
||||
if (!sws)
|
||||
return NULL;
|
||||
|
||||
screen = r300_screen_create(sws);
|
||||
if (!screen)
|
||||
return NULL;
|
||||
|
||||
screen = debug_screen_wrap(screen);
|
||||
|
||||
return screen;
|
||||
sws = radeon_drm_winsys_create(fd, r300_screen_create);
|
||||
return sws ? debug_screen_wrap(sws->screen) : NULL;
|
||||
}
|
||||
|
||||
PUBLIC
|
||||
|
|
|
|||
|
|
@ -7,19 +7,9 @@ static struct pipe_screen *
|
|||
create_screen(int fd)
|
||||
{
|
||||
struct radeon_winsys *rw;
|
||||
struct pipe_screen *screen;
|
||||
|
||||
rw = radeon_drm_winsys_create(fd);
|
||||
if (!rw)
|
||||
return NULL;
|
||||
|
||||
screen = r600_screen_create(rw);
|
||||
if (!screen)
|
||||
return NULL;
|
||||
|
||||
screen = debug_screen_wrap(screen);
|
||||
|
||||
return screen;
|
||||
rw = radeon_drm_winsys_create(fd, r600_screen_create);
|
||||
return rw ? debug_screen_wrap(rw->screen) : NULL;
|
||||
}
|
||||
|
||||
PUBLIC
|
||||
|
|
|
|||
|
|
@ -7,19 +7,9 @@ static struct pipe_screen *
|
|||
create_screen(int fd)
|
||||
{
|
||||
struct radeon_winsys *rw;
|
||||
struct pipe_screen *screen;
|
||||
|
||||
rw = radeon_drm_winsys_create(fd);
|
||||
if (!rw)
|
||||
return NULL;
|
||||
|
||||
screen = radeonsi_screen_create(rw);
|
||||
if (!screen)
|
||||
return NULL;
|
||||
|
||||
screen = debug_screen_wrap(screen);
|
||||
|
||||
return screen;
|
||||
rw = radeon_drm_winsys_create(fd, radeonsi_screen_create);
|
||||
return rw ? debug_screen_wrap(rw->screen) : NULL;
|
||||
}
|
||||
|
||||
PUBLIC
|
||||
|
|
|
|||
|
|
@ -36,19 +36,8 @@ create_screen(int fd)
|
|||
{
|
||||
struct radeon_winsys *sws;
|
||||
|
||||
sws = radeon_drm_winsys_create(fd);
|
||||
if (!sws)
|
||||
return NULL;
|
||||
|
||||
if (!sws->screen) {
|
||||
sws->screen = r300_screen_create(sws);
|
||||
if (!sws->screen)
|
||||
return NULL;
|
||||
|
||||
sws->screen = debug_screen_wrap(sws->screen);
|
||||
}
|
||||
|
||||
return sws->screen;
|
||||
sws = radeon_drm_winsys_create(fd, r300_screen_create);
|
||||
return sws ? debug_screen_wrap(sws->screen) : NULL;
|
||||
}
|
||||
|
||||
/* Technically this is only true for kernels >= 3.12, which
|
||||
|
|
|
|||
|
|
@ -35,19 +35,8 @@ static struct pipe_screen *create_screen(int fd)
|
|||
{
|
||||
struct radeon_winsys *radeon;
|
||||
|
||||
radeon = radeon_drm_winsys_create(fd);
|
||||
if (!radeon)
|
||||
return NULL;
|
||||
|
||||
if (!radeon->screen) {
|
||||
radeon->screen = r600_screen_create(radeon);
|
||||
if (!radeon->screen)
|
||||
return NULL;
|
||||
|
||||
radeon->screen = debug_screen_wrap(radeon->screen);
|
||||
}
|
||||
|
||||
return radeon->screen;
|
||||
radeon = radeon_drm_winsys_create(fd, r600_screen_create);
|
||||
return radeon ? debug_screen_wrap(radeon->screen) : NULL;
|
||||
}
|
||||
|
||||
static const struct drm_conf_ret throttle_ret = {
|
||||
|
|
|
|||
|
|
@ -35,19 +35,8 @@ static struct pipe_screen *create_screen(int fd)
|
|||
{
|
||||
struct radeon_winsys *radeon;
|
||||
|
||||
radeon = radeon_drm_winsys_create(fd);
|
||||
if (!radeon)
|
||||
return NULL;
|
||||
|
||||
if (!radeon->screen) {
|
||||
radeon->screen = radeonsi_screen_create(radeon);
|
||||
if (!radeon->screen)
|
||||
return NULL;
|
||||
|
||||
radeon->screen = debug_screen_wrap(radeon->screen);
|
||||
}
|
||||
|
||||
return radeon->screen;
|
||||
radeon = radeon_drm_winsys_create(fd, radeonsi_screen_create);
|
||||
return radeon ? debug_screen_wrap(radeon->screen) : NULL;
|
||||
}
|
||||
|
||||
static const struct drm_conf_ret throttle_ret = {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,11 @@
|
|||
#include "pipe/p_defines.h"
|
||||
|
||||
struct radeon_winsys;
|
||||
struct pipe_screen;
|
||||
|
||||
struct radeon_winsys *radeon_drm_winsys_create(int fd);
|
||||
typedef struct pipe_screen *(*radeon_screen_create_t)(struct radeon_winsys *);
|
||||
|
||||
struct radeon_winsys *
|
||||
radeon_drm_winsys_create(int fd, radeon_screen_create_t screen_create);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -586,7 +586,8 @@ static bool radeon_winsys_unref(struct radeon_winsys *ws)
|
|||
return destroy;
|
||||
}
|
||||
|
||||
PUBLIC struct radeon_winsys *radeon_drm_winsys_create(int fd)
|
||||
PUBLIC struct radeon_winsys *
|
||||
radeon_drm_winsys_create(int fd, radeon_screen_create_t screen_create)
|
||||
{
|
||||
struct radeon_drm_winsys *ws;
|
||||
|
||||
|
|
@ -609,7 +610,6 @@ PUBLIC struct radeon_winsys *radeon_drm_winsys_create(int fd)
|
|||
}
|
||||
|
||||
ws->fd = fd;
|
||||
util_hash_table_set(fd_tab, intptr_to_pointer(fd), ws);
|
||||
|
||||
if (!do_winsys_init(ws))
|
||||
goto fail;
|
||||
|
|
@ -652,6 +652,20 @@ PUBLIC struct radeon_winsys *radeon_drm_winsys_create(int fd)
|
|||
if (ws->num_cpus > 1 && debug_get_option_thread())
|
||||
ws->thread = pipe_thread_create(radeon_drm_cs_emit_ioctl, ws);
|
||||
|
||||
/* Create the screen at the end. The winsys must be initialized
|
||||
* completely.
|
||||
*
|
||||
* Alternatively, we could create the screen based on "ws->gen"
|
||||
* and link all drivers into one binary blob. */
|
||||
ws->base.screen = screen_create(&ws->base);
|
||||
if (!ws->base.screen) {
|
||||
radeon_winsys_destroy(&ws->base);
|
||||
pipe_mutex_unlock(fd_tab_mutex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
util_hash_table_set(fd_tab, intptr_to_pointer(fd), ws);
|
||||
|
||||
/* We must unlock the mutex once the winsys is fully initialized, so that
|
||||
* other threads attempting to create the winsys from the same fd will
|
||||
* get a fully initialized winsys and not just half-way initialized. */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue