From patchwork Mon Mar 18 21:17:10 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Wilcox X-Patchwork-Id: 10858571 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 4B00E17E9 for ; Mon, 18 Mar 2019 21:17:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3045C25EA6 for ; Mon, 18 Mar 2019 21:17:20 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2EF5F28796; Mon, 18 Mar 2019 21:17:20 +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 0E74A29547 for ; Mon, 18 Mar 2019 21:17:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727390AbfCRVRQ (ORCPT ); Mon, 18 Mar 2019 17:17:16 -0400 Received: from bombadil.infradead.org ([198.137.202.133]:51014 "EHLO bombadil.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726832AbfCRVRQ (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=wRMMG8sk6LAsoY+FLbmbsMtsdAhL+8QTTR5ERl8JOd8=; b=RpYtq4yJdTI13T9XYUvysLqIZ mszdalpK08OjVkMKcV+0kg4oDeGcagsbHy0mwQsuETA5qYy0cC/8GDxnHQjotLAaHEzzj5NY+RYb5 Z68WO46byJJtW2aNvB0+FXu4LgrKp0t0Tq5LrGyidNj6NpVi8GJ+VktSwBQmr0v0COEKER/7cnB7U puV0UoLsK3+3pzPnFdrNX2z4o68bsT+u2J8rpHE4jBz+gm+KIsKyHfERPTZ2bl9HsI732JzQSmait VzO0Q2gzE52Ic3Ndi7tlu8BnFtwwqrXlKm1CSsoSNl4jcIQKsVDybCoKMDhFTLNyT2TMJM0OAFiXP 7BcR8DIXA==; Received: from willy by bombadil.infradead.org with local (Exim 4.90_1 #2 (Red Hat Linux)) id 1h5zdD-0000uq-Ka; Mon, 18 Mar 2019 21:17:15 +0000 From: Matthew Wilcox To: linux-usb@vger.kernel.org Cc: Matthew Wilcox Subject: [PATCH 1/4] usb: Convert xhci-mem to XArray Date: Mon, 18 Mar 2019 14:17:10 -0700 Message-Id: <20190318211713.3462-2-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 The XArray API is a better fit for xhci than the radix tree API was, to the point where we can remove the wrappers around the radix tree and just call the XArray APIs directly. Signed-off-by: Matthew Wilcox --- drivers/usb/host/xhci-mem.c | 86 +++++++++++++------------------------ drivers/usb/host/xhci.h | 5 ++- 2 files changed, 33 insertions(+), 58 deletions(-) diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index cf5e17962179..0f58a0f9a20f 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -151,86 +151,59 @@ static void xhci_link_rings(struct xhci_hcd *xhci, struct xhci_ring *ring, } /* - * We need a radix tree for mapping physical addresses of TRBs to which stream - * ID they belong to. We need to do this because the host controller won't tell + * We need to map physical addresses of TRBs to the stream ID they belong to. + * We need to do this because the host controller won't tell * us which stream ring the TRB came from. We could store the stream ID in an * event data TRB, but that doesn't help us for the cancellation case, since the * endpoint may stop before it reaches that event data TRB. * - * The radix tree maps the upper portion of the TRB DMA address to a ring + * The xarray maps the upper portion of the TRB DMA address to a ring * segment that has the same upper portion of DMA addresses. For example, say I * have segments of size 1KB, that are always 1KB aligned. A segment may * start at 0x10c91000 and end at 0x10c913f0. If I use the upper 10 bits, the - * key to the stream ID is 0x43244. I can use the DMA address of the TRB to - * pass the radix tree a key to get the right stream ID: + * index of the stream ID is 0x43244. I can use the DMA address of the TRB as + * the xarray index to get the right stream ID: * * 0x10c90fff >> 10 = 0x43243 * 0x10c912c0 >> 10 = 0x43244 * 0x10c91400 >> 10 = 0x43245 * * Obviously, only those TRBs with DMA addresses that are within the segment - * will make the radix tree return the stream ID for that ring. + * will make the xarray return the stream ID for that ring. * - * Caveats for the radix tree: + * Caveats for the xarray: * - * The radix tree uses an unsigned long as a key pair. On 32-bit systems, an + * The xarray uses an unsigned long for the index. On 32-bit systems, an * unsigned long will be 32-bits; on a 64-bit system an unsigned long will be * 64-bits. Since we only request 32-bit DMA addresses, we can use that as the - * key on 32-bit or 64-bit systems (it would also be fine if we asked for 64-bit - * PCI DMA addresses on a 64-bit system). There might be a problem on 32-bit - * extended systems (where the DMA address can be bigger than 32-bits), + * index on 32-bit or 64-bit systems (it would also be fine if we asked for + * 64-bit PCI DMA addresses on a 64-bit system). There might be a problem on + * 32-bit extended systems (where the DMA address can be bigger than 32-bits), * if we allow the PCI dma mask to be bigger than 32-bits. So don't do that. */ -static int xhci_insert_segment_mapping(struct radix_tree_root *trb_address_map, - struct xhci_ring *ring, - struct xhci_segment *seg, - gfp_t mem_flags) -{ - unsigned long key; - int ret; - key = (unsigned long)(seg->dma >> TRB_SEGMENT_SHIFT); - /* Skip any segments that were already added. */ - if (radix_tree_lookup(trb_address_map, key)) - return 0; - - ret = radix_tree_maybe_preload(mem_flags); - if (ret) - return ret; - ret = radix_tree_insert(trb_address_map, - key, ring); - radix_tree_preload_end(); - return ret; -} - -static void xhci_remove_segment_mapping(struct radix_tree_root *trb_address_map, - struct xhci_segment *seg) +static unsigned long trb_index(dma_addr_t dma) { - unsigned long key; - - key = (unsigned long)(seg->dma >> TRB_SEGMENT_SHIFT); - if (radix_tree_lookup(trb_address_map, key)) - radix_tree_delete(trb_address_map, key); + return (unsigned long)(dma >> TRB_SEGMENT_SHIFT); } static int xhci_update_stream_segment_mapping( - struct radix_tree_root *trb_address_map, struct xhci_ring *ring, struct xhci_segment *first_seg, struct xhci_segment *last_seg, - gfp_t mem_flags) + gfp_t gfp) { + struct xarray *address_map = ring->trb_address_map; struct xhci_segment *seg; struct xhci_segment *failed_seg; int ret; - if (WARN_ON_ONCE(trb_address_map == NULL)) + if (WARN_ON_ONCE(address_map == NULL)) return 0; seg = first_seg; do { - ret = xhci_insert_segment_mapping(trb_address_map, - ring, seg, mem_flags); + ret = xa_insert(address_map, trb_index(seg->dma), ring, gfp); if (ret) goto remove_streams; if (seg == last_seg) @@ -244,7 +217,7 @@ static int xhci_update_stream_segment_mapping( failed_seg = seg; seg = first_seg; do { - xhci_remove_segment_mapping(trb_address_map, seg); + xa_erase(address_map, trb_index(seg->dma)); if (seg == failed_seg) return ret; seg = seg->next; @@ -256,21 +229,22 @@ static int xhci_update_stream_segment_mapping( static void xhci_remove_stream_mapping(struct xhci_ring *ring) { struct xhci_segment *seg; + struct xarray *trb_address_map = ring->trb_address_map; - if (WARN_ON_ONCE(ring->trb_address_map == NULL)) + if (WARN_ON_ONCE(trb_address_map == NULL)) return; seg = ring->first_seg; do { - xhci_remove_segment_mapping(ring->trb_address_map, seg); + xa_erase(trb_address_map, trb_index(seg->dma)); seg = seg->next; } while (seg != ring->first_seg); } static int xhci_update_stream_mapping(struct xhci_ring *ring, gfp_t mem_flags) { - return xhci_update_stream_segment_mapping(ring->trb_address_map, ring, - ring->first_seg, ring->last_seg, mem_flags); + return xhci_update_stream_segment_mapping(ring, ring->first_seg, + ring->last_seg, mem_flags); } /* XXX: Do we need the hcd structure in all these functions? */ @@ -434,8 +408,8 @@ int xhci_ring_expansion(struct xhci_hcd *xhci, struct xhci_ring *ring, return -ENOMEM; if (ring->type == TYPE_STREAM) - ret = xhci_update_stream_segment_mapping(ring->trb_address_map, - ring, first, last, flags); + ret = xhci_update_stream_segment_mapping(ring, first, last, + flags); if (ret) { struct xhci_segment *next; do { @@ -578,8 +552,8 @@ struct xhci_ring *xhci_dma_to_transfer_ring( u64 address) { if (ep->ep_state & EP_HAS_STREAMS) - return radix_tree_lookup(&ep->stream_info->trb_address_map, - address >> TRB_SEGMENT_SHIFT); + return xa_load(&ep->stream_info->trb_address_map, + trb_index(address)); return ep->ring; } @@ -660,10 +634,10 @@ struct xhci_stream_info *xhci_alloc_stream_info(struct xhci_hcd *xhci, if (!stream_info->free_streams_command) goto cleanup_ctx; - INIT_RADIX_TREE(&stream_info->trb_address_map, GFP_ATOMIC); + xa_init(&stream_info->trb_address_map); /* Allocate rings for all the streams that the driver will use, - * and add their segment DMA addresses to the radix tree. + * and add their segment DMA addresses to the map. * Stream 0 is reserved. */ @@ -2410,7 +2384,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) * Initialize the ring segment pool. The ring must be a contiguous * structure comprised of TRBs. The TRBs must be 16 byte aligned, * however, the command ring segment needs 64-byte aligned segments - * and our use of dma addresses in the trb_address_map radix tree needs + * and our use of dma addresses in the trb_address_map xarray needs * TRB_SEGMENT_SIZE alignment, so we pick the greater alignment need. */ xhci->segment_pool = dma_pool_create("xHCI ring segments", dev, diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 652dc36e3012..da2b4abec11a 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -841,7 +842,7 @@ struct xhci_stream_info { unsigned int num_stream_ctxs; dma_addr_t ctx_array_dma; /* For mapping physical TRB addresses to segments in stream rings */ - struct radix_tree_root trb_address_map; + struct xarray trb_address_map; struct xhci_command *free_streams_command; }; @@ -1592,7 +1593,7 @@ struct xhci_ring { unsigned int bounce_buf_len; enum xhci_ring_type type; bool last_td_was_short; - struct radix_tree_root *trb_address_map; + struct xarray *trb_address_map; }; struct xhci_erst_entry { From patchwork Mon Mar 18 21:17:11 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Wilcox X-Patchwork-Id: 10858569 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 052611575 for ; Mon, 18 Mar 2019 21:17:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E04B82954A for ; Mon, 18 Mar 2019 21:17:19 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D4EF829554; Mon, 18 Mar 2019 21:17:19 +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 667482954A for ; Mon, 18 Mar 2019 21:17:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727418AbfCRVRQ (ORCPT ); Mon, 18 Mar 2019 17:17:16 -0400 Received: from bombadil.infradead.org ([198.137.202.133]:51016 "EHLO bombadil.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727000AbfCRVRQ (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=dPx0k4stXyozImbCyxz+jDZYAFn8twGzr4GtOxTTEuU=; b=cDRf04NiGDikO/oFBFl0JsRoK fzSX/um3IkmU5Jb38YCbtq0Vv97zCaH3qFDSb8Dfh1iuqQrZW7DQdSxQTkT/tdA1pVTxiWaqcTbHd +vo2s6+cUdUkqHjT3WFhmtguaednvP0Rgo1ZVOBYFi923SNO9Ad0O5bNnQGcGXhiGstENqIl+M759 XUuQBTp66tvEclIZCDYUcJi4jz96MMBnOZFhetqDySB3nrlC9QoI98o4k7BvkLQWcKQ4iS6S8IPOX 4EVR0SW8rTzqlfB16SRIpc+0SrGH37C3yuEbbL3t44cPgv7wnx+9PNm8Uu/WKrmlQXpzNM5UfHwVM wRSyrvXaw==; Received: from willy by bombadil.infradead.org with local (Exim 4.90_1 #2 (Red Hat Linux)) id 1h5zdD-0000uu-PK; Mon, 18 Mar 2019 21:17:15 +0000 From: Matthew Wilcox To: linux-usb@vger.kernel.org Cc: Matthew Wilcox Subject: [PATCH 2/4] cdc-acm: Convert acm_minors to XArray Date: Mon, 18 Mar 2019 14:17:11 -0700 Message-Id: <20190318211713.3462-3-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 Signed-off-by: Matthew Wilcox --- drivers/usb/class/cdc-acm.c | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 739f8960811a..28eb9a898b4a 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -47,7 +47,7 @@ static struct usb_driver acm_driver; static struct tty_driver *acm_tty_driver; -static DEFINE_IDR(acm_minors); +static DEFINE_XARRAY_ALLOC(acm_minors); static DEFINE_MUTEX(acm_minors_lock); static void acm_tty_set_termios(struct tty_struct *tty, @@ -66,7 +66,7 @@ static struct acm *acm_get_by_minor(unsigned int minor) struct acm *acm; mutex_lock(&acm_minors_lock); - acm = idr_find(&acm_minors, minor); + acm = xa_load(&acm_minors, minor); if (acm) { mutex_lock(&acm->mutex); if (acm->disconnected) { @@ -86,20 +86,15 @@ static struct acm *acm_get_by_minor(unsigned int minor) */ static int acm_alloc_minor(struct acm *acm) { - int minor; - - mutex_lock(&acm_minors_lock); - minor = idr_alloc(&acm_minors, acm, 0, ACM_TTY_MINORS, GFP_KERNEL); - mutex_unlock(&acm_minors_lock); - - return minor; + return xa_alloc(&acm_minors, &acm->minor, acm, + XA_LIMIT(0, ACM_TTY_MINORS - 1), GFP_KERNEL); } /* Release the minor number associated with 'acm'. */ static void acm_release_minor(struct acm *acm) { mutex_lock(&acm_minors_lock); - idr_remove(&acm_minors, acm->minor); + xa_erase(&acm_minors, acm->minor); mutex_unlock(&acm_minors_lock); } @@ -1130,7 +1125,6 @@ static int acm_probe(struct usb_interface *intf, struct usb_device *usb_dev = interface_to_usbdev(intf); struct usb_cdc_parsed_header h; struct acm *acm; - int minor; int ctrlsize, readsize; u8 *buf; int call_intf_num = -1; @@ -1302,9 +1296,10 @@ static int acm_probe(struct usb_interface *intf, tty_port_init(&acm->port); acm->port.ops = &acm_port_ops; - minor = acm_alloc_minor(acm); - if (minor < 0) - goto alloc_fail1; + rv = acm_alloc_minor(acm); + if (rv < 0) + goto alloc_fail0; + rv = -ENOMEM; ctrlsize = usb_endpoint_maxp(epctrl); readsize = usb_endpoint_maxp(epread) * @@ -1313,7 +1308,6 @@ static int acm_probe(struct usb_interface *intf, acm->writesize = usb_endpoint_maxp(epwrite) * 20; acm->control = control_interface; acm->data = data_interface; - acm->minor = minor; acm->dev = usb_dev; if (h.usb_cdc_acm_descriptor) acm->ctrl_caps = h.usb_cdc_acm_descriptor->bmCapabilities; @@ -1450,7 +1444,7 @@ static int acm_probe(struct usb_interface *intf, acm->nb_index = 0; acm->nb_size = 0; - dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor); + dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", acm->minor); acm->line.dwDTERate = cpu_to_le32(9600); acm->line.bDataBits = 8; @@ -1460,8 +1454,8 @@ static int acm_probe(struct usb_interface *intf, usb_set_intfdata(data_interface, acm); usb_get_intf(control_interface); - tty_dev = tty_port_register_device(&acm->port, acm_tty_driver, minor, - &control_interface->dev); + tty_dev = tty_port_register_device(&acm->port, acm_tty_driver, + acm->minor, &control_interface->dev); if (IS_ERR(tty_dev)) { rv = PTR_ERR(tty_dev); goto alloc_fail6; @@ -1496,6 +1490,8 @@ static int acm_probe(struct usb_interface *intf, alloc_fail2: usb_free_coherent(usb_dev, ctrlsize, acm->ctrl_buffer, acm->ctrl_dma); alloc_fail1: + acm_release_minor(acm); +alloc_fail0: tty_port_put(&acm->port); alloc_fail: return rv; @@ -1986,7 +1982,6 @@ static void __exit acm_exit(void) usb_deregister(&acm_driver); tty_unregister_driver(acm_tty_driver); put_tty_driver(acm_tty_driver); - idr_destroy(&acm_minors); } module_init(acm_init); 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; From patchwork Mon Mar 18 21:17:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Wilcox X-Patchwork-Id: 10858567 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 0C1341575 for ; Mon, 18 Mar 2019 21:17:19 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E832B28796 for ; Mon, 18 Mar 2019 21:17:18 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E6B1F2905B; Mon, 18 Mar 2019 21:17:18 +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 65A4C294F0 for ; Mon, 18 Mar 2019 21:17:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727422AbfCRVRQ (ORCPT ); Mon, 18 Mar 2019 17:17:16 -0400 Received: from bombadil.infradead.org ([198.137.202.133]:51020 "EHLO bombadil.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727202AbfCRVRQ (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=LosKC8rr3Iby31JkBz3FPdvI2FsSt37/CGzxL6YJ0pU=; b=mQm0HEqjx7eo/pDP9QYyuGl+t dMNx44We2hu3z6ZqtF9/wEobLMj+np33xC3k/PyCV/szfUcRsPq/cur8OQMWaa/FTPCSINURdAlRq AixcjNhAtLcPnkPfQAULONKyxFO11qNaCrxP+3ULkgE+6EkEZ9gwr2XoGDwyb5fdf5XcQlSJ4O+dg 9Ro+agfoLwgn9aclXpTgsQcI2ntfyIHmXP334/gVf5YAozZmutWPtcq6eeq/zavdDUWodXCF07MqI sX3zthzwTl6V3K2TJiv2MT/3aqF9yT3bZH71Fm6qhZRx4xGVqmr6TSGEd63NdJjosIRch+B0sirIb M8vx4MU+w==; Received: from willy by bombadil.infradead.org with local (Exim 4.90_1 #2 (Red Hat Linux)) id 1h5zdE-0000v6-2l; Mon, 18 Mar 2019 21:17:16 +0000 From: Matthew Wilcox To: linux-usb@vger.kernel.org Cc: Matthew Wilcox Subject: [PATCH 4/4] usb/serial: Convert serial_minors to XArray Date: Mon, 18 Mar 2019 14:17:13 -0700 Message-Id: <20190318211713.3462-5-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 Signed-off-by: Matthew Wilcox --- drivers/usb/serial/usb-serial.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 7e89efbf2c28..ad8b9cb17ca5 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -49,7 +49,7 @@ drivers depend on it. */ -static DEFINE_IDR(serial_minors); +static DEFINE_XARRAY_ALLOC(serial_minors); static DEFINE_MUTEX(table_lock); static LIST_HEAD(usb_serial_driver_list); @@ -64,7 +64,7 @@ struct usb_serial_port *usb_serial_port_get_by_minor(unsigned minor) struct usb_serial_port *port; mutex_lock(&table_lock); - port = idr_find(&serial_minors, minor); + port = xa_load(&serial_minors, minor); if (!port) goto exit; @@ -85,18 +85,18 @@ static int allocate_minors(struct usb_serial *serial, int num_ports) { struct usb_serial_port *port; unsigned int i, j; - int minor; + int err; dev_dbg(&serial->interface->dev, "%s %d\n", __func__, num_ports); mutex_lock(&table_lock); for (i = 0; i < num_ports; ++i) { port = serial->port[i]; - minor = idr_alloc(&serial_minors, port, 0, - USB_SERIAL_TTY_MINORS, GFP_KERNEL); - if (minor < 0) + err = xa_alloc(&serial_minors, &port->minor, port, + XA_LIMIT(0, USB_SERIAL_TTY_MINORS - 1), + GFP_KERNEL); + if (err < 0) goto error; - port->minor = minor; port->port_number = i; } serial->minors_reserved = 1; @@ -105,9 +105,9 @@ static int allocate_minors(struct usb_serial *serial, int num_ports) error: /* unwind the already allocated minors */ for (j = 0; j < i; ++j) - idr_remove(&serial_minors, serial->port[j]->minor); + xa_erase(&serial_minors, serial->port[j]->minor); mutex_unlock(&table_lock); - return minor; + return err; } static void release_minors(struct usb_serial *serial) @@ -116,7 +116,7 @@ static void release_minors(struct usb_serial *serial) mutex_lock(&table_lock); for (i = 0; i < serial->num_ports; ++i) - idr_remove(&serial_minors, serial->port[i]->minor); + xa_erase(&serial_minors, serial->port[i]->minor); mutex_unlock(&table_lock); serial->minors_reserved = 0; } @@ -1271,7 +1271,6 @@ static void __exit usb_serial_exit(void) tty_unregister_driver(usb_serial_tty_driver); put_tty_driver(usb_serial_tty_driver); bus_unregister(&usb_serial_bus_type); - idr_destroy(&serial_minors); }