Skip to content

Commit 5f5b32b

Browse files
mwiniarsgregkh
authored andcommitted
accel: Use XArray instead of IDR for minors
[ Upstream commit 45c4d99 ] Accel minor management is based on DRM (and is also using struct drm_minor internally), since DRM is using XArray for minors, it makes sense to also convert accel. As the two implementations are identical (only difference being the underlying xarray), move the accel_minor_* functionality to DRM. Signed-off-by: Michał Winiarski <michal.winiarski@intel.com> Acked-by: James Zhu <James.Zhu@amd.com> Acked-by: Christian König <christian.koenig@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240823163048.2676257-3-michal.winiarski@intel.com Signed-off-by: Christian König <christian.koenig@amd.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent c4c03bb commit 5f5b32b

6 files changed

Lines changed: 47 additions & 158 deletions

File tree

drivers/accel/drm_accel.c

Lines changed: 7 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
#include <linux/debugfs.h>
1010
#include <linux/device.h>
11-
#include <linux/idr.h>
11+
#include <linux/xarray.h>
1212

1313
#include <drm/drm_accel.h>
1414
#include <drm/drm_auth.h>
@@ -18,8 +18,7 @@
1818
#include <drm/drm_ioctl.h>
1919
#include <drm/drm_print.h>
2020

21-
static DEFINE_SPINLOCK(accel_minor_lock);
22-
static struct idr accel_minors_idr;
21+
DEFINE_XARRAY_ALLOC(accel_minors_xa);
2322

2423
static struct dentry *accel_debugfs_root;
2524

@@ -117,99 +116,6 @@ void accel_set_device_instance_params(struct device *kdev, int index)
117116
kdev->type = &accel_sysfs_device_minor;
118117
}
119118

120-
/**
121-
* accel_minor_alloc() - Allocates a new accel minor
122-
*
123-
* This function access the accel minors idr and allocates from it
124-
* a new id to represent a new accel minor
125-
*
126-
* Return: A new id on success or error code in case idr_alloc failed
127-
*/
128-
int accel_minor_alloc(void)
129-
{
130-
unsigned long flags;
131-
int r;
132-
133-
spin_lock_irqsave(&accel_minor_lock, flags);
134-
r = idr_alloc(&accel_minors_idr, NULL, 0, ACCEL_MAX_MINORS, GFP_NOWAIT);
135-
spin_unlock_irqrestore(&accel_minor_lock, flags);
136-
137-
return r;
138-
}
139-
140-
/**
141-
* accel_minor_remove() - Remove an accel minor
142-
* @index: The minor id to remove.
143-
*
144-
* This function access the accel minors idr and removes from
145-
* it the member with the id that is passed to this function.
146-
*/
147-
void accel_minor_remove(int index)
148-
{
149-
unsigned long flags;
150-
151-
spin_lock_irqsave(&accel_minor_lock, flags);
152-
idr_remove(&accel_minors_idr, index);
153-
spin_unlock_irqrestore(&accel_minor_lock, flags);
154-
}
155-
156-
/**
157-
* accel_minor_replace() - Replace minor pointer in accel minors idr.
158-
* @minor: Pointer to the new minor.
159-
* @index: The minor id to replace.
160-
*
161-
* This function access the accel minors idr structure and replaces the pointer
162-
* that is associated with an existing id. Because the minor pointer can be
163-
* NULL, we need to explicitly pass the index.
164-
*
165-
* Return: 0 for success, negative value for error
166-
*/
167-
void accel_minor_replace(struct drm_minor *minor, int index)
168-
{
169-
unsigned long flags;
170-
171-
spin_lock_irqsave(&accel_minor_lock, flags);
172-
idr_replace(&accel_minors_idr, minor, index);
173-
spin_unlock_irqrestore(&accel_minor_lock, flags);
174-
}
175-
176-
/*
177-
* Looks up the given minor-ID and returns the respective DRM-minor object. The
178-
* refence-count of the underlying device is increased so you must release this
179-
* object with accel_minor_release().
180-
*
181-
* The object can be only a drm_minor that represents an accel device.
182-
*
183-
* As long as you hold this minor, it is guaranteed that the object and the
184-
* minor->dev pointer will stay valid! However, the device may get unplugged and
185-
* unregistered while you hold the minor.
186-
*/
187-
static struct drm_minor *accel_minor_acquire(unsigned int minor_id)
188-
{
189-
struct drm_minor *minor;
190-
unsigned long flags;
191-
192-
spin_lock_irqsave(&accel_minor_lock, flags);
193-
minor = idr_find(&accel_minors_idr, minor_id);
194-
if (minor)
195-
drm_dev_get(minor->dev);
196-
spin_unlock_irqrestore(&accel_minor_lock, flags);
197-
198-
if (!minor) {
199-
return ERR_PTR(-ENODEV);
200-
} else if (drm_dev_is_unplugged(minor->dev)) {
201-
drm_dev_put(minor->dev);
202-
return ERR_PTR(-ENODEV);
203-
}
204-
205-
return minor;
206-
}
207-
208-
static void accel_minor_release(struct drm_minor *minor)
209-
{
210-
drm_dev_put(minor->dev);
211-
}
212-
213119
/**
214120
* accel_open - open method for ACCEL file
215121
* @inode: device inode
@@ -227,7 +133,7 @@ int accel_open(struct inode *inode, struct file *filp)
227133
struct drm_minor *minor;
228134
int retcode;
229135

230-
minor = accel_minor_acquire(iminor(inode));
136+
minor = drm_minor_acquire(&accel_minors_xa, iminor(inode));
231137
if (IS_ERR(minor))
232138
return PTR_ERR(minor);
233139

@@ -246,7 +152,7 @@ int accel_open(struct inode *inode, struct file *filp)
246152

247153
err_undo:
248154
atomic_dec(&dev->open_count);
249-
accel_minor_release(minor);
155+
drm_minor_release(minor);
250156
return retcode;
251157
}
252158
EXPORT_SYMBOL_GPL(accel_open);
@@ -257,7 +163,7 @@ static int accel_stub_open(struct inode *inode, struct file *filp)
257163
struct drm_minor *minor;
258164
int err;
259165

260-
minor = accel_minor_acquire(iminor(inode));
166+
minor = drm_minor_acquire(&accel_minors_xa, iminor(inode));
261167
if (IS_ERR(minor))
262168
return PTR_ERR(minor);
263169

@@ -274,7 +180,7 @@ static int accel_stub_open(struct inode *inode, struct file *filp)
274180
err = 0;
275181

276182
out:
277-
accel_minor_release(minor);
183+
drm_minor_release(minor);
278184

279185
return err;
280186
}
@@ -290,15 +196,13 @@ void accel_core_exit(void)
290196
unregister_chrdev(ACCEL_MAJOR, "accel");
291197
debugfs_remove(accel_debugfs_root);
292198
accel_sysfs_destroy();
293-
idr_destroy(&accel_minors_idr);
199+
WARN_ON(!xa_empty(&accel_minors_xa));
294200
}
295201

296202
int __init accel_core_init(void)
297203
{
298204
int ret;
299205

300-
idr_init(&accel_minors_idr);
301-
302206
ret = accel_sysfs_init();
303207
if (ret < 0) {
304208
DRM_ERROR("Cannot create ACCEL class: %d\n", ret);

drivers/gpu/drm/drm_drv.c

Lines changed: 32 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ MODULE_AUTHOR("Gareth Hughes, Leif Delgass, José Fonseca, Jon Smirl");
5555
MODULE_DESCRIPTION("DRM shared core routines");
5656
MODULE_LICENSE("GPL and additional rights");
5757

58-
static DEFINE_XARRAY_ALLOC(drm_minors_xa);
58+
DEFINE_XARRAY_ALLOC(drm_minors_xa);
5959

6060
/*
6161
* If the drm core fails to init for whatever reason,
@@ -83,6 +83,18 @@ DEFINE_STATIC_SRCU(drm_unplug_srcu);
8383
* registered and unregistered dynamically according to device-state.
8484
*/
8585

