From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Cyrus-Session-Id: sloti22d1t05-322982-1516221190-2-16133551488102770169 X-Sieve: CMU Sieve 3.0 X-Spam-known-sender: no X-Spam-score: 0.0 X-Spam-hits: BAYES_00 -1.9, HEADER_FROM_DIFFERENT_DOMAINS 0.25, RCVD_IN_DNSWL_HI -5, T_RP_MATCHES_RCVD -0.01, LANGUAGES roenfr, BAYES_USED global, SA_VERSION 3.4.0 X-Spam-source: IP='209.132.180.67', Host='vger.kernel.org', Country='US', FromHeader='org', MailFrom='org' X-Spam-charsets: X-Resolved-to: greg@kroah.com X-Delivered-to: greg@kroah.com X-Mail-from: linux-usb-owner@vger.kernel.org ARC-Seal: i=1; a=rsa-sha256; cv=none; d=messagingengine.com; s=arctest; t=1516221189; b=d083uoqzvL2aOUHZkbxK3NuOtk+Xa2/xQFE6v8aZtzN+UWN pnwwvaYB72uMl551fxqSjPs2P4K2Ag4+J1gTfxe3qXvIi32mYkcevpaf1yNciPxS tJyIhg7uJAYNIOsjnZRotmk4zK8h2HVqKk8kv3Jv+7Gd/4MICljgiz+ioLB5XmUa T08pYJIa+i90jK9T3FOSDzFZZgndLJ3R+wx9sb+2vbtawI+qJalX/tI55J+RBp3/ Bg7UyeS7ycwOpYob+JQqtDBn1/EdZzGrO7XCCagBL0W32Zyh8MNTaMSNaPKAZeVW /ZvxFfVOQKs3Sc7/ZQcnPsQ81UKVi4S87bq+p0g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=from:to:cc:subject:date:message-id :in-reply-to:references:sender:list-id; s=arctest; t=1516221189; bh=A+Y7eDbAsZH05PO1iNlTpSb9Ik+HL7s3edXuMcAwNaI=; b=IUmKdvMzRlvz zz5yfmbiM4IHU/hlCxfa0x5vHzsknGNf2HuQgVpYCvS2O4Ke1RX+xlrj9F+ja/TK /q0RJgaNPGiZVMP7Ny6qnZUvTWqCARN9DW285KqqG4zRJftXLF5DHFa4LR4I41Tr xZUkBKEY5EkFb/nTbu99d3kEkrv/G0sv8Lxn0aBRqscr+V2E18b4rYF34bc2+yar RbuThReBg7+Y8lqzx2XSWfsEMQFpG5J5cS2u378Q7nZy+mQhBxs/A+xln10Hh3o6 86JRA2DS8A+qbI9P+Rofso3qX9NIPX0GE9gxHUiQM9L5BrxEwLENWl/ZIdmp51Ev f6w1Xqy2Qw== ARC-Authentication-Results: i=1; mx2.messagingengine.com; arc=none (no signatures found); dkim=fail (message has been altered; 2048-bit rsa key sha256) header.d=infradead.org header.i=@infradead.org header.b=Z5HwbJq+ x-bits=2048 x-keytype=rsa x-algorithm=sha256 x-selector=bombadil.20170209; dmarc=none (p=none,has-list-id=yes,d=none) header.from=infradead.org; iprev=pass policy.iprev=209.132.180.67 (vger.kernel.org); spf=none smtp.mailfrom=linux-usb-owner@vger.kernel.org smtp.helo=vger.kernel.org; x-aligned-from=fail; x-ptr=pass x-ptr-helo=vger.kernel.org x-ptr-lookup=vger.kernel.org; x-return-mx=pass smtp.domain=vger.kernel.org smtp.result=pass smtp_org.domain=kernel.org smtp_org.result=pass smtp_is_org_domain=no header.domain=infradead.org header.result=pass header_is_org_domain=yes Authentication-Results: mx2.messagingengine.com; arc=none (no signatures found); dkim=fail (message has been altered; 2048-bit rsa key sha256) header.d=infradead.org header.i=@infradead.org header.b=Z5HwbJq+ x-bits=2048 x-keytype=rsa x-algorithm=sha256 x-selector=bombadil.20170209; dmarc=none (p=none,has-list-id=yes,d=none) header.from=infradead.org; iprev=pass policy.iprev=209.132.180.67 (vger.kernel.org); spf=none smtp.mailfrom=linux-usb-owner@vger.kernel.org smtp.helo=vger.kernel.org; x-aligned-from=fail; x-ptr=pass x-ptr-helo=vger.kernel.org x-ptr-lookup=vger.kernel.org; x-return-mx=pass smtp.domain=vger.kernel.org smtp.result=pass smtp_org.domain=kernel.org smtp_org.result=pass smtp_is_org_domain=no header.domain=infradead.org header.result=pass header_is_org_domain=yes Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932103AbeAQUdF (ORCPT ); Wed, 17 Jan 2018 15:33:05 -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 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-usb-owner@vger.kernel.org X-Mailing-List: linux-usb@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-Mailing-List: linux-kernel@vger.kernel.org List-ID: 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); } -- 2.15.1