From 9ae055aa98477c317a219e1583828bdc1a75a10b Mon Sep 17 00:00:00 2001 From: jsg Date: Tue, 1 Oct 2024 06:36:45 +0000 Subject: [PATCH] accel: Use XArray instead of IDR for minors From Michal Winiarski f6b589e361538285fdad8cf62143e3cf3b2c8b2a in linux-6.6.y/6.6.53 45c4d994b82b08f0ce5eb50f8da29379c92a391e in mainline linux --- sys/dev/pci/drm/drm_drv.c | 64 +++++++++++++------------- sys/dev/pci/drm/drm_file.c | 2 +- sys/dev/pci/drm/drm_internal.h | 4 -- sys/dev/pci/drm/include/drm/drm_file.h | 5 ++ 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); -- 2.20.1