From: Matthew Wilcox Date: Mon, 18 Feb 2019 22:47:01 +0000 (-0500) Subject: uio: Convert uio_idr to XArray X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=0f9443a4320a7d53c2550515d4e42028b1f9970f;p=users%2Fwilly%2Fxarray.git uio: Convert uio_idr to XArray Signed-off-by: Matthew Wilcox --- diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c index a57698985f9c..5e9a43fc3aed 100644 --- a/drivers/uio/uio.c +++ b/drivers/uio/uio.c @@ -18,23 +18,20 @@ #include #include #include -#include #include #include #include #include #include +#include #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)