aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorFrederic Barrat <fbarrat@linux.ibm.com>2022-06-15 16:21:41 +0200
committerReza Arbab <arbab@linux.ibm.com>2022-07-05 09:22:14 -0500
commit4d27f0375de64645194a5ca6a5b85cef42524d0e (patch)
treed17dd1f677841f1c2f352019508861690430dfa6 /hw
parentd9772c6108db42dc7b186cc699fe597d3f40c302 (diff)
downloadskiboot-4d27f0375de64645194a5ca6a5b85cef42524d0e.zip
skiboot-4d27f0375de64645194a5ca6a5b85cef42524d0e.tar.gz
skiboot-4d27f0375de64645194a5ca6a5b85cef42524d0e.tar.bz2
interrupts: Speed up opal interrupts scanning
When looking for which interrupts are serviced by opal, we scan all sources and query every single interrupt to know if it's for linux or opal. An optimization was made so that if the source doesn't have an 'interrupt' op (=the handler) or an 'attributes' op (to do the query), then we can skip the source. That's all good. However, when xive was introduced, the 'irq_source' defining those ops was wrapped in a 'xive_src' source which adds a level of indirection for those 'attributes' and 'interrupt' ops. So the previous optimization no longer works: the 'attributes' and 'interrupt' ops are defined from the wrapper, but if we could look past the indirection, we would realize they are not. That is getting problematic for the rather large generic IPIs source. We have 8 million such interrupts defined per chip on P10 and because the above optimization is no longer kicking in, we are now querying every single one of them to know if it is for opal. Real hardware swallows it without much difficulty, but simulators don't. Running qemu on my laptop, the full scan takes ~12 seconds per chip! This patch adds a callback for an interrupt source to report whether it has opal interrupts. If the source doesn't define it, then we fallback to looking at the 'interrupt' and 'attributes' ops, like before, as it is still useful on P8. We can then define that new callback on the xive sources, allowing to look past the indirection level and skip scanning the source when appropriate. Signed-off-by: Frederic Barrat <fbarrat@linux.ibm.com> Signed-off-by: Reza Arbab <arbab@linux.ibm.com>
Diffstat (limited to 'hw')
-rw-r--r--hw/xive.c10
-rw-r--r--hw/xive2.c10
2 files changed, 20 insertions, 0 deletions
diff --git a/hw/xive.c b/hw/xive.c
index 6055276..bf711ad 100644
--- a/hw/xive.c
+++ b/hw/xive.c
@@ -2520,6 +2520,15 @@ void xive_source_mask(struct irq_source *is, uint32_t isn)
xive_update_irq_mask(s, isn - s->esb_base, true);
}
+static bool xive_has_opal_interrupts(struct irq_source *is)
+{
+ struct xive_src *s = container_of(is, struct xive_src, is);
+
+ if (!s->orig_ops || !s->orig_ops->attributes || !s->orig_ops->interrupt)
+ return false;
+ return true;
+}
+
static const struct irq_source_ops xive_irq_source_ops = {
.get_xive = xive_source_get_xive,
.set_xive = xive_source_set_xive,
@@ -2527,6 +2536,7 @@ static const struct irq_source_ops xive_irq_source_ops = {
.interrupt = xive_source_interrupt,
.attributes = xive_source_attributes,
.name = xive_source_name,
+ .has_opal_interrupts = xive_has_opal_interrupts,
};
static void __xive_register_source(struct xive *x, struct xive_src *s,
diff --git a/hw/xive2.c b/hw/xive2.c
index 8e2a1f2..d20e3c5 100644
--- a/hw/xive2.c
+++ b/hw/xive2.c
@@ -2644,10 +2644,20 @@ void xive2_source_mask(struct irq_source *is, uint32_t isn)
xive_update_irq_mask(s, isn - s->esb_base, true);
}
+static bool xive_has_opal_interrupts(struct irq_source *is)
+{
+ struct xive_src *s = container_of(is, struct xive_src, is);
+
+ if (!s->orig_ops || !s->orig_ops->attributes || !s->orig_ops->interrupt)
+ return false;
+ return true;
+}
+
static const struct irq_source_ops xive_irq_source_ops = {
.interrupt = xive_source_interrupt,
.attributes = xive_source_attributes,
.name = xive_source_name,
+ .has_opal_interrupts = xive_has_opal_interrupts,
};
static void __xive_register_source(struct xive *x, struct xive_src *s,