From: Marc Zyngier <marc.zyngier@arm.com>
To: linux-kernel@vger.kernel.org
Cc: Thomas Gleixner <tglx@linutronix.de>,
Jason Cooper <jason@lakedaemon.net>,
Shanker Donthineni <shankerd@codeaurora.org>,
Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>,
Christoffer Dall <cdall@linaro.org>,
Eric Auger <eric.auger@redhat.com>
Subject: [PATCH 08/10] irqchip/gic-v3-its: Limit scope of VPE mapping to be per ITS
Date: Tue, 10 Oct 2017 13:51:35 +0100 [thread overview]
Message-ID: <20171010125137.9464-9-marc.zyngier@arm.com> (raw)
In-Reply-To: <20171010125137.9464-1-marc.zyngier@arm.com>
So far, we map all VPEs on all ITSs. While this is not wrong,
this is quite a big hammer, as moving a VPE around requires
all ITSs to be synchronized. Needles to say, this is an
expensive proposition.
Instead, let's switch to a mode where we issue VMAPP commands
only on ITSs that are actually involved in reporting interrupts
to the given VM.
For that purpose, we refcount the number of interrupts are are
mapped for this VM on each ITS, performing the map/unmap
operations as required. It then allows us to use this refcount
to only issue VMOVP to the ITSs that need to know about this
VM.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
drivers/irqchip/irq-gic-v3-its.c | 75 ++++++++++++++++++++++++++++++++++++++
include/linux/irqchip/arm-gic-v4.h | 1 +
2 files changed, 76 insertions(+)
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 4583af37785b..9997e387b936 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -965,6 +965,9 @@ static void its_send_vmovp(struct its_vpe *vpe)
if (!its->is_v4)
continue;
+ if (!vpe->its_vm->vlpi_count[its->list_nr])
+ continue;
+
desc.its_vmovp_cmd.col = &its->collections[col_id];
its_send_single_vcommand(its, its_build_vmovp_cmd, &desc);
}
@@ -1141,6 +1144,58 @@ static int its_irq_set_irqchip_state(struct irq_data *d,
return 0;
}
+static void its_map_vm(struct its_node *its, struct its_vm *vm)
+{
+ unsigned long flags;
+
+ /* Not using the ITS list? Everything is always mapped. */
+ if (!its_list_map)
+ return;
+
+ raw_spin_lock_irqsave(&vmovp_lock, flags);
+
+ /*
+ * If the VM wasn't mapped yet, iterate over the vpes and get
+ * them mapped now.
+ */
+ vm->vlpi_count[its->list_nr]++;
+
+ if (vm->vlpi_count[its->list_nr] == 1) {
+ int i;
+
+ for (i = 0; i < vm->nr_vpes; i++) {
+ struct its_vpe *vpe = vm->vpes[i];
+
+ /* Map the VPE to the first possible CPU */
+ vpe->col_idx = cpumask_first(cpu_online_mask);
+ its_send_vmapp(its, vpe, true);
+ its_send_vinvall(its, vpe);
+ }
+ }
+
+ raw_spin_unlock_irqrestore(&vmovp_lock, flags);
+}
+
+static void its_unmap_vm(struct its_node *its, struct its_vm *vm)
+{
+ unsigned long flags;
+
+ /* Not using the ITS list? Everything is always mapped. */
+ if (!its_list_map)
+ return;
+
+ raw_spin_lock_irqsave(&vmovp_lock, flags);
+
+ if (!--vm->vlpi_count[its->list_nr]) {
+ int i;
+
+ for (i = 0; i < vm->nr_vpes; i++)
+ its_send_vmapp(its, vm->vpes[i], false);
+ }
+
+ raw_spin_unlock_irqrestore(&vmovp_lock, flags);
+}
+
static int its_vlpi_map(struct irq_data *d, struct its_cmd_info *info)
{
struct its_device *its_dev = irq_data_get_irq_chip_data(d);
@@ -1176,6 +1231,9 @@ static int its_vlpi_map(struct irq_data *d, struct its_cmd_info *info)
/* Already mapped, move it around */
its_send_vmovi(its_dev, event);
} else {
+ /* Ensure all the VPEs are mapped on this ITS */
+ its_map_vm(its_dev->its, info->map->vm);
+
/* Drop the physical mapping */
its_send_discard(its_dev, event);
@@ -1237,6 +1295,9 @@ static int its_vlpi_unmap(struct irq_data *d)
LPI_PROP_ENABLED |
LPI_PROP_GROUP1));
+ /* Potentially unmap the VM from this ITS */
+ its_unmap_vm(its_dev->its, its_dev->event_map.vm);
+
/*
* Drop the refcount and make the device available again if
* this was the last VLPI.
@@ -2458,6 +2519,9 @@ static void its_vpe_invall(struct its_vpe *vpe)
if (!its->is_v4)
continue;
+ if (its_list_map && !vpe->its_vm->vlpi_count[its->list_nr])
+ continue;
+
its_send_vinvall(its, vpe);
}
}
@@ -2708,6 +2772,10 @@ static void its_vpe_irq_domain_activate(struct irq_domain *domain,
struct its_vpe *vpe = irq_data_get_irq_chip_data(d);
struct its_node *its;
+ /* If we use the list map, we issue VMAPP on demand... */
+ if (its_list_map)
+ return;
+
/* Map the VPE to the first possible CPU */
vpe->col_idx = cpumask_first(cpu_online_mask);
@@ -2726,6 +2794,13 @@ static void its_vpe_irq_domain_deactivate(struct irq_domain *domain,
struct its_vpe *vpe = irq_data_get_irq_chip_data(d);
struct its_node *its;
+ /*
+ * If we use the list map, we unmap the VPE once no VLPIs are
+ * associated with the VM.
+ */
+ if (its_list_map)
+ return;
+
list_for_each_entry(its, &its_nodes, entry) {
if (!its->is_v4)
continue;
diff --git a/include/linux/irqchip/arm-gic-v4.h b/include/linux/irqchip/arm-gic-v4.h
index e26a668826e6..43cde15f221b 100644
--- a/include/linux/irqchip/arm-gic-v4.h
+++ b/include/linux/irqchip/arm-gic-v4.h
@@ -36,6 +36,7 @@ struct its_vm {
irq_hw_number_t db_lpi_base;
unsigned long *db_bitmap;
int nr_db_lpis;
+ u32 vlpi_count[GICv4_ITS_LIST_MAX];
};
/* Embedded in kvm_vcpu.arch */
--
2.11.0
next prev parent reply other threads:[~2017-10-10 12:52 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-10-10 12:51 [PATCH 00/10] irqchip: Proposed GICv4 updates for 4.15 Marc Zyngier
2017-10-10 12:51 ` [PATCH 01/10] irqchip/gic-v3-its: Add post-mortem info on command timeout Marc Zyngier
2017-10-10 12:51 ` [PATCH 02/10] irqchip/gic-v3-its: Pass its_node pointer to each command builder Marc Zyngier
2017-10-10 12:51 ` [PATCH 03/10] irqchip/gic-v3-its: Workaround HiSilicon Hip07 redistributor addressing Marc Zyngier
2017-10-10 12:51 ` [PATCH 04/10] irqchip/gic-v3-its: Track per-ITS list number Marc Zyngier
2017-10-10 12:51 ` [PATCH 05/10] irqchip/gic-v3-its: Make GICv4_ITS_LIST_MAX globally available Marc Zyngier
2017-10-10 12:51 ` [PATCH 06/10] irqchip/gic-v3-its: Make its_send_vinvall operate on a single ITS Marc Zyngier
2017-10-10 12:51 ` [PATCH 07/10] irqchip/gic-v3-its: Make its_send_vmapp " Marc Zyngier
2017-10-10 12:51 ` Marc Zyngier [this message]
2017-10-10 12:51 ` [PATCH 09/10] irqchip/gic-v3-its: Only send VINVALL to " Marc Zyngier
2017-10-10 12:51 ` [PATCH 10/10] irqchip/gic-v4: Make the doorbells managed affinity interrupts Marc Zyngier
2017-10-12 9:22 ` Thomas Gleixner
2017-10-12 14:38 ` Marc Zyngier
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=20171010125137.9464-9-marc.zyngier@arm.com \
--to=marc.zyngier@arm.com \
--cc=cdall@linaro.org \
--cc=eric.auger@redhat.com \
--cc=jason@lakedaemon.net \
--cc=linux-kernel@vger.kernel.org \
--cc=shameerali.kolothum.thodi@huawei.com \
--cc=shankerd@codeaurora.org \
--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
all inboxes | Powered by JetHome®