hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/dma-buf/dma-heap.c
....@@ -11,6 +11,7 @@
1111 #include <linux/device.h>
1212 #include <linux/dma-buf.h>
1313 #include <linux/err.h>
14
+#include <linux/xarray.h>
1415 #include <linux/list.h>
1516 #include <linux/slab.h>
1617 #include <linux/nospec.h>
....@@ -49,9 +50,7 @@
4950 static DEFINE_MUTEX(heap_list_lock);
5051 static dev_t dma_heap_devt;
5152 static struct class *dma_heap_class;
52
-
53
-static DEFINE_MUTEX(heap_devnode_lock);
54
-static DECLARE_BITMAP(heap_devnode_nums, NUM_HEAP_MINORS);
53
+static DEFINE_XARRAY_ALLOC(dma_heap_minors);
5554
5655 struct dma_heap *dma_heap_find(const char *name)
5756 {
....@@ -124,14 +123,11 @@
124123 {
125124 struct dma_heap *heap;
126125
127
- mutex_lock(&heap_devnode_lock);
128
- heap = container_of(inode->i_cdev, struct dma_heap, heap_cdev);
126
+ heap = xa_load(&dma_heap_minors, iminor(inode));
129127 if (!heap) {
130128 pr_err("dma_heap: minor %d unknown.\n", iminor(inode));
131
- mutex_unlock(&heap_devnode_lock);
132129 return -ENODEV;
133130 }
134
- mutex_unlock(&heap_devnode_lock);
135131
136132 /* instance data as context */
137133 file->private_data = heap;
....@@ -273,9 +269,7 @@
273269
274270 device_destroy(dma_heap_class, heap->heap_devt);
275271 cdev_del(&heap->heap_cdev);
276
- mutex_lock(&heap_devnode_lock);
277
- clear_bit(minor, heap_devnode_nums);
278
- mutex_unlock(&heap_devnode_lock);
272
+ xa_erase(&dma_heap_minors, minor);
279273
280274 kfree(heap);
281275 }
....@@ -320,7 +314,7 @@
320314
321315 struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info)
322316 {
323
- struct dma_heap *heap, *err_ret;
317
+ struct dma_heap *heap, *h, *err_ret;
324318 unsigned int minor;
325319 int ret;
326320
....@@ -334,15 +328,6 @@
334328 return ERR_PTR(-EINVAL);
335329 }
336330
337
- /* check the name is unique */
338
- heap = dma_heap_find(exp_info->name);
339
- if (heap) {
340
- pr_err("dma_heap: Already registered heap named %s\n",
341
- exp_info->name);
342
- dma_heap_put(heap);
343
- return ERR_PTR(-EINVAL);
344
- }
345
-
346331 heap = kzalloc(sizeof(*heap), GFP_KERNEL);
347332 if (!heap)
348333 return ERR_PTR(-ENOMEM);
....@@ -352,18 +337,14 @@
352337 heap->ops = exp_info->ops;
353338 heap->priv = exp_info->priv;
354339
355
- /* Part 1: Find a free minor number */
356
-
357
- mutex_lock(&heap_devnode_lock);
358
- minor = find_next_zero_bit(heap_devnode_nums, NUM_HEAP_MINORS, 0);
359
- if (minor == NUM_HEAP_MINORS) {
360
- mutex_unlock(&heap_devnode_lock);
340
+ /* Find unused minor number */
341
+ ret = xa_alloc(&dma_heap_minors, &minor, heap,
342
+ XA_LIMIT(0, NUM_HEAP_MINORS - 1), GFP_KERNEL);
343
+ if (ret < 0) {
361344 pr_err("dma_heap: Unable to get minor number for heap\n");
362
- err_ret = ERR_PTR(-ENFILE);
345
+ err_ret = ERR_PTR(ret);
363346 goto err0;
364347 }
365
- set_bit(minor, heap_devnode_nums);
366
- mutex_unlock(&heap_devnode_lock);
367348
368349 /* Create device */
369350 heap->heap_devt = MKDEV(MAJOR(dma_heap_devt), minor);
....@@ -390,19 +371,31 @@
390371 /* Make sure it doesn't disappear on us */
391372 heap->heap_dev = get_device(heap->heap_dev);
392373
393
- /* Add heap to the list */
394374 mutex_lock(&heap_list_lock);
375
+ /* check the name is unique */
376
+ list_for_each_entry(h, &heap_list, list) {
377
+ if (!strcmp(h->name, exp_info->name)) {
378
+ mutex_unlock(&heap_list_lock);
379
+ pr_err("dma_heap: Already registered heap named %s\n",
380
+ exp_info->name);
381
+ err_ret = ERR_PTR(-EINVAL);
382
+ put_device(heap->heap_dev);
383
+ goto err3;
384
+ }
385
+ }
386
+
387
+ /* Add heap to the list */
395388 list_add(&heap->list, &heap_list);
396389 mutex_unlock(&heap_list_lock);
397390
398391 return heap;
399392
393
+err3:
394
+ device_destroy(dma_heap_class, heap->heap_devt);
400395 err2:
401396 cdev_del(&heap->heap_cdev);
402397 err1:
403
- mutex_lock(&heap_devnode_lock);
404
- clear_bit(minor, heap_devnode_nums);
405
- mutex_unlock(&heap_devnode_lock);
398
+ xa_erase(&dma_heap_minors, minor);
406399 err0:
407400 kfree(heap);
408401 return err_ret;