From: Nicolas Ferre <nicolas.ferre@atmel.com>
To: Grant Likely <grant.likely@secretlab.ca>,
devicetree-discuss@lists.ozlabs.org
Cc: linux-kernel@vger.kernel.org,
Benjamin Herrenschmidt <benh@kernel.crashing.org>,
Thomas Gleixner <tglx@linutronix.de>,
Milton Miller <miltonm@bga.com>,
Rob Herring <rob.herring@calxeda.com>,
Stephen Rothwell <sfr@canb.auug.org.au>,
linuxppc-dev@lists.ozlabs.org,
linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH v3 25/25] irq_domain: mostly eliminate slow-path revmap lookups
Date: Wed, 15 Feb 2012 17:36:46 +0100 [thread overview]
Message-ID: <4F3BDF1E.4040506@atmel.com> (raw)
In-Reply-To: <1327700179-17454-26-git-send-email-grant.likely@secretlab.ca>
Grant,
I do not know if it is the latest revision but I have identified some
issues on error/slow paths...
On 01/27/2012 10:36 PM, Grant Likely :
> With the current state of irq_domain, the reverse map is always used when
> new IRQs get mapped. This means that the irq_find_mapping() function
> can be simplified to always call out to the revmap-specific lookup function.
>
> This patch adds lookup functions for the revmaps that don't yet have one
> and removes the slow path lookup from most of the code paths. The only
> place where the slow path legitimately remains is when the linear map
> is used with a hwirq number larger than the revmap size.
>
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Milton Miller <miltonm@bga.com>
> ---
> arch/powerpc/sysdev/xics/xics-common.c | 3 -
> include/linux/irqdomain.h | 3 +-
> kernel/irq/irqdomain.c | 94 +++++++++++++++++---------------
> 3 files changed, 51 insertions(+), 49 deletions(-)
>
> diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c
> index ea5e204..1d7067d 100644
> --- a/arch/powerpc/sysdev/xics/xics-common.c
> +++ b/arch/powerpc/sysdev/xics/xics-common.c
> @@ -330,9 +330,6 @@ static int xics_host_map(struct irq_domain *h, unsigned int virq,
>
> pr_devel("xics: map virq %d, hwirq 0x%lx\n", virq, hw);
>
> - /* Insert the interrupt mapping into the radix tree for fast lookup */
> - irq_radix_revmap_insert(xics_host, virq, hw);
> -
> /* They aren't all level sensitive but we just don't really know */
> irq_set_status_flags(virq, IRQ_LEVEL);
>
> diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
> index 0b00f83..38314f2 100644
> --- a/include/linux/irqdomain.h
> +++ b/include/linux/irqdomain.h
> @@ -93,6 +93,7 @@ struct irq_domain {
> struct list_head link;
>
> /* type of reverse mapping_technique */
> + unsigned int (*revmap)(struct irq_domain *host, irq_hw_number_t hwirq);
> unsigned int revmap_type;
> union {
> struct {
> @@ -155,8 +156,6 @@ extern void irq_dispose_mapping(unsigned int virq);
> extern unsigned int irq_find_mapping(struct irq_domain *host,
> irq_hw_number_t hwirq);
> extern unsigned int irq_create_direct_mapping(struct irq_domain *host);
> -extern void irq_radix_revmap_insert(struct irq_domain *host, unsigned int virq,
> - irq_hw_number_t hwirq);
> extern unsigned int irq_radix_revmap_lookup(struct irq_domain *host,
> irq_hw_number_t hwirq);
> extern unsigned int irq_linear_revmap(struct irq_domain *host,
> diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
> index 5b4fc4d..91c1cb7 100644
> --- a/kernel/irq/irqdomain.c
> +++ b/kernel/irq/irqdomain.c
> @@ -104,6 +104,7 @@ struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
> domain->revmap_data.legacy.first_irq = first_irq;
> domain->revmap_data.legacy.first_hwirq = first_hwirq;
> domain->revmap_data.legacy.size = size;
> + domain->revmap = irq_domain_legacy_revmap;
>
> mutex_lock(&irq_domain_mutex);
> /* Verify that all the irqs are available */
> @@ -174,18 +175,35 @@ struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
> }
> domain->revmap_data.linear.size = size;
> domain->revmap_data.linear.revmap = revmap;
> + domain->revmap = irq_linear_revmap;
> irq_domain_add(domain);
> return domain;
> }
>
> +static unsigned int irq_domain_nomap_revmap(struct irq_domain *domain,
> + irq_hw_number_t hwirq)
> +{
> + struct irq_data *data = irq_get_irq_data(hwirq);
> +
> + if (WARN_ON_ONCE(domain->revmap_type != IRQ_DOMAIN_MAP_NOMAP))
> + return irq_find_mapping(domain, hwirq);
Should be:
return irq_find_mapping_slow(domain, hwirq);
Recursion otherwise...
> +
> + /* Verify that the map has actually been established */
> + if (data && (data->domain == domain) && (data->hwirq == hwirq))
> + return hwirq;
> + return 0;
> +}
> +
> struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
> const struct irq_domain_ops *ops,
> void *host_data)
> {
> struct irq_domain *domain = irq_domain_alloc(of_node,
> IRQ_DOMAIN_MAP_NOMAP, ops, host_data);
> - if (domain)
> + if (domain) {
> + domain->revmap = irq_domain_nomap_revmap;
> irq_domain_add(domain);
> + }
> return domain;
> }
>
> @@ -205,6 +223,7 @@ struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
> IRQ_DOMAIN_MAP_TREE, ops, host_data);
> if (domain) {
> INIT_RADIX_TREE(&domain->revmap_data.tree, GFP_KERNEL);
> + domain->revmap = irq_radix_revmap_lookup;
> irq_domain_add(domain);
> }
> return domain;
> @@ -378,6 +397,19 @@ unsigned int irq_create_mapping(struct irq_domain *domain,
> return 0;
> }
>
> + switch(domain->revmap_type) {
> + case IRQ_DOMAIN_MAP_LINEAR:
> + if (hwirq < domain->revmap_data.linear.size)
> + domain->revmap_data.linear.revmap[hwirq] = irq;
> + break;
> + case IRQ_DOMAIN_MAP_TREE:
> + mutex_lock(&revmap_trees_mutex);
> + radix_tree_insert(&domain->revmap_data.tree, hwirq,
> + irq_get_irq_data(irq));
> + mutex_unlock(&revmap_trees_mutex);
> +
> + break;
> + }
> pr_debug("irq: irq %lu on domain %s mapped to virtual irq %u\n",
> hwirq, domain->of_node ? domain->of_node->full_name : "null", virq);
>
> @@ -478,25 +510,27 @@ EXPORT_SYMBOL_GPL(irq_dispose_mapping);
> * irq_find_mapping() - Find a linux irq from an hw irq number.
> * @domain: domain owning this hardware interrupt
> * @hwirq: hardware irq number in that domain space
> - *
> - * This is a slow path, for use by generic code. It's expected that an
> - * irq controller implementation directly calls the appropriate low level
> - * mapping function.
> */
> unsigned int irq_find_mapping(struct irq_domain *domain,
> irq_hw_number_t hwirq)
> {
> - unsigned int i;
> -
> - /* Look for default domain if nececssary */
> - if (domain == NULL)
> + if (!domain)
> domain = irq_default_domain;
> - if (domain == NULL)
> - return 0;
> + return domain ? domain->revmap(domain, hwirq) : 0;
> +}
> +EXPORT_SYMBOL_GPL(irq_find_mapping);
>
> - /* legacy -> bail early */
> - if (domain->revmap_type == IRQ_DOMAIN_MAP_LEGACY)
> - return irq_domain_legacy_revmap(domain, hwirq);
> +/**
> + * irq_find_mapping_slow() - slow path for finding the irq mapped to a hwirq
> + *
> + * This is the failsafe slow path for finding an irq mapping. The only time
> + * this will reasonably get called is when the linear map is used with a
> + * hwirq number larger than the size of the reverse map.
> + */
> +static unsigned int irq_find_mapping_slow(struct irq_domain *domain,
> + irq_hw_number_t hwirq)
> +{
> + int i;
>
> /* Slow path does a linear search of the map */
> for (i = 0; i < irq_virq_count; i++) {
> @@ -506,7 +540,6 @@ unsigned int irq_find_mapping(struct irq_domain *domain,
> }
> return 0;
> }
> -EXPORT_SYMBOL_GPL(irq_find_mapping);
>
> /**
> * irq_radix_revmap_lookup() - Find a linux irq from a hw irq number.
> @@ -537,31 +570,7 @@ unsigned int irq_radix_revmap_lookup(struct irq_domain *domain,
> * Else fallback to linear lookup - this should not happen in practice
> * as it means that we failed to insert the node in the radix tree.
> */
> - return irq_data ? irq_data->irq : irq_find_mapping(domain, hwirq);
> -}
> -
> -/**
> - * irq_radix_revmap_insert() - Insert a hw irq to linux irq number mapping.
> - * @domain: domain owning this hardware interrupt
> - * @virq: linux irq number
> - * @hwirq: hardware irq number in that domain space
> - *
> - * This is for use by irq controllers that use a radix tree reverse
> - * mapping for fast lookup.
> - */
> -void irq_radix_revmap_insert(struct irq_domain *domain, unsigned int virq,
> - irq_hw_number_t hwirq)
> -{
> - struct irq_data *irq_data = irq_get_irq_data(virq);
> -
> - if (WARN_ON(domain->revmap_type != IRQ_DOMAIN_MAP_TREE))
> - return;
> -
> - if (virq) {
> - mutex_lock(&revmap_trees_mutex);
> - radix_tree_insert(&domain->revmap_data.tree, hwirq, irq_data);
> - mutex_unlock(&revmap_trees_mutex);
> - }
> + return irq_data ? irq_data->irq : irq_find_mapping_slow(domain, hwirq);
> }
>
> /**
> @@ -585,14 +594,11 @@ unsigned int irq_linear_revmap(struct irq_domain *domain,
> if (unlikely(hwirq >= domain->revmap_data.linear.size))
> return irq_find_mapping(domain, hwirq);
Ditto here. And same whith previous one in same function. Check in
irq_radix_revmap_lookup() there is the same issue on the "WARN_ON_ONCE"
path...
>
> - /* Check if revmap was allocated */
> revmap = domain->revmap_data.linear.revmap;
> - if (unlikely(revmap == NULL))
> - return irq_find_mapping(domain, hwirq);
>
> /* Fill up revmap with slow path if no mapping found */
> if (unlikely(!revmap[hwirq]))
> - revmap[hwirq] = irq_find_mapping(domain, hwirq);
> + revmap[hwirq] = irq_find_mapping_slow(domain, hwirq);
>
> return revmap[hwirq];
> }
Bye,
--
Nicolas Ferre
next prev parent reply other threads:[~2012-02-15 16:37 UTC|newest]
Thread overview: 66+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-01-27 21:35 [PATCH v3 00/25] irq_domain generalization and refinement Grant Likely
2012-01-27 21:35 ` [PATCH v3 01/25] irq_domain: add documentation and MAINTAINERS entry Grant Likely
2012-01-28 18:23 ` Randy Dunlap
2012-01-27 21:35 ` [PATCH v3 02/25] dt: Make irqdomain less verbose Grant Likely
2012-01-27 21:35 ` [PATCH v3 03/25] irq_domain: Make irq_domain structure match powerpc's irq_host Grant Likely
2012-01-27 21:35 ` [PATCH v3 04/25] irq_domain: convert microblaze from irq_host to irq_domain Grant Likely
2012-01-27 21:35 ` [PATCH v3 05/25] irq_domain/powerpc: Use common irq_domain structure instead of irq_host Grant Likely
2012-01-27 21:36 ` [PATCH v3 06/25] irq_domain/powerpc: eliminate irq_map; use irq_alloc_desc() instead Grant Likely
2012-01-27 21:36 ` [PATCH v3 07/25] irq_domain/powerpc: Eliminate virq_is_host() Grant Likely
2012-01-27 21:36 ` [PATCH v3 08/25] irq_domain: Move irq_domain code from powerpc to kernel/irq Grant Likely
2012-01-27 21:36 ` [PATCH v3 09/25] irqdomain: remove NO_IRQ from irq domain code Grant Likely
2012-01-27 21:36 ` [PATCH v3 10/25] irq_domain: Remove references to old irq_host names Grant Likely
2012-01-27 21:36 ` [PATCH v3 11/25] irq_domain: Replace irq_alloc_host() with revmap-specific initializers Grant Likely
2012-01-27 21:36 ` [PATCH v3 12/25] irq_domain: Add support for base irq and hwirq in legacy mappings Grant Likely
2012-01-27 21:36 ` [PATCH v3 13/25] irq_domain: Remove 'new' irq_domain in favour of the ppc one Grant Likely
2012-02-03 14:48 ` Cousson, Benoit
2012-02-03 16:42 ` Grant Likely
2012-01-27 21:36 ` [PATCH v3 14/25] irq_domain: Remove irq_domain_add_simple() Grant Likely
2012-01-31 12:45 ` Shawn Guo
2012-01-31 13:15 ` Rob Herring
2012-01-31 13:58 ` Shawn Guo
2012-02-01 0:08 ` Grant Likely
2012-02-01 5:46 ` [PATCH] irq_domain: fix the irq number of imx5 tzic Shawn Guo
2012-02-02 4:58 ` Grant Likely
2012-01-27 21:36 ` [PATCH v3 15/25] irq_domain: Create common xlate functions that device drivers can use Grant Likely
2012-01-27 21:36 ` [PATCH v3 16/25] irq_domain: constify irq_domain_ops Grant Likely
2012-01-27 21:36 ` [PATCH v3 17/25] irq_domain/c6x: Convert c6x to use generic irq_domain support Grant Likely
2012-01-27 21:36 ` [PATCH v3 18/25] irq_domain/c6x: constify irq_domain structures Grant Likely
2012-01-27 21:36 ` [PATCH v3 19/25] irq_domain/c6x: Use library of xlate functions Grant Likely
2012-01-27 21:36 ` [PATCH v3 20/25] irq_domain/powerpc: constify irq_domain_ops Grant Likely
2012-01-27 21:36 ` [PATCH v3 21/25] irqdomain/powerpc: Replace custom xlate functions with library functions Grant Likely
2012-02-06 5:22 ` Michael Neuling
2012-02-06 6:00 ` Grant Likely
2012-01-27 21:36 ` [PATCH v3 22/25] irq_domain/x86: Convert x86 (embedded) to use common irq_domain Grant Likely
2012-01-28 16:44 ` Sebastian Andrzej Siewior
2012-01-29 0:35 ` Grant Likely
2012-01-29 0:39 ` Grant Likely
2012-01-30 19:58 ` Grant Likely
2012-02-01 14:17 ` Sebastian Andrzej Siewior
2012-02-01 18:06 ` Grant Likely
2012-02-23 19:56 ` Grant Likely
2012-02-23 21:22 ` Sebastian Andrzej Siewior
2012-02-23 21:39 ` Grant Likely
2012-01-27 21:36 ` [PATCH v3 23/25] irq_domain: Include hwirq number in /proc/interrupts Grant Likely
2012-01-27 21:36 ` [PATCH v3 24/25] irq_domain: remove "hint" when allocating irq numbers Grant Likely
2012-02-07 18:07 ` Nicolas Ferre
2012-02-15 15:04 ` Nicolas Ferre
2012-02-15 20:21 ` Grant Likely
2012-02-15 21:50 ` Shawn Guo
2012-02-16 5:32 ` Grant Likely
2012-02-16 6:03 ` Shawn Guo
2012-01-27 21:36 ` [PATCH v3 25/25] irq_domain: mostly eliminate slow-path revmap lookups Grant Likely
2012-02-15 16:36 ` Nicolas Ferre [this message]
2012-02-15 20:29 ` Grant Likely
2012-01-28 18:38 ` [PATCH v3 00/25] irq_domain generalization and refinement Rob Herring
2012-01-31 4:53 ` Olof Johansson
2012-02-01 0:07 ` Grant Likely
2012-02-04 22:17 ` Russell King - ARM Linux
2012-02-04 22:31 ` Russell King - ARM Linux
2012-02-05 1:38 ` Tony Lindgren
2012-02-05 16:13 ` Russell King - ARM Linux
2012-02-07 15:26 ` Mark Brown
2012-02-15 20:33 ` Grant Likely
2012-02-05 0:01 ` Benjamin Herrenschmidt
2012-02-06 0:51 ` Rob Herring
2012-02-06 5:56 ` Grant Likely
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4F3BDF1E.4040506@atmel.com \
--to=nicolas.ferre@atmel.com \
--cc=benh@kernel.crashing.org \
--cc=devicetree-discuss@lists.ozlabs.org \
--cc=grant.likely@secretlab.ca \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=miltonm@bga.com \
--cc=rob.herring@calxeda.com \
--cc=sfr@canb.auug.org.au \
--cc=tglx@linutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).