Remove the usb_bus_idr_lock as it doesn't appear to be protecting
anything more than the built-in XArray lock does.

Signed-off-by: Matthew Wilcox <wi...@infradead.org>
---
 drivers/usb/core/devices.c      | 10 +++------
 drivers/usb/core/hcd.c          | 40 ++++++++-------------------------
 drivers/usb/core/usb.c          |  1 -
 drivers/usb/host/r8a66597-hcd.c |  4 +---
 drivers/usb/mon/mon_main.c      |  7 +++---
 include/linux/usb/hcd.h         |  3 +--
 6 files changed, 17 insertions(+), 48 deletions(-)

diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c
index 44f28a114c2b..f4a851713cf1 100644
--- a/drivers/usb/core/devices.c
+++ b/drivers/usb/core/devices.c
@@ -592,7 +592,7 @@ static ssize_t usb_device_read(struct file *file, char 
__user *buf,
        struct usb_bus *bus;
        ssize_t ret, total_written = 0;
        loff_t skip_bytes = *ppos;
-       int id;
+       unsigned long id;
 
        if (*ppos < 0)
                return -EINVAL;
@@ -601,9 +601,8 @@ static ssize_t usb_device_read(struct file *file, char 
__user *buf,
        if (!access_ok(buf, nbytes))
                return -EFAULT;
 
-       mutex_lock(&usb_bus_idr_lock);
        /* print devices for all busses */
-       idr_for_each_entry(&usb_bus_idr, bus, id) {
+       xa_for_each(&usb_busses, id, bus) {
                /* recurse through all children of the root hub */
                if (!bus_to_hcd(bus)->rh_registered)
                        continue;
@@ -611,13 +610,10 @@ static ssize_t usb_device_read(struct file *file, char 
__user *buf,
                ret = usb_device_dump(&buf, &nbytes, &skip_bytes, ppos,
                                      bus->root_hub, bus, 0, 0, 0);
                usb_unlock_device(bus->root_hub);
-               if (ret < 0) {
-                       mutex_unlock(&usb_bus_idr_lock);
+               if (ret < 0)
                        return ret;
-               }
                total_written += ret;
        }
-       mutex_unlock(&usb_bus_idr_lock);
        return total_written;
 }
 
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 3189181bb628..dac70d27abc7 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -79,15 +79,11 @@ unsigned long usb_hcds_loaded;
 EXPORT_SYMBOL_GPL(usb_hcds_loaded);
 
 /* host controllers we manage */
-DEFINE_IDR (usb_bus_idr);
-EXPORT_SYMBOL_GPL (usb_bus_idr);
+DEFINE_XARRAY_ALLOC1(usb_busses);
+EXPORT_SYMBOL_GPL(usb_busses);
 
 /* used when allocating bus numbers */
-#define USB_MAXBUS             64
-
-/* used when updating list of hcds */
-DEFINE_MUTEX(usb_bus_idr_lock);        /* exported only for usbfs */
-EXPORT_SYMBOL_GPL (usb_bus_idr_lock);
+#define USB_BUS_LIMIT          XA_LIMIT(0, 63)
 
 /* used for controlling access to virtual root hubs */
 static DEFINE_SPINLOCK(hcd_root_hub_lock);
@@ -1010,27 +1006,20 @@ static void usb_bus_init (struct usb_bus *bus)
  */
 static int usb_register_bus(struct usb_bus *bus)
 {
-       int result = -E2BIG;
-       int busnum;
+       int err;
 
-       mutex_lock(&usb_bus_idr_lock);
-       busnum = idr_alloc(&usb_bus_idr, bus, 1, USB_MAXBUS, GFP_KERNEL);
-       if (busnum < 0) {
+       err = xa_alloc(&usb_busses, &bus->busnum, bus, USB_BUS_LIMIT,
+                       GFP_KERNEL);
+       if (err < 0) {
                pr_err("%s: failed to get bus number\n", usbcore_name);
-               goto error_find_busnum;
+               return -E2BIG;
        }
-       bus->busnum = busnum;
-       mutex_unlock(&usb_bus_idr_lock);
 
        usb_notify_add_bus(bus);
 
        dev_info (bus->controller, "new USB bus registered, assigned bus "
                  "number %d\n", bus->busnum);
        return 0;
-
-error_find_busnum:
-       mutex_unlock(&usb_bus_idr_lock);
-       return result;
 }
 
 /**
@@ -1050,9 +1039,7 @@ static void usb_deregister_bus (struct usb_bus *bus)
         * controller code, as well as having it call this when cleaning
         * itself up
         */
-       mutex_lock(&usb_bus_idr_lock);
-       idr_remove(&usb_bus_idr, bus->busnum);
-       mutex_unlock(&usb_bus_idr_lock);
+       xa_erase(&usb_busses, bus->busnum);
 
        usb_notify_remove_bus(bus);
 }
@@ -1080,12 +1067,9 @@ static int register_root_hub(struct usb_hcd *hcd)
        set_bit (devnum, usb_dev->bus->devmap.devicemap);
        usb_set_device_state(usb_dev, USB_STATE_ADDRESS);
 
-       mutex_lock(&usb_bus_idr_lock);
-
        usb_dev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);
        retval = usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE);
        if (retval != sizeof usb_dev->descriptor) {
-               mutex_unlock(&usb_bus_idr_lock);
                dev_dbg (parent_dev, "can't read %s device descriptor %d\n",
                                dev_name(&usb_dev->dev), retval);
                return (retval < 0) ? retval : -EMSGSIZE;
@@ -1096,7 +1080,6 @@ static int register_root_hub(struct usb_hcd *hcd)
                if (!retval) {
                        usb_dev->lpm_capable = usb_device_supports_lpm(usb_dev);
                } else if (usb_dev->speed >= USB_SPEED_SUPER) {
-                       mutex_unlock(&usb_bus_idr_lock);
                        dev_dbg(parent_dev, "can't read %s bos descriptor %d\n",
                                        dev_name(&usb_dev->dev), retval);
                        return retval;
@@ -1116,7 +1099,6 @@ static int register_root_hub(struct usb_hcd *hcd)
                if (HCD_DEAD(hcd))
                        usb_hc_died (hcd);      /* This time clean up */
        }
-       mutex_unlock(&usb_bus_idr_lock);
 
        return retval;
 }
@@ -2905,9 +2887,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
 #ifdef CONFIG_PM
        cancel_work_sync(&hcd->wakeup_work);
 #endif
-       mutex_lock(&usb_bus_idr_lock);
        usb_disconnect(&rhdev);         /* Sets rhdev to NULL */
-       mutex_unlock(&usb_bus_idr_lock);
 err_register_root_hub:
        hcd->rh_pollable = 0;
        clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
@@ -2966,9 +2946,7 @@ void usb_remove_hcd(struct usb_hcd *hcd)
        cancel_work_sync(&hcd->wakeup_work);
 #endif
 
-       mutex_lock(&usb_bus_idr_lock);
        usb_disconnect(&rhdev);         /* Sets rhdev to NULL */
-       mutex_unlock(&usb_bus_idr_lock);
 
        /*
         * tasklet_kill() isn't needed here because:
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 7fcb9f782931..b41090a80df0 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -1274,7 +1274,6 @@ static void __exit usb_exit(void)
        bus_unregister(&usb_bus_type);
        usb_acpi_unregister();
        usb_debugfs_cleanup();
-       idr_destroy(&usb_bus_idr);
 }
 
 subsys_initcall(usb_init);
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
index 42668aeca57c..4f9c6af00548 100644
--- a/drivers/usb/host/r8a66597-hcd.c
+++ b/drivers/usb/host/r8a66597-hcd.c
@@ -2093,13 +2093,11 @@ static void r8a66597_check_detect_child(struct r8a66597 
*r8a66597,
 
        memset(now_map, 0, sizeof(now_map));
 
-       mutex_lock(&usb_bus_idr_lock);
-       bus = idr_find(&usb_bus_idr, hcd->self.busnum);
+       bus = xa_load(&usb_busses, hcd->self.busnum);
        if (bus && bus->root_hub) {
                collect_usb_address_map(bus->root_hub, now_map);
                update_usb_address_map(r8a66597, bus->root_hub, now_map);
        }
-       mutex_unlock(&usb_bus_idr_lock);
 }
 
 static int r8a66597_hub_status_data(struct usb_hcd *hcd, char *buf)
diff --git a/drivers/usb/mon/mon_main.c b/drivers/usb/mon/mon_main.c
index 9812d102a005..3d7b35559d15 100644
--- a/drivers/usb/mon/mon_main.c
+++ b/drivers/usb/mon/mon_main.c
@@ -350,7 +350,8 @@ struct mon_bus *mon_bus_lookup(unsigned int num)
 static int __init mon_init(void)
 {
        struct usb_bus *ubus;
-       int rc, id;
+       unsigned long id;
+       int rc;
 
        if ((rc = mon_text_init()) != 0)
                goto err_text;
@@ -366,11 +367,9 @@ static int __init mon_init(void)
        }
        // MOD_INC_USE_COUNT(which_module?);
 
-       mutex_lock(&usb_bus_idr_lock);
-       idr_for_each_entry(&usb_bus_idr, ubus, id)
+       xa_for_each(&usb_busses, id, ubus)
                mon_bus_init(ubus);
        usb_register_notify(&mon_nb);
-       mutex_unlock(&usb_bus_idr_lock);
        return 0;
 
 err_reg:
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
index 695931b03684..929e11a91b47 100644
--- a/include/linux/usb/hcd.h
+++ b/include/linux/usb/hcd.h
@@ -644,8 +644,7 @@ extern void usb_set_device_state(struct usb_device *udev,
 
 /* exported only within usbcore */
 
-extern struct idr usb_bus_idr;
-extern struct mutex usb_bus_idr_lock;
+extern struct xarray usb_busses;
 extern wait_queue_head_t usb_kill_urb_queue;
 
 
-- 
2.20.1

Reply via email to