86+
static struct xarray *drm_minor_get_xa(enum drm_minor_type type)
87+
{
88+
if (type == DRM_MINOR_PRIMARY || type == DRM_MINOR_RENDER)
89+
return &drm_minors_xa;
90+
#if IS_ENABLED(CONFIG_DRM_ACCEL)
91+
else if (type == DRM_MINOR_ACCEL)
92+
return &accel_minors_xa;
93+
#endif
94+
else
95+
return ERR_PTR(-EOPNOTSUPP);
96+
}
97+
8698
static struct drm_minor **drm_minor_get_slot(struct drm_device *dev,
8799
enum drm_minor_type type)
88100
{
@@ -106,18 +118,18 @@ static void drm_minor_alloc_release(struct drm_device *dev, void *data)
106118

107119
put_device(minor->kdev);
108120

109-
if (minor->type == DRM_MINOR_ACCEL)
110-
accel_minor_remove(minor->index);
111-
else
112-
xa_erase(&drm_minors_xa, minor->index);
121+
xa_erase(drm_minor_get_xa(minor->type), minor->index);
113122
}
114123

115-
#define DRM_MINOR_LIMIT(t) ({ typeof(t) _t = (t); XA_LIMIT(64 * _t, 64 * _t + 63); })
124+
#define DRM_MINOR_LIMIT(t) ({ \
125+
typeof(t) _t = (t); \
126+
_t == DRM_MINOR_ACCEL ? XA_LIMIT(0, ACCEL_MAX_MINORS) : XA_LIMIT(64 * _t, 64 * _t + 63); \
127+
})
116128

