Skip to content
Snippets Groups Projects
Commit bb4c9e09 authored by Marek Olšák's avatar Marek Olšák
Browse files

r300g: make accessing map_list and buffer_handles thread-safe

NOTE: This is a candidate for the 7.9 branch.
(cherry picked from commit a3334853)
parent aa057530
No related branches found
No related tags found
No related merge requests found
......@@ -11,8 +11,10 @@
#include "util/u_simple_list.h"
#include "pipebuffer/pb_buffer.h"
#include "pipebuffer/pb_bufmgr.h"
#include "os/os_thread.h"
#include "radeon_winsys.h"
struct radeon_drm_bufmgr;
struct radeon_drm_buffer {
......@@ -39,10 +41,19 @@ radeon_drm_buffer(struct pb_buffer *buf)
}
struct radeon_drm_bufmgr {
/* Base class. */
struct pb_manager base;
/* Winsys. */
struct radeon_libdrm_winsys *rws;
/* List of mapped buffers and its mutex. */
struct radeon_drm_buffer buffer_map_list;
pipe_mutex buffer_map_list_mutex;
/* List of buffer handles and its mutex. */
struct util_hash_table *buffer_handles;
pipe_mutex buffer_handles_mutex;
};
static INLINE struct radeon_drm_bufmgr *
......@@ -59,14 +70,21 @@ radeon_drm_buffer_destroy(struct pb_buffer *_buf)
int name;
if (buf->bo->ptr != NULL) {
remove_from_list(buf);
radeon_bo_unmap(buf->bo);
buf->bo->ptr = NULL;
pipe_mutex_lock(buf->mgr->buffer_map_list_mutex);
/* Now test it again inside the mutex. */
if (buf->bo->ptr != NULL) {
remove_from_list(buf);
radeon_bo_unmap(buf->bo);
buf->bo->ptr = NULL;
}
pipe_mutex_unlock(buf->mgr->buffer_map_list_mutex);
}
name = radeon_gem_name_bo(buf->bo);
if (name) {
pipe_mutex_lock(buf->mgr->buffer_handles_mutex);
util_hash_table_remove(buf->mgr->buffer_handles,
(void*)(uintptr_t)name);
pipe_mutex_unlock(buf->mgr->buffer_handles_mutex);
}
radeon_bo_unref(buf->bo);
......@@ -119,7 +137,13 @@ radeon_drm_buffer_map_internal(struct pb_buffer *_buf,
}
if (buf->bo->ptr != NULL) {
remove_from_list(buf);
pipe_mutex_lock(buf->mgr->buffer_map_list_mutex);
/* Now test ptr again inside the mutex. We might have gotten a race
* during the first test. */
if (buf->bo->ptr != NULL) {
remove_from_list(buf);
}
pipe_mutex_unlock(buf->mgr->buffer_map_list_mutex);
return buf->bo->ptr;
}
......@@ -145,7 +169,9 @@ radeon_drm_buffer_map_internal(struct pb_buffer *_buf,
return NULL;
}
pipe_mutex_lock(buf->mgr->buffer_map_list_mutex);
remove_from_list(buf);
pipe_mutex_unlock(buf->mgr->buffer_map_list_mutex);
return buf->bo->ptr;
}
......@@ -153,9 +179,11 @@ static void
radeon_drm_buffer_unmap_internal(struct pb_buffer *_buf)
{
struct radeon_drm_buffer *buf = radeon_drm_buffer(_buf);
pipe_mutex_lock(buf->mgr->buffer_map_list_mutex);
if (is_empty_list(buf)) { /* = is not inserted... */
insert_at_tail(&buf->mgr->buffer_map_list, buf);
}
pipe_mutex_unlock(buf->mgr->buffer_map_list_mutex);
}
static void
......@@ -192,8 +220,9 @@ const struct pb_vtbl radeon_drm_buffer_vtbl = {
radeon_drm_buffer_get_base_buffer,
};
struct pb_buffer *radeon_drm_bufmgr_create_buffer_from_handle(struct pb_manager *_mgr,
uint32_t handle)
static struct pb_buffer *
radeon_drm_bufmgr_create_buffer_from_handle_unsafe(struct pb_manager *_mgr,
uint32_t handle)
{
struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr);
struct radeon_libdrm_winsys *rws = mgr->rws;
......@@ -201,6 +230,7 @@ struct pb_buffer *radeon_drm_bufmgr_create_buffer_from_handle(struct pb_manager
struct radeon_bo *bo;
buf = util_hash_table_get(mgr->buffer_handles, (void*)(uintptr_t)handle);
if (buf) {
struct pb_buffer *b = NULL;
pb_reference(&b, &buf->base);
......@@ -234,6 +264,20 @@ struct pb_buffer *radeon_drm_bufmgr_create_buffer_from_handle(struct pb_manager
return &buf->base;
}
struct pb_buffer *
radeon_drm_bufmgr_create_buffer_from_handle(struct pb_manager *_mgr,
uint32_t handle)
{
struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr);
struct pb_buffer *pb;
pipe_mutex_lock(mgr->buffer_handles_mutex);
pb = radeon_drm_bufmgr_create_buffer_from_handle_unsafe(_mgr, handle);
pipe_mutex_unlock(mgr->buffer_handles_mutex);
return pb;
}
static struct pb_buffer *
radeon_drm_bufmgr_create_buffer(struct pb_manager *_mgr,
pb_size size,
......@@ -285,6 +329,8 @@ radeon_drm_bufmgr_destroy(struct pb_manager *_mgr)
{
struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr);
util_hash_table_destroy(mgr->buffer_handles);
pipe_mutex_destroy(mgr->buffer_map_list_mutex);
pipe_mutex_destroy(mgr->buffer_handles_mutex);
FREE(mgr);
}
......@@ -314,6 +360,8 @@ radeon_drm_bufmgr_create(struct radeon_libdrm_winsys *rws)
mgr->rws = rws;
make_empty_list(&mgr->buffer_map_list);
mgr->buffer_handles = util_hash_table_create(handle_hash, handle_compare);
pipe_mutex_init(mgr->buffer_map_list_mutex);
pipe_mutex_init(mgr->buffer_handles_mutex);
return &mgr->base;
}
......@@ -489,6 +537,8 @@ void radeon_drm_bufmgr_flush_maps(struct pb_manager *_mgr)
struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr);
struct radeon_drm_buffer *rpb, *t_rpb;
pipe_mutex_lock(mgr->buffer_map_list_mutex);
foreach_s(rpb, t_rpb, &mgr->buffer_map_list) {
radeon_bo_unmap(rpb->bo);
rpb->bo->ptr = NULL;
......@@ -496,6 +546,8 @@ void radeon_drm_bufmgr_flush_maps(struct pb_manager *_mgr)
}
make_empty_list(&mgr->buffer_map_list);
pipe_mutex_unlock(mgr->buffer_map_list_mutex);
}
void radeon_drm_bufmgr_wait(struct r300_winsys_screen *ws,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment