From patchwork Mon Mar 18 21:17:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Wilcox X-Patchwork-Id: 10858573 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C9076139A for ; Mon, 18 Mar 2019 21:17:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AC58C25EA6 for ; Mon, 18 Mar 2019 21:17:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A105C29544; Mon, 18 Mar 2019 21:17:21 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.7 required=2.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F25802846F for ; Mon, 18 Mar 2019 21:17:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727502AbfCRVRU (ORCPT ); Mon, 18 Mar 2019 17:17:20 -0400 Received: from bombadil.infradead.org ([198.137.202.133]:51018 "EHLO bombadil.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727055AbfCRVRQ (ORCPT ); Mon, 18 Mar 2019 17:17:16 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20170209; h=References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=oodCQlEL9jYYoz9miivxR3kzdX2V86S4mOdqwO4vHec=; b=bUnKHZyTEwCXjFt3WpHX87J7O fi+4IoYSOSUasCNQ/7Q3b72zkFMllaQ1eplrBOd+J4vTT59Z5cSkX7XK7MBWKHvATx0e79c5Q+D9D j8Ecwbga4URkd0J154n3J7rmCvN/BcL9F6sT187ZLqy3WTiZUrjUODvBDzqxEwylgB3r5kUoBwq1M J0CFnOxcKB5xdU1cBlMxYptm9sZ076IiqiAhxPfzZyE3ou7IebU5Y+oTuF67NGcwPp6wJ1w1JJWx9 FqJU66eo6/Uk9yfLMAAkjz3AE/aKQUXKCdAmYLMIKlEiMtYLw8XUHBKSGWNF3kh/oQXdoRnaC92fV Vr2fG7AHg==; Received: from willy by bombadil.infradead.org with local (Exim 4.90_1 #2 (Red Hat Linux)) id 1h5zdD-0000uz-U7; Mon, 18 Mar 2019 21:17:15 +0000 From: Matthew Wilcox To: linux-usb@vger.kernel.org Cc: Matthew Wilcox Subject: [PATCH 3/4] usb: Convert usb_bus_idr to XArray Date: Mon, 18 Mar 2019 14:17:12 -0700 Message-Id: <20190318211713.3462-4-willy@infradead.org> X-Mailer: git-send-email 2.14.5 In-Reply-To: <20190318211713.3462-1-willy@infradead.org> References: <20190318211713.3462-1-willy@infradead.org> Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 Acked-by: Alan Stern --- 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;