Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1676825

[PATCH v2 25/52] irqchip/gic-v3-its: Add VPE affinity changes

From Marc Zyngier <marc.zyngier@arm.com>
Newsgroups linux.kernel
Subject [PATCH v2 25/52] irqchip/gic-v3-its: Add VPE affinity changes
Date 2017-06-28 17:20 +0200
Message-ID <tXmV6-8uj-71@gated-at.bofh.it> (permalink)
References <tXmLn-8q5-7@gated-at.bofh.it>
Organization linux.* mail to news gateway

Show all headers | View raw


When we're about to run a vcpu, it is crucial that the redistributor
associated with the physical CPU is being told about the new residency.

This is abstracted by hijacking the irq_set_affinity method for the
doorbell interrupt associated with the VPE. It is expected that the
hypervisor will call this method before scheduling the VPE.

Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/irqchip/irq-gic-v3-its.c | 96 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 96 insertions(+)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 0eda36dc84b4..281eed031e01 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -150,6 +150,9 @@ static struct irq_domain *its_parent;
 #define ITS_LIST_MAX		16
 
 static unsigned long its_list_map;
+static u16 vmovp_seq_num;
+static DEFINE_RAW_SPINLOCK(vmovp_lock);
+
 static DEFINE_IDA(its_vpeid_ida);
 
 #define gic_data_rdist()		(raw_cpu_ptr(gic_rdists->rdist))
@@ -240,6 +243,13 @@ struct its_cmd_desc {
 			u32 event_id;
 			bool db_enabled;
 		} its_vmovi_cmd;
+
+		struct {
+			struct its_vpe *vpe;
+			struct its_collection *col;
+			u16 seq_num;
+			u16 its_list;
+		} its_vmovp_cmd;
 	};
 };
 
@@ -331,6 +341,16 @@ static void its_encode_db_valid(struct its_cmd_block *cmd, bool db_valid)
 	its_mask_encode(&cmd->raw_cmd[2], db_valid, 0, 0);
 }
 
+static void its_encode_seq_num(struct its_cmd_block *cmd, u16 seq_num)
+{
+	its_mask_encode(&cmd->raw_cmd[0], seq_num, 47, 32);
+}
+
+static void its_encode_its_list(struct its_cmd_block *cmd, u16 its_list)
+{
+	its_mask_encode(&cmd->raw_cmd[1], its_list, 15, 0);
+}
+
 static void its_encode_vpt_addr(struct its_cmd_block *cmd, u64 vpt_pa)
 {
 	its_mask_encode(&cmd->raw_cmd[3], vpt_pa >> 16, 50, 16);
@@ -573,6 +593,20 @@ static struct its_vpe *its_build_vmovi_cmd(struct its_cmd_block *cmd,
 	return desc->its_vmovi_cmd.vpe;
 }
 
+static struct its_vpe *its_build_vmovp_cmd(struct its_cmd_block *cmd,
+					   struct its_cmd_desc *desc)
+{
+	its_encode_cmd(cmd, GITS_CMD_VMOVP);
+	its_encode_seq_num(cmd, desc->its_vmovp_cmd.seq_num);
+	its_encode_its_list(cmd, desc->its_vmovp_cmd.its_list);
+	its_encode_vpeid(cmd, desc->its_vmovp_cmd.vpe->vpe_id);
+	its_encode_target(cmd, desc->its_vmovp_cmd.col->target_address);
+
+	its_fixup_cmd(cmd);
+
+	return desc->its_vmovp_cmd.vpe;
+}
+
 static u64 its_cmd_ptr_to_offset(struct its_node *its,
 				 struct its_cmd_block *ptr)
 {
@@ -867,6 +901,48 @@ static void its_send_vmapp(struct its_vpe *vpe, bool valid)
 	}
 }
 