117129
static int drm_minor_alloc(struct drm_device *dev, enum drm_minor_type type)
118130
{
119131
struct drm_minor *minor;
120-
int index, r;
132+
int r;
121133

122134
minor = drmm_kzalloc(dev, sizeof(*minor), GFP_KERNEL);
123135
if (!minor)
@@ -126,18 +138,11 @@ static int drm_minor_alloc(struct drm_device *dev, enum drm_minor_type type)
126138
minor->type = type;
127139
minor->dev = dev;
128140

129-
if (type == DRM_MINOR_ACCEL) {
130-
r = accel_minor_alloc();
131-
index = r;
132-
} else {
133-
r = xa_alloc(&drm_minors_xa, &index, NULL, DRM_MINOR_LIMIT(type), GFP_KERNEL);
134-
}
135-
141+
r = xa_alloc(drm_minor_get_xa(type), &minor->index,
142+
NULL, DRM_MINOR_LIMIT(type), GFP_KERNEL);
136143
if (r < 0)
137144
return r;
138145

139-
minor->index = index;
140-
141146
r = drmm_add_action_or_reset(dev, drm_minor_alloc_release, minor);
142147
if (r)
143148
return r;
@@ -176,16 +181,12 @@ static int drm_minor_register(struct drm_device *dev, enum drm_minor_type type)
176181
goto err_debugfs;
177182

178183
/* replace NULL with @minor so lookups will succeed from now on */
179-
if (minor->type == DRM_MINOR_ACCEL) {
180-
accel_minor_replace(minor, minor->index);
181-
} else {
182-
entry = xa_store(&drm_minors_xa, minor->index, minor, GFP_KERNEL);
183-
if (xa_is_err(entry)) {
184-
ret = xa_err(entry);
185-
goto err_debugfs;
186-
}
187-
WARN_ON(entry);
184+
entry = xa_store(drm_minor_get_xa(type), minor->index, minor, GFP_KERNEL);
185+
if (xa_is_err(entry)) {
186+
ret = xa_err(entry);
187+
goto err_debugfs;
188188
}
189+
WARN_ON(entry);
189190

190191
DRM_DEBUG("new minor registered %d\n", minor->index);
191192
return 0;
@@ -204,10 +205,7 @@ static void drm_minor_unregister(struct drm_device *dev, enum drm_minor_type typ
204205
return;
205206

206207
/* replace @minor with NULL so lookups will fail from now on */
207-
if (minor->type == DRM_MINOR_ACCEL)
208-
accel_minor_replace(NULL, minor->index);
209-
else
210-
xa_store(&drm_minors_xa, minor->index, NULL, GFP_KERNEL);
208+
xa_store(drm_minor_get_xa(type), minor->index, NULL, GFP_KERNEL);
211209

212210
device_del(minor->kdev);
213211
dev_set_drvdata(minor->kdev, NULL); /* safety belt */
@@ -223,15 +221,15 @@ static void drm_minor_unregister(struct drm_device *dev, enum drm_minor_type typ
223221
* minor->dev pointer will stay valid! However, the device may get unplugged and
224222
* unregistered while you hold the minor.
225223
*/
226-
struct drm_minor *drm_minor_acquire(unsigned int minor_id)
224+
struct drm_minor *drm_minor_acquire(struct xarray *minor_xa, unsigned int minor_id)
227225
{
228226
struct drm_minor *minor;
229227

230-
xa_lock(&drm_minors_xa);
231-
minor = xa_load(&drm_minors_xa, minor_id);
228+
xa_lock(minor_xa);
229+
minor = xa_load(minor_xa, minor_id);
232230
if (minor)
233231
drm_dev_get(minor->dev);
234-
xa_unlock(&drm_minors_xa);
232+
xa_unlock(minor_xa);
235233

236234
if (!minor) {
237235
return ERR_PTR(-ENODEV);
@@ -1024,7 +1022,7 @@ static int drm_stub_open(struct inode *inode, struct file *filp)
10241022

10251023
DRM_DEBUG("\n");
10261024

1027-
minor = drm_minor_acquire(iminor(inode));
1025+
minor = drm_minor_acquire(&drm_minors_xa, iminor(inode));
10281026
if (IS_ERR(minor))
10291027
return PTR_ERR(minor);
10301028

drivers/gpu/drm/drm_file.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ int drm_open(struct inode *inode, struct file *filp)
364364
struct drm_minor *minor;
365365
int retcode;
366366

367-
minor = drm_minor_acquire(iminor(inode));
367+
minor = drm_minor_acquire(&drm_minors_xa, iminor(inode));
368368
if (IS_ERR(minor))
369369
return PTR_ERR(minor);
370370

drivers/gpu/drm/drm_internal.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,6 @@ void drm_prime_destroy_file_private(struct drm_prime_file_private *prime_fpriv);
8181
void drm_prime_remove_buf_handle(struct drm_prime_file_private *prime_fpriv,
8282
uint32_t handle);
8383

84-
/* drm_drv.c */
85-
struct drm_minor *drm_minor_acquire(unsigned int minor_id);
86-
void drm_minor_release(struct drm_minor *minor);
87-
8884
/* drm_managed.c */
8985
void drm_managed_release(struct drm_device *dev);
9086
void drmm_add_final_kfree(struct drm_device *dev, void *container);

include/drm/drm_accel.h

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,10 @@
5151

5252
#if IS_ENABLED(CONFIG_DRM_ACCEL)
5353

54+
extern struct xarray accel_minors_xa;
55+
5456
void accel_core_exit(void);
5557
int accel_core_init(void);
56-
void accel_minor_remove(int index);
57-
int accel_minor_alloc(void);
58-
void accel_minor_replace(struct drm_minor *minor, int index);
5958
void accel_set_device_instance_params(struct device *kdev, int index);
6059
int accel_open(struct inode *inode, struct file *filp);
6160
void accel_debugfs_init(struct drm_device *dev);
@@ -73,19 +72,6 @@ static inline int __init accel_core_init(void)
7372
return 0;
7473
}
7574

76-
static inline void accel_minor_remove(int index)
77-
{
78-
}
79-
80-
static inline int accel_minor_alloc(void)
81-
{
82-
return -EOPNOTSUPP;
83-
}
84-
85-
static inline void accel_minor_replace(struct drm_minor *minor, int index)
86-
{
87-
}
88-
8975
static inline void accel_set_device_instance_params(struct device *kdev, int index)
9076
{
9177
}

include/drm/drm_file.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ struct drm_printer;
4545
struct device;
4646
struct file;
4747

48+
extern struct xarray drm_minors_xa;
49+
4850
/*
4951
* FIXME: Not sure we want to have drm_minor here in the end, but to avoid
5052
* header include loops we need it here for now.
@@ -434,6 +436,9 @@ static inline bool drm_is_accel_client(const struct drm_file *file_priv)
434436

435437
void drm_file_update_pid(struct drm_file *);
436438

439+
struct drm_minor *drm_minor_acquire(struct xarray *minors_xa, unsigned int minor_id);
440+
void drm_minor_release(struct drm_minor *minor);
441+
437442
int drm_open(struct inode *inode, struct file *filp);
438443
int drm_open_helper(struct file *filp, struct drm_minor *minor);
439444
ssize_t drm_read(struct file *filp, char __user *buffer,

0 commit comments

Comments
 (0)