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 <willy@xxxxxxxxxxxxx> --- 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