etnaviv: drm: make etna_bo_map thread safe

This might be called from multiple threads at the same time. To avoid
taking a global lock just to guard against the fairly low chance of
multiple threads calling this on the same BO at the same time, we allow
for the threads to race. All threads will set up a mapping, but only
the first thread is able to set the map member of the etna_bo, all other
threads just roll back and use the mapping set up by the winning thread.

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Reviewed-by: Christian Gmeiner <christian.gmeiner@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14466>
This commit is contained in:
Lucas Stach 2022-01-06 21:46:25 +01:00 committed by Marge Bot
parent 5711329cbc
commit 6e181476c3

View file

@ -388,6 +388,7 @@ void *etna_bo_map(struct etna_bo *bo)
{
if (!bo->map) {
int ret;
void *map;
struct drm_etnaviv_gem_info req = {
.handle = bo->handle,
};
@ -397,12 +398,15 @@ void *etna_bo_map(struct etna_bo *bo)
if (ret)
return NULL;
bo->map = os_mmap(0, bo->size, PROT_READ | PROT_WRITE,
map = os_mmap(0, bo->size, PROT_READ | PROT_WRITE,
MAP_SHARED, bo->dev->fd, req.offset);
if (bo->map == MAP_FAILED) {
if (map == MAP_FAILED) {
ERROR_MSG("mmap failed: %s", strerror(errno));
bo->map = NULL;
return NULL;
}
if (p_atomic_cmpxchg(&bo->map, NULL, map))
munmap(map, bo->size);
}
return bo->map;