The IDR interface is deprecated and the XArray API is the recommended replacement. Replace the per-file IDR used to track perfmons with an XArray. This allows us to remove the external mutex that protects the IDR.
While at it, introduce the vc4_perfmon_delete() helper to consolidate the perfmon cleanup logic used by both vc4_perfmon_close_file() and vc4_perfmon_destroy_ioctl(). Also, remove the redundant assignment of vc4file->dev to itself in vc4_perfmon_open_file(). Reviewed-by: Iago Toral Quiroga <[email protected]> Reviewed-by: Tvrtko Ursulin <[email protected]> Signed-off-by: Maíra Canal <[email protected]> --- v1 -> v2: https://lore.kernel.org/dri-devel/[email protected]/ - Replace XA_LIMIT(VC4_PERFMONID_MIN, VC4_PERFMONID_MAX) with xa_limit_32b (Tvrtko Ursulin) --- drivers/gpu/drm/vc4/vc4_drv.h | 5 +-- drivers/gpu/drm/vc4/vc4_perfmon.c | 51 +++++++++++++------------------ 2 files changed, 22 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 221d8e01d539..dbcc83b7df00 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -791,10 +791,7 @@ struct vc4_exec_info { struct vc4_file { struct vc4_dev *dev; - struct { - struct idr idr; - struct mutex lock; - } perfmon; + struct xarray perfmons; bool bin_bo_used; }; diff --git a/drivers/gpu/drm/vc4/vc4_perfmon.c b/drivers/gpu/drm/vc4/vc4_perfmon.c index 1ac80c0b258f..c02609b3ca47 100644 --- a/drivers/gpu/drm/vc4/vc4_perfmon.c +++ b/drivers/gpu/drm/vc4/vc4_perfmon.c @@ -14,9 +14,6 @@ #include "vc4_drv.h" #include "vc4_regs.h" -#define VC4_PERFMONID_MIN 1 -#define VC4_PERFMONID_MAX U32_MAX - void vc4_perfmon_get(struct vc4_perfmon *perfmon) { struct vc4_dev *vc4; @@ -95,10 +92,10 @@ struct vc4_perfmon *vc4_perfmon_find(struct vc4_file *vc4file, int id) if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return NULL; - mutex_lock(&vc4file->perfmon.lock); - perfmon = idr_find(&vc4file->perfmon.idr, id); + xa_lock(&vc4file->perfmons); + perfmon = xa_load(&vc4file->perfmons, id); vc4_perfmon_get(perfmon); - mutex_unlock(&vc4file->perfmon.lock); + xa_unlock(&vc4file->perfmons); return perfmon; } @@ -110,37 +107,34 @@ void vc4_perfmon_open_file(struct vc4_file *vc4file) if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return; - mutex_init(&vc4file->perfmon.lock); - idr_init_base(&vc4file->perfmon.idr, VC4_PERFMONID_MIN); - vc4file->dev = vc4; + xa_init_flags(&vc4file->perfmons, XA_FLAGS_ALLOC1); } -static int vc4_perfmon_idr_del(int id, void *elem, void *data) +static void vc4_perfmon_delete(struct vc4_file *vc4file, + struct vc4_perfmon *perfmon) { - struct vc4_perfmon *perfmon = elem; - struct vc4_dev *vc4 = (struct vc4_dev *)data; + struct vc4_dev *vc4 = vc4file->dev; /* If the active perfmon is being destroyed, stop it first */ if (perfmon == vc4->active_perfmon) vc4_perfmon_stop(vc4, perfmon, false); vc4_perfmon_put(perfmon); - - return 0; } void vc4_perfmon_close_file(struct vc4_file *vc4file) { struct vc4_dev *vc4 = vc4file->dev; + struct vc4_perfmon *perfmon; + unsigned long id; if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return; - mutex_lock(&vc4file->perfmon.lock); - idr_for_each(&vc4file->perfmon.idr, vc4_perfmon_idr_del, vc4); - idr_destroy(&vc4file->perfmon.idr); - mutex_unlock(&vc4file->perfmon.lock); - mutex_destroy(&vc4file->perfmon.lock); + xa_for_each(&vc4file->perfmons, id, perfmon) + vc4_perfmon_delete(vc4file, perfmon); + + xa_destroy(&vc4file->perfmons); } int vc4_perfmon_create_ioctl(struct drm_device *dev, void *data, @@ -152,6 +146,7 @@ int vc4_perfmon_create_ioctl(struct drm_device *dev, void *data, struct vc4_perfmon *perfmon; unsigned int i; int ret; + u32 id; if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return -ENODEV; @@ -185,17 +180,15 @@ int vc4_perfmon_create_ioctl(struct drm_device *dev, void *data, refcount_set(&perfmon->refcnt, 1); - mutex_lock(&vc4file->perfmon.lock); - ret = idr_alloc(&vc4file->perfmon.idr, perfmon, VC4_PERFMONID_MIN, - VC4_PERFMONID_MAX, GFP_KERNEL); - mutex_unlock(&vc4file->perfmon.lock); - + ret = xa_alloc(&vc4file->perfmons, &id, perfmon, xa_limit_32b, + GFP_KERNEL); if (ret < 0) { kfree(perfmon); return ret; } - req->id = ret; + req->id = id; + return 0; } @@ -215,14 +208,12 @@ int vc4_perfmon_destroy_ioctl(struct drm_device *dev, void *data, return -ENODEV; } - mutex_lock(&vc4file->perfmon.lock); - perfmon = idr_remove(&vc4file->perfmon.idr, req->id); - mutex_unlock(&vc4file->perfmon.lock); - + perfmon = xa_erase(&vc4file->perfmons, req->id); if (!perfmon) return -EINVAL; - vc4_perfmon_put(perfmon); + vc4_perfmon_delete(vc4file, perfmon); + return 0; } -- 2.52.0
