]> www.infradead.org Git - users/willy/xarray.git/commitdiff
uio: Convert uio_idr to XArray
authorMatthew Wilcox <willy@infradead.org>
Mon, 18 Feb 2019 22:47:01 +0000 (17:47 -0500)
committerMatthew Wilcox (Oracle) <willy@infradead.org>
Fri, 9 Aug 2019 01:38:18 +0000 (21:38 -0400)
Signed-off-by: Matthew Wilcox <willy@infradead.org>
drivers/uio/uio.c

index a57698985f9c419dc7a35c17560fa52c7ad491e8..5e9a43fc3aed1832ce3a46127f7ee419db252c83 100644 (file)
 #include <linux/device.h>
 #include <linux/slab.h>
 #include <linux/mm.h>
-#include <linux/idr.h>
 #include <linux/sched/signal.h>
 #include <linux/string.h>
 #include <linux/kobject.h>
 #include <linux/cdev.h>
 #include <linux/uio_driver.h>
+#include <linux/xarray.h>
 
 #define UIO_MAX_DEVICES                (1U << MINORBITS)
 
 static int uio_major;
 static struct cdev *uio_cdev;
-static DEFINE_IDR(uio_idr);
+static DEFINE_XARRAY_ALLOC(uio_devs);
 static const struct file_operations uio_fops;
 
-/* Protect idr accesses */
-static DEFINE_MUTEX(minor_lock);
-
 /*
  * attributes
  */
@@ -398,26 +395,21 @@ static void uio_dev_del_attributes(struct uio_device *idev)
 
 static int uio_get_minor(struct uio_device *idev)
 {
-       int retval = -ENOMEM;
-
-       mutex_lock(&minor_lock);
-       retval = idr_alloc(&uio_idr, idev, 0, UIO_MAX_DEVICES, GFP_KERNEL);
-       if (retval >= 0) {
-               idev->minor = retval;
-               retval = 0;
-       } else if (retval == -ENOSPC) {
+       int err;
+
+       err = xa_alloc(&uio_devs, &idev->minor, idev,
+                       XA_LIMIT(0, UIO_MAX_DEVICES - 1), GFP_KERNEL);
+       if (err == -EBUSY) {
                dev_err(&idev->dev, "too many uio devices\n");
-               retval = -EINVAL;
+               err = -EINVAL;
        }
-       mutex_unlock(&minor_lock);
-       return retval;
+
+       return err;
 }
 
 static void uio_free_minor(struct uio_device *idev)
 {
-       mutex_lock(&minor_lock);
-       idr_remove(&uio_idr, idev->minor);
-       mutex_unlock(&minor_lock);
+       xa_erase(&uio_devs, idev->minor);
 }
 
 /**
@@ -462,9 +454,7 @@ static int uio_open(struct inode *inode, struct file *filep)
        struct uio_listener *listener;
        int ret = 0;
 
-       mutex_lock(&minor_lock);
-       idev = idr_find(&uio_idr, iminor(inode));
-       mutex_unlock(&minor_lock);
+       idev = xa_load(&uio_devs, iminor(inode));
        if (!idev) {
                ret = -ENODEV;
                goto out;
@@ -1038,7 +1028,6 @@ static int __init uio_init(void)
 static void __exit uio_exit(void)
 {
        release_uio_class();
-       idr_destroy(&uio_idr);
 }
 
 module_init(uio_init)