+static void its_send_vmovp(struct its_vpe *vpe)
+{
+	struct its_cmd_desc desc;
+	struct its_node *its;
+	unsigned long flags;
+	int col_id = vpe->col_idx;
+
+	desc.its_vmovp_cmd.vpe = vpe;
+	desc.its_vmovp_cmd.its_list = (u16)its_list_map;
+
+	if (!its_list_map) {
+		its = list_first_entry(&its_nodes, struct its_node, entry);
+		desc.its_vmovp_cmd.seq_num = 0;
+		desc.its_vmovp_cmd.col = &its->collections[col_id];
+		its_send_single_vcommand(its, its_build_vmovp_cmd, &desc);
+		return;
+	}
+
+	/*
+	 * Yet another marvel of the architecture. If using the
+	 * its_list "feature", we need to make sure that all ITSs
+	 * receive all VMOVP commands in the same order. The only way
+	 * to guarantee this is to make vmovp a serialization point.
+	 *
+	 * Wall <-- Head.
+	 */
+	raw_spin_lock_irqsave(&vmovp_lock, flags);
+
+	desc.its_vmovp_cmd.seq_num = vmovp_seq_num++;
+
+	/* Emit VMOVPs */
+	list_for_each_entry(its, &its_nodes, entry) {
+		if (!its->is_v4)
+			continue;
+
+		desc.its_vmovp_cmd.col = &its->collections[col_id];
+		its_send_single_vcommand(its, its_build_vmovp_cmd, &desc);
+	}
+
+	raw_spin_unlock_irqrestore(&vmovp_lock, flags);
+}
+
 static void its_send_vinvall(struct its_vpe *vpe)
 {
 	struct its_cmd_desc desc;
@@ -2145,6 +2221,25 @@ static const struct irq_domain_ops its_domain_ops = {
 	.deactivate		= its_irq_domain_deactivate,
 };
 
+static int its_vpe_set_affinity(struct irq_data *d,
+				const struct cpumask *mask_val,
+				bool force)
+{
+	struct its_vpe *vpe = irq_data_get_irq_chip_data(d);
+	int cpu = cpumask_first(mask_val);
+
+	/*
+	 * Changing affinity is mega expensive, so let's be as lazy as
+	 * we can and only do it if we really have to.
+	 */
+	if (vpe->col_idx != cpu) {
+		vpe->col_idx = cpu;
+		its_send_vmovp(vpe);
+	}
+
+	return IRQ_SET_MASK_OK_DONE;
+}
+
 static void its_vpe_schedule(struct its_vpe *vpe)
 {
 	void * __iomem vlpi_base = gic_data_rdist_vlpi_base();
@@ -2222,6 +2317,7 @@ static int its_vpe_set_vcpu_affinity(struct irq_data *d, void *vcpu_info)
 
 static struct irq_chip its_vpe_irq_chip = {
 	.name			= "GICv4-vpe",
+	.irq_set_affinity	= its_vpe_set_affinity,
 	.irq_set_vcpu_affinity	= its_vpe_set_vcpu_affinity,
 };
 
-- 
2.11.0

Back to linux.kernel | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

[PATCH v2 00/52] irqchip: KVM: Add support for GICv4 Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:10 +0200
  [PATCH v2 07/52] irqchip/gic-v3-its: Implement irq_set_irqchip_state for pending state Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:10 +0200
  [PATCH v2 39/52] KVM: arm/arm64: GICv4: Wire mapping/unmapping of VLPIs in VFIO irq bypass Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:10 +0200
  [PATCH v2 51/52] KVM: arm/arm64: GICv4: Use pending_last as a scheduling hint Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:10 +0200
  [PATCH v2 30/52] irqchip/gic-v4: Add VPE command interface Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:10 +0200
  [PATCH v2 48/52] KVM: arm/arm64: GICv4: Add doorbell interrupt handling Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:10 +0200
  [PATCH v2 28/52] irqchip/gic-v3-its: Set implementation defined bit to enable VLPIs Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:10 +0200
  [PATCH v2 43/52] KVM: arm/arm64: GICv4: Handle CLEAR applied to a VLPI Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:10 +0200
  [PATCH v2 44/52] KVM: arm/arm64: GICv4: Handle MOVALL applied to a vPE Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:10 +0200
  [PATCH v2 41/52] KVM: arm/arm64: GICv4: Unmap VLPI when freeing an LPI Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:10 +0200
  [PATCH v2 50/52] KVM: arm/arm64: GICv4: Enable virtual cpuif if VLPIs can be delivered Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:10 +0200
  [PATCH v2 49/52] KVM: arm/arm64: GICv4: Hook vPE scheduling into vgic flush/sync Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:10 +0200
  [PATCH v2 37/52] KVM: arm/arm64: GICv4: Add init and teardown of the vPE irq domain Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:10 +0200
  [PATCH v2 52/52] KVM: arm/arm64: GICv4: Enable VLPI support Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:10 +0200
  [PATCH v2 35/52] KVM: arm/arm64: vgic: Move kvm_vgic_destroy call around Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:10 +0200
  [PATCH v2 08/52] irqchip/gic-v3-its: Split out property table allocation Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:10 +0200
  [PATCH v2 47/52] KVM: arm/arm64: GICv4: Propagate VLPI properties at map time Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
  [PATCH v2 19/52] irqchip/gic-v3-its: Add VPE domain infrastructure Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
  [PATCH v2 15/52] irqchip/gic-v3-its: Add GICv4 ITS command definitions Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
  [PATCH v2 42/52] KVM: arm/arm64: GICv4: Handle MOVI applied to a VLPI Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
  [PATCH v2 38/52] KVM: arm/arm64: GICv4: Wire init/teardown of per-VM support Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
  [PATCH v2 32/52] irqchip/gic-v4: Add some basic documentation Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
  [PATCH v2 24/52] irqchip/gic-v3-its: Add VPE invalidation hook Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
  [PATCH v2 33/52] irqchip/gic-v4: Enable low-level GICv4 operations Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
  [PATCH v2 29/52] irqchip/gic-v4: Add per-VM VPE domain creation Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
  [PATCH v2 22/52] irqchip/gic-v3-its: Add VPENDBASER/VPROPBASER accessors Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
  [PATCH v2 13/52] irqchip/gic-v3-its: Generalize LPI configuration Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
  [PATCH v2 40/52] KVM: arm/arm64: GICv4: Handle INT command applied to a VLPI Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
  [PATCH v2 23/52] irqchip/gic-v3-its: Add VPE scheduling Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
  [PATCH v2 17/52] irqchip/gic-v3-its: Add VLPI map/unmap operations Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
  [PATCH v2 46/52] KVM: arm/arm64: GICv4: Handle INVALL applied to a vPE Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
  [PATCH v2 12/52] irqchip/gic-v3-its: Generalize device table allocation Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
  [PATCH v2 09/52] irqchip/gic-v3-its: Allow use of indirect VCPU tables Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
  [PATCH v2 14/52] irqchip/gic-v4: Add management structure definitions Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
  [PATCH v2 11/52] irqchip/gic-v3-its: Rework LPI freeing Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
  [PATCH v2 31/52] irqchip/gic-v4: Add VLPI configuration interface Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
  [PATCH v2 21/52] irqchip/gic-v3-its: Add VPE irq domain [de]activation Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
  [PATCH v2 25/52] irqchip/gic-v3-its: Add VPE affinity changes Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
  [PATCH v2 18/52] irqchip/gic-v3-its: Add VLPI configuration handling Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
  [PATCH v2 16/52] irqchip/gic-v3-its: Add VLPI configuration hook Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
  [PATCH v2 20/52] irqchip/gic-v3-its: Add VPE irq domain allocation/teardown Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
  [PATCH v2 36/52] KVM: arm/arm64: vITS: Add MSI translation helpers Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
  [PATCH v2 10/52] irqchip/gic-v3-its: Split out pending table allocation Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:30 +0200
  [PATCH v2 02/52] irqchip/gic-v3: Add redistributor iterator Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:30 +0200
  [PATCH v2 06/52] irqchip/gic-v3-its: Macro-ize its_send_single_command Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:30 +0200
  [PATCH v2 04/52] irqchip/gic-v3-its: Move LPI definitions around Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:30 +0200
  [PATCH v2 05/52] irqchip/gic-v3-its: Add probing for VLPI properties Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:30 +0200
  RE: [PATCH v2 00/52] irqchip: KVM: Add support for GICv4 "Shanker Donthineni" <shankerd@codeaurora.org> - 2017-07-01 17:00 +0200

csiph-web