pan/kmod: Make default allocator thread-safe

Allocations targeting a pan_kmod_dev can happen concurrently, so we
need the pan_kmod_dev allocator to be thread-safe.

ralloc() is not thread-safe, and we don't really need a hierarchical
allocator in this context anyway, so let's just switch to calloc/free
instead.

Fixes: d95ec56f8c ("panfrost: Abstract kernel driver operations")
Reported-by: Eric Smith <eric.smith@collabora.com>
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Tested-by: Eric Smith <eric.smith@collabora.com>
Reviewed-by: Eric Smith <eric.smith@collabora.com>
Reviewed-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28926>
(cherry picked from commit 4c74d14730)
This commit is contained in:
Boris Brezillon 2024-04-30 13:56:41 +02:00 committed by Eric Engestrom
parent 1f917b8814
commit 965f8b10d5
2 changed files with 10 additions and 33 deletions

View file

@ -54,7 +54,7 @@
"description": "pan/kmod: Make default allocator thread-safe",
"nominated": true,
"nomination_type": 1,
"resolution": 0,
"resolution": 1,
"main_sha": null,
"because_sha": "d95ec56f8c6884e0ae975b683fe7249fab9e740d",
"notes": null

View file

@ -7,6 +7,7 @@
#include <string.h>
#include <xf86drm.h>
#include "util/u_memory.h"
#include "util/macros.h"
#include "pan_kmod.h"
@ -31,28 +32,19 @@ static void *
default_zalloc(const struct pan_kmod_allocator *allocator, size_t size,
UNUSED bool transient)
{
return rzalloc_size(allocator, size);
return os_calloc(1, size);
}
static void
default_free(const struct pan_kmod_allocator *allocator, void *data)
{
return ralloc_free(data);
os_free(data);
}
static const struct pan_kmod_allocator *
create_default_allocator(void)
{
struct pan_kmod_allocator *allocator =
rzalloc(NULL, struct pan_kmod_allocator);
if (allocator) {
allocator->zalloc = default_zalloc;
allocator->free = default_free;
}
return allocator;
}
static const struct pan_kmod_allocator default_allocator = {
.zalloc = default_zalloc,
.free = default_free,
};
struct pan_kmod_dev *
pan_kmod_dev_create(int fd, uint32_t flags,
@ -64,28 +56,18 @@ pan_kmod_dev_create(int fd, uint32_t flags,
if (!version)
return NULL;
if (!allocator) {
allocator = create_default_allocator();
if (!allocator)
goto out_free_version;
}
if (!allocator)
allocator = &default_allocator;
for (unsigned i = 0; i < ARRAY_SIZE(drivers); i++) {
if (!strcmp(drivers[i].name, version->name)) {
const struct pan_kmod_ops *ops = drivers[i].ops;
dev = ops->dev_create(fd, flags, version, allocator);
if (dev)
goto out_free_version;
break;
}
}
if (allocator->zalloc == default_zalloc)
ralloc_free((void *)allocator);
out_free_version:
drmFreeVersion(version);
return dev;
}
@ -93,12 +75,7 @@ out_free_version:
void
pan_kmod_dev_destroy(struct pan_kmod_dev *dev)
{
const struct pan_kmod_allocator *allocator = dev->allocator;
dev->ops->dev_destroy(dev);
if (allocator->zalloc == default_zalloc)
ralloc_free((void *)allocator);
}
struct pan_kmod_bo *