#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;
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;
}
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,
struct vc4_perfmon *perfmon;
unsigned int i;
int ret;
+ u32 id;
if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4))
return -ENODEV;
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;
}
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;
}