diff mbox

[v3,4/7] x86/hyper-v: redirect reenlightment notifications on CPU offlining

Message ID 20180116182700.1042-5-vkuznets@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Vitaly Kuznetsov Jan. 16, 2018, 6:26 p.m. UTC
It is very unlikely for CPUs to get offlined when we run on Hyper-V as
we have a protection in vmbus module which prevents it when we have any
VMBus devices assigned. This, however,  may change in future if an option
to reassign an already active channel will be added. It is also possible
to run without any Hyper-V devices of have a CPU with no assigned channels.

Reassign reenlightenment notifications to some other active CPU when
the CPU which is assigned to get them goes offline.

Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
v2-> v3:
- Drop spinlock protection from hv_cpu_die() as cpu hotplug is already
  serialized [Thomas Gleixner]
- Use cpumask_any_but() in hv_cpu_die() [Thomas Gleixner]
---
 arch/x86/hyperv/hv_init.c | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

Comments

Thomas Gleixner Jan. 16, 2018, 6:31 p.m. UTC | #1
On Tue, 16 Jan 2018, Vitaly Kuznetsov wrote:

> It is very unlikely for CPUs to get offlined when we run on Hyper-V as
> we have a protection in vmbus module which prevents it when we have any
> VMBus devices assigned. This, however,  may change in future if an option
> to reassign an already active channel will be added. It is also possible
> to run without any Hyper-V devices of have a CPU with no assigned channels.
> 
> Reassign reenlightenment notifications to some other active CPU when
> the CPU which is assigned to get them goes offline.
> 
> Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>

Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
diff mbox

Patch

diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 712ac40081f7..e4377e2f2a10 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -191,6 +191,26 @@  void clear_hv_tscchange_cb(void)
 }
 EXPORT_SYMBOL_GPL(clear_hv_tscchange_cb);
 
+static int hv_cpu_die(unsigned int cpu)
+{
+	struct hv_reenlightenment_control re_ctrl;
+	unsigned int new_cpu;
+
+	if (hv_reenlightenment_cb == NULL)
+		return 0;
+
+	rdmsrl(HV_X64_MSR_REENLIGHTENMENT_CONTROL, *((u64 *)&re_ctrl));
+	if (re_ctrl.target_vp == hv_vp_index[cpu]) {
+		/* Reassign to some other online CPU */
+		new_cpu = cpumask_any_but(cpu_online_mask, cpu);
+
+		re_ctrl.target_vp = hv_vp_index[new_cpu];
+		wrmsrl(HV_X64_MSR_REENLIGHTENMENT_CONTROL, *((u64 *)&re_ctrl));
+	}
+
+	return 0;
+}
+
 /*
  * This function is to be invoked early in the boot sequence after the
  * hypervisor has been detected.
@@ -220,7 +240,7 @@  void hyperv_init(void)
 		return;
 
 	if (cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "x86/hyperv_init:online",
-			      hv_cpu_init, NULL) < 0)
+			      hv_cpu_init, hv_cpu_die) < 0)
 		goto free_vp_index;
 
 	/*