From patchwork Wed Jan 17 20:21:42 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Matthew Wilcox (Oracle)" X-Patchwork-Id: 10171007 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 9DAC4603B5 for ; Wed, 17 Jan 2018 20:33:12 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8F72E207A7 for ; Wed, 17 Jan 2018 20:33:12 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 83A6B21BED; Wed, 17 Jan 2018 20:33:12 +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=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=unavailable 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 F2A30207A7 for ; Wed, 17 Jan 2018 20:33:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754588AbeAQUdE (ORCPT ); Wed, 17 Jan 2018 15:33:04 -0500 Received: from bombadil.infradead.org ([65.50.211.133]:56971 "EHLO bombadil.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753942AbeAQUW7 (ORCPT ); Wed, 17 Jan 2018 15:22:59 -0500 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=dMmQH2kHjjOa16pkYOdU1wgqtUGiT/uWNr9dt65hu+s=; b=Z5HwbJq+WvZ17baDIq63sXVlp JVwvHXByxRp4BFajgsSY2DUEvl80qyvZvhEcU3ZmC2gRpCdmiUKDD/+ux6zHxZ9rqc7p1rxJo5nz8 XP+PIn2FFUC8y1gxVF+6B2/MWY0wv6MWZLTH/vZK89LybM/5sZSN4YauDexE1DwhoJoi5gXlTCY1F jkSOL5vf/vc5S4Mvkz0kSEfE/TlhtHWa1x0n+3uJYohkJnWNOsT/FJ2OOBw49wMJIvBTYvv5e23zQ w+ejeudjqCGq7mWLWkV745jkOevwKzzZCIUMysgMKx+TTPoseudlmEaiVvPWnoJjLEUIP2eF42NVW 3pUb2wDjw==; Received: from willy by bombadil.infradead.org with local (Exim 4.89 #1 (Red Hat Linux)) id 1ebuEc-0006Du-Dz; Wed, 17 Jan 2018 20:22:58 +0000 From: Matthew Wilcox To: linux-kernel@vger.kernel.org Cc: Matthew Wilcox , linux-mm@kvack.org, linux-fsdevel@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net, linux-nilfs@vger.kernel.org, linux-btrfs@vger.kernel.org, linux-xfs@vger.kernel.org, linux-usb@vger.kernel.org, Bjorn Andersson , Stefano Stabellini , iommu@lists.linux-foundation.org, linux-remoteproc@vger.kernel.org, linux-s390@vger.kernel.org, intel-gfx@lists.freedesktop.org, cgroups@vger.kernel.org, linux-sh@vger.kernel.org, David Howells Subject: [PATCH v6 78/99] sh: intc: Convert to XArray Date: Wed, 17 Jan 2018 12:21:42 -0800 Message-Id: <20180117202203.19756-79-willy@infradead.org> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180117202203.19756-1-willy@infradead.org> References: <20180117202203.19756-1-willy@infradead.org> Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Matthew Wilcox The radix tree was being protected by a raw spinlock. I believe that was not necessary, and the new internal regular spinlock will be adequate for this array. Signed-off-by: Matthew Wilcox --- drivers/sh/intc/core.c | 9 ++---- drivers/sh/intc/internals.h | 5 ++-- drivers/sh/intc/virq.c | 72 +++++++++++++-------------------------------- 3 files changed, 25 insertions(+), 61 deletions(-) diff --git a/drivers/sh/intc/core.c b/drivers/sh/intc/core.c index 8e72bcbd3d6d..356a423d9dcb 100644 --- a/drivers/sh/intc/core.c +++ b/drivers/sh/intc/core.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include "internals.h" @@ -78,11 +77,8 @@ static void __init intc_register_irq(struct intc_desc *desc, struct intc_handle_int *hp; struct irq_data *irq_data; unsigned int data[2], primary; - unsigned long flags; - raw_spin_lock_irqsave(&intc_big_lock, flags); - radix_tree_insert(&d->tree, enum_id, intc_irq_xlate_get(irq)); - raw_spin_unlock_irqrestore(&intc_big_lock, flags); + xa_store(&d->array, enum_id, intc_irq_xlate_get(irq), GFP_ATOMIC); /* * Prefer single interrupt source bitmap over other combinations: @@ -196,8 +192,7 @@ int __init register_intc_controller(struct intc_desc *desc) INIT_LIST_HEAD(&d->list); list_add_tail(&d->list, &intc_list); - raw_spin_lock_init(&d->lock); - INIT_RADIX_TREE(&d->tree, GFP_ATOMIC); + xa_init(&d->array); d->index = nr_intc_controllers; diff --git a/drivers/sh/intc/internals.h b/drivers/sh/intc/internals.h index fa73c173b56a..9b6fd07e99a6 100644 --- a/drivers/sh/intc/internals.h +++ b/drivers/sh/intc/internals.h @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #define _INTC_MK(fn, mode, addr_e, addr_d, width, shift) \ @@ -54,8 +54,7 @@ struct intc_subgroup_entry { struct intc_desc_int { struct list_head list; struct device dev; - struct radix_tree_root tree; - raw_spinlock_t lock; + struct xarray array; unsigned int index; unsigned long *reg; #ifdef CONFIG_SMP diff --git a/drivers/sh/intc/virq.c b/drivers/sh/intc/virq.c index a638c3048207..801c9c8b7556 100644 --- a/drivers/sh/intc/virq.c +++ b/drivers/sh/intc/virq.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include "internals.h" @@ -27,10 +26,7 @@ struct intc_virq_list { #define for_each_virq(entry, head) \ for (entry = head; entry; entry = entry->next) -/* - * Tags for the radix tree - */ -#define INTC_TAG_VIRQ_NEEDS_ALLOC 0 +#define INTC_TAG_VIRQ_NEEDS_ALLOC XA_TAG_0 void intc_irq_xlate_set(unsigned int irq, intc_enum id, struct intc_desc_int *d) { @@ -54,23 +50,18 @@ int intc_irq_lookup(const char *chipname, intc_enum enum_id) int irq = -1; list_for_each_entry(d, &intc_list, list) { - int tagged; - if (strcmp(d->chip.name, chipname) != 0) continue; /* * Catch early lookups for subgroup VIRQs that have not - * yet been allocated an IRQ. This already includes a - * fast-path out if the tree is untagged, so there is no - * need to explicitly test the root tree. + * yet been allocated an IRQ. */ - tagged = radix_tree_tag_get(&d->tree, enum_id, - INTC_TAG_VIRQ_NEEDS_ALLOC); - if (unlikely(tagged)) + if (unlikely(xa_get_tag(&d->array, enum_id, + INTC_TAG_VIRQ_NEEDS_ALLOC))) break; - ptr = radix_tree_lookup(&d->tree, enum_id); + ptr = xa_load(&d->array, enum_id); if (ptr) { irq = ptr - intc_irq_xlate; break; @@ -148,22 +139,16 @@ static void __init intc_subgroup_init_one(struct intc_desc *desc, { struct intc_map_entry *mapped; unsigned int pirq; - unsigned long flags; int i; - mapped = radix_tree_lookup(&d->tree, subgroup->parent_id); - if (!mapped) { - WARN_ON(1); + mapped = xa_load(&d->array, subgroup->parent_id); + if (WARN_ON(!mapped)) return; - } pirq = mapped - intc_irq_xlate; - raw_spin_lock_irqsave(&d->lock, flags); - for (i = 0; i < ARRAY_SIZE(subgroup->enum_ids); i++) { struct intc_subgroup_entry *entry; - int err; if (!subgroup->enum_ids[i]) continue; @@ -176,15 +161,14 @@ static void __init intc_subgroup_init_one(struct intc_desc *desc, entry->enum_id = subgroup->enum_ids[i]; entry->handle = intc_subgroup_data(subgroup, d, i); - err = radix_tree_insert(&d->tree, entry->enum_id, entry); - if (unlikely(err < 0)) + if (xa_err(xa_store(&d->array, entry->enum_id, entry, + GFP_NOWAIT))) { + kfree(entry); break; - - radix_tree_tag_set(&d->tree, entry->enum_id, + } + xa_set_tag(&d->array, entry->enum_id, INTC_TAG_VIRQ_NEEDS_ALLOC); } - - raw_spin_unlock_irqrestore(&d->lock, flags); } void __init intc_subgroup_init(struct intc_desc *desc, struct intc_desc_int *d) @@ -201,28 +185,16 @@ void __init intc_subgroup_init(struct intc_desc *desc, struct intc_desc_int *d) static void __init intc_subgroup_map(struct intc_desc_int *d) { struct intc_subgroup_entry *entries[32]; - unsigned long flags; unsigned int nr_found; int i; - raw_spin_lock_irqsave(&d->lock, flags); - -restart: - nr_found = radix_tree_gang_lookup_tag_slot(&d->tree, - (void ***)entries, 0, ARRAY_SIZE(entries), - INTC_TAG_VIRQ_NEEDS_ALLOC); + nr_found = xa_extract(&d->array, (void **)entries, 0, ULONG_MAX, + ARRAY_SIZE(entries), INTC_TAG_VIRQ_NEEDS_ALLOC); for (i = 0; i < nr_found; i++) { - struct intc_subgroup_entry *entry; - int irq; + struct intc_subgroup_entry *entry = entries[i]; + int irq = irq_alloc_desc(numa_node_id()); - entry = radix_tree_deref_slot((void **)entries[i]); - if (unlikely(!entry)) - continue; - if (radix_tree_deref_retry(entry)) - goto restart; - - irq = irq_alloc_desc(numa_node_id()); if (unlikely(irq < 0)) { pr_err("no more free IRQs, bailing..\n"); break; @@ -250,13 +222,11 @@ static void __init intc_subgroup_map(struct intc_desc_int *d) add_virq_to_pirq(entry->pirq, irq); irq_set_chained_handler(entry->pirq, intc_virq_handler); - radix_tree_tag_clear(&d->tree, entry->enum_id, - INTC_TAG_VIRQ_NEEDS_ALLOC); - radix_tree_replace_slot(&d->tree, (void **)entries[i], - &intc_irq_xlate[irq]); + xa_store(&d->array, entry->enum_id, &intc_irq_xlate[irq], + GFP_NOWAIT); + xa_clear_tag(&d->array, entry->enum_id, + INTC_TAG_VIRQ_NEEDS_ALLOC); } - - raw_spin_unlock_irqrestore(&d->lock, flags); } void __init intc_finalize(void) @@ -264,6 +234,6 @@ void __init intc_finalize(void) struct intc_desc_int *d; list_for_each_entry(d, &intc_list, list) - if (radix_tree_tagged(&d->tree, INTC_TAG_VIRQ_NEEDS_ALLOC)) + if (xa_tagged(&d->array, INTC_TAG_VIRQ_NEEDS_ALLOC)) intc_subgroup_map(d); }