summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2024-10-01 06:36:46 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2024-10-01 06:36:46 +0000
commit4451dee883dd930b290db3640001761c9ebb3d49 (patch)
tree14c1a3496f8fe95f00e4ebde674f16ac5a4e9581
parent9bc120e0ed6f60b98d403b60f0949cced4495f7c (diff)
accel: Use XArray instead of IDR for minors
From Michal Winiarski f6b589e361538285fdad8cf62143e3cf3b2c8b2a in linux-6.6.y/6.6.53 45c4d994b82b08f0ce5eb50f8da29379c92a391e in mainline linux
-rw-r--r--sys/dev/pci/drm/drm_drv.c64
-rw-r--r--sys/dev/pci/drm/drm_file.c2
-rw-r--r--sys/dev/pci/drm/drm_internal.h4
-rw-r--r--sys/dev/pci/drm/include/drm/drm_file.h5
4 files changed, 37 insertions, 38 deletions
diff --git a/sys/dev/pci/drm/drm_drv.c b/sys/dev/pci/drm/drm_drv.c
index 7dbc555b6fb..06f6e78514a 100644
--- a/sys/dev/pci/drm/drm_drv.c
+++ b/sys/dev/pci/drm/drm_drv.c
@@ -71,7 +71,7 @@ MODULE_AUTHOR("Gareth Hughes, Leif Delgass, José Fonseca, Jon Smirl");
MODULE_DESCRIPTION("DRM shared core routines");
MODULE_LICENSE("GPL and additional rights");
-static DEFINE_XARRAY_ALLOC(drm_minors_xa);
+DEFINE_XARRAY_ALLOC(drm_minors_xa);
/*
* If the drm core fails to init for whatever reason,
@@ -144,6 +144,18 @@ SPLAY_PROTOTYPE(drm_file_tree, drm_file, link, drm_file_cmp);
* registered and unregistered dynamically according to device-state.
*/
+static struct xarray *drm_minor_get_xa(enum drm_minor_type type)
+{
+ if (type == DRM_MINOR_PRIMARY || type == DRM_MINOR_RENDER)
+ return &drm_minors_xa;
+#if IS_ENABLED(CONFIG_DRM_ACCEL)
+ else if (type == DRM_MINOR_ACCEL)
+ return &accel_minors_xa;
+#endif
+ else
+ return ERR_PTR(-EOPNOTSUPP);
+}
+
static struct drm_minor **drm_minor_get_slot(struct drm_device *dev,
enum drm_minor_type type)
{
@@ -169,13 +181,13 @@ static void drm_minor_alloc_release(struct drm_device *dev, void *data)
put_device(minor->kdev);
#endif
- if (minor->type == DRM_MINOR_ACCEL)
- accel_minor_remove(minor->index);
- else
- xa_erase(&drm_minors_xa, minor->index);
+ xa_erase(drm_minor_get_xa(minor->type), minor->index);
}
-#define DRM_MINOR_LIMIT(t) ({ typeof(t) _t = (t); XA_LIMIT(64 * _t, 64 * _t + 63); })
+#define DRM_MINOR_LIMIT(t) ({ \
+ typeof(t) _t = (t); \
+ _t == DRM_MINOR_ACCEL ? XA_LIMIT(0, ACCEL_MAX_MINORS) : XA_LIMIT(64 * _t, 64 * _t + 63); \
+})
static int drm_minor_alloc(struct drm_device *dev, enum drm_minor_type type)
{
@@ -189,18 +201,11 @@ static int drm_minor_alloc(struct drm_device *dev, enum drm_minor_type type)
minor->type = type;
minor->dev = dev;
- if (type == DRM_MINOR_ACCEL) {
- r = accel_minor_alloc();
- index = r;
- } else {
- r = xa_alloc(&drm_minors_xa, &index, NULL, DRM_MINOR_LIMIT(type), GFP_KERNEL);
- }
-
+ r = xa_alloc(drm_minor_get_xa(type), &minor->index,
+ NULL, DRM_MINOR_LIMIT(type), GFP_KERNEL);
if (r < 0)
return r;
- minor->index = index;
-
r = drmm_add_action_or_reset(dev, drm_minor_alloc_release, minor);
if (r)
return r;
@@ -246,16 +251,12 @@ static int drm_minor_register(struct drm_device *dev, enum drm_minor_type type)
#endif
/* replace NULL with @minor so lookups will succeed from now on */
- if (minor->type == DRM_MINOR_ACCEL) {
- accel_minor_replace(minor, minor->index);
- } else {
- entry = xa_store(&drm_minors_xa, minor->index, minor, GFP_KERNEL);
- if (xa_is_err(entry)) {
- ret = xa_err(entry);
- goto err_debugfs;
- }
- WARN_ON(entry);
+ entry = xa_store(drm_minor_get_xa(type), minor->index, minor, GFP_KERNEL);
+ if (xa_is_err(entry)) {
+ ret = xa_err(entry);
+ goto err_debugfs;
}
+ WARN_ON(entry);
DRM_DEBUG("new minor registered %d\n", minor->index);
return 0;
@@ -280,10 +281,7 @@ static void drm_minor_unregister(struct drm_device *dev, enum drm_minor_type typ
return;
/* replace @minor with NULL so lookups will fail from now on */
- if (minor->type == DRM_MINOR_ACCEL)
- accel_minor_replace(NULL, minor->index);
- else
- xa_store(&drm_minors_xa, minor->index, NULL, GFP_KERNEL);
+ xa_store(drm_minor_get_xa(type), minor->index, NULL, GFP_KERNEL);
#ifdef __linux__
device_del(minor->kdev);
@@ -301,15 +299,15 @@ static void drm_minor_unregister(struct drm_device *dev, enum drm_minor_type typ
* minor->dev pointer will stay valid! However, the device may get unplugged and
* unregistered while you hold the minor.
*/
-struct drm_minor *drm_minor_acquire(unsigned int minor_id)
+struct drm_minor *drm_minor_acquire(struct xarray *minor_xa, unsigned int minor_id)
{
struct drm_minor *minor;
- xa_lock(&drm_minors_xa);
- minor = xa_load(&drm_minors_xa, minor_id);
+ xa_lock(minor_xa);
+ minor = xa_load(minor_xa, minor_id);
if (minor)
drm_dev_get(minor->dev);
- xa_unlock(&drm_minors_xa);
+ xa_unlock(minor_xa);
if (!minor) {
return ERR_PTR(-ENODEV);
@@ -1128,7 +1126,7 @@ static int drm_stub_open(struct inode *inode, struct file *filp)
DRM_DEBUG("\n");
- minor = drm_minor_acquire(iminor(inode));
+ minor = drm_minor_acquire(&drm_minors_xa, iminor(inode));
if (IS_ERR(minor))
return PTR_ERR(minor);
diff --git a/sys/dev/pci/drm/drm_file.c b/sys/dev/pci/drm/drm_file.c
index a4f3e5c81d0..d160a129f81 100644
--- a/sys/dev/pci/drm/drm_file.c
+++ b/sys/dev/pci/drm/drm_file.c
@@ -426,7 +426,7 @@ int drm_open(struct inode *inode, struct file *filp)
int retcode;
int need_setup = 0;
- minor = drm_minor_acquire(iminor(inode));
+ minor = drm_minor_acquire(&drm_minors_xa, iminor(inode));
if (IS_ERR(minor))
return PTR_ERR(minor);
diff --git a/sys/dev/pci/drm/drm_internal.h b/sys/dev/pci/drm/drm_internal.h
index 584cc7fed03..e0db753bb5c 100644
--- a/sys/dev/pci/drm/drm_internal.h
+++ b/sys/dev/pci/drm/drm_internal.h
@@ -77,10 +77,6 @@ void drm_prime_destroy_file_private(struct drm_prime_file_private *prime_fpriv);
void drm_prime_remove_buf_handle(struct drm_prime_file_private *prime_fpriv,
uint32_t handle);
-/* drm_drv.c */
-struct drm_minor *drm_minor_acquire(unsigned int minor_id);
-void drm_minor_release(struct drm_minor *minor);
-
/* drm_managed.c */
void drm_managed_release(struct drm_device *dev);
void drmm_add_final_kfree(struct drm_device *dev, void *container);
diff --git a/sys/dev/pci/drm/include/drm/drm_file.h b/sys/dev/pci/drm/include/drm/drm_file.h
index 6e966a8e86b..50ed4cf44e8 100644
--- a/sys/dev/pci/drm/include/drm/drm_file.h
+++ b/sys/dev/pci/drm/include/drm/drm_file.h
@@ -48,6 +48,8 @@ struct device;
struct file;
struct seq_file;
+extern struct xarray drm_minors_xa;
+
/*
* FIXME: Not sure we want to have drm_minor here in the end, but to avoid
* header include loops we need it here for now.
@@ -449,6 +451,9 @@ static inline bool drm_is_accel_client(const struct drm_file *file_priv)
void drm_file_update_pid(struct drm_file *);
+struct drm_minor *drm_minor_acquire(struct xarray *minors_xa, unsigned int minor_id);
+void drm_minor_release(struct drm_minor *minor);
+
#ifdef __linux__
int drm_open(struct inode *inode, struct file *filp);
int drm_open_helper(struct file *filp, struct drm_minor *minor);