Re: [PATCH 1/9] irqdomain: Reimplement irq_linear_revmap() with irq_find_mapping()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 





Le 06/04/2021 à 11:35, Marc Zyngier a écrit :
irq_linear_revmap() is supposed to be a fast path for domain
lookups, but it only exposes low-level details of the irqdomain
implementation, details which are better kept private.

Can you elaborate with more details ?


The *overhead* between the two is only a function call and
a couple of tests, so it is likely that noone can show any
meaningful difference compared to the cost of taking an
interrupt.

Do you have any measurement ?

Can you make the "likely" a certitude ?


Reimplement irq_linear_revmap() with irq_find_mapping()
in order to preserve source code compatibility, and
rename the internal field for a measure.

This is in complete contradiction with commit https://github.com/torvalds/linux/commit/d3dcb436

At that time, irq_linear_revmap() was less complex than what irq_find_mapping() is today, and nevertheless it was considered worth restoring in as a fast path. What has changed since then ?

Can you also explain the reason for the renaming of "linear_revmap" into "revmap" ? What is that "measure" ?


Signed-off-by: Marc Zyngier <maz@xxxxxxxxxx>
---
  include/linux/irqdomain.h | 22 +++++++++-------------
  kernel/irq/irqdomain.c    |  6 +++---
  2 files changed, 12 insertions(+), 16 deletions(-)

diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 33cacc8af26d..b9600f24878a 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -154,9 +154,9 @@ struct irq_domain_chip_generic;
   * Revmap data, used internally by irq_domain
   * @revmap_direct_max_irq: The largest hwirq that can be set for controllers that
   *                         support direct mapping
- * @revmap_size: Size of the linear map table @linear_revmap[]
+ * @revmap_size: Size of the linear map table @revmap[]
   * @revmap_tree: Radix map tree for hwirqs that don't fit in the linear map
- * @linear_revmap: Linear table of hwirq->virq reverse mappings
+ * @revmap: Linear table of hwirq->virq reverse mappings
   */
  struct irq_domain {
  	struct list_head link;
@@ -180,7 +180,7 @@ struct irq_domain {
  	unsigned int revmap_size;
  	struct radix_tree_root revmap_tree;
  	struct mutex revmap_tree_mutex;
-	unsigned int linear_revmap[];
+	unsigned int revmap[];
  };
/* Irq domain flags */
@@ -396,24 +396,20 @@ static inline unsigned int irq_create_mapping(struct irq_domain *host,
  	return irq_create_mapping_affinity(host, hwirq, NULL);
  }
-
  /**
- * irq_linear_revmap() - Find a linux irq from a hw irq number.
+ * irq_find_mapping() - Find a linux irq from a hw irq number.
   * @domain: domain owning this hardware interrupt
   * @hwirq: hardware irq number in that domain space
- *
- * This is a fast path alternative to irq_find_mapping() that can be
- * called directly by irq controller code to save a handful of
- * instructions. It is always safe to call, but won't find irqs mapped
- * using the radix tree.
   */
+extern unsigned int irq_find_mapping(struct irq_domain *host,
+				     irq_hw_number_t hwirq);
+
  static inline unsigned int irq_linear_revmap(struct irq_domain *domain,
  					     irq_hw_number_t hwirq)
  {
-	return hwirq < domain->revmap_size ? domain->linear_revmap[hwirq] : 0;
+	return irq_find_mapping(domain, hwirq);
  }
-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 int irq_create_strict_mappings(struct irq_domain *domain,
  				      unsigned int irq_base,
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index d10ab1d689d5..dfa716305ea9 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -486,7 +486,7 @@ static void irq_domain_clear_mapping(struct irq_domain *domain,
  				     irq_hw_number_t hwirq)
  {
  	if (hwirq < domain->revmap_size) {
-		domain->linear_revmap[hwirq] = 0;
+		domain->revmap[hwirq] = 0;
  	} else {
  		mutex_lock(&domain->revmap_tree_mutex);
  		radix_tree_delete(&domain->revmap_tree, hwirq);
@@ -499,7 +499,7 @@ static void irq_domain_set_mapping(struct irq_domain *domain,
  				   struct irq_data *irq_data)
  {
  	if (hwirq < domain->revmap_size) {
-		domain->linear_revmap[hwirq] = irq_data->irq;
+		domain->revmap[hwirq] = irq_data->irq;
  	} else {
  		mutex_lock(&domain->revmap_tree_mutex);
  		radix_tree_insert(&domain->revmap_tree, hwirq, irq_data);
@@ -920,7 +920,7 @@ unsigned int irq_find_mapping(struct irq_domain *domain,
/* Check if the hwirq is in the linear revmap. */
  	if (hwirq < domain->revmap_size)
-		return domain->linear_revmap[hwirq];
+		return domain->revmap[hwirq];
rcu_read_lock();
  	data = radix_tree_lookup(&domain->revmap_tree, hwirq);




[Index of Archives]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux