forked from Minki/linux
hv: switch to cpuhp state machine for synic init/cleanup
To make it possible to online/offline CPUs switch to cpuhp infrastructure for doing hv_synic_init()/hv_synic_cleanup(). Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com> Signed-off-by: K. Y. Srinivasan <kys@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
e7e97dd8b7
commit
76d36ab798
@ -496,7 +496,7 @@ void hv_synic_free(void)
|
||||
* retrieve the initialized message and event pages. Otherwise, we create and
|
||||
* initialize the message and event pages.
|
||||
*/
|
||||
void hv_synic_init(void *arg)
|
||||
int hv_synic_init(unsigned int cpu)
|
||||
{
|
||||
u64 version;
|
||||
union hv_synic_simp simp;
|
||||
@ -505,10 +505,8 @@ void hv_synic_init(void *arg)
|
||||
union hv_synic_scontrol sctrl;
|
||||
u64 vp_index;
|
||||
|
||||
int cpu = smp_processor_id();
|
||||
|
||||
if (!hv_context.hypercall_page)
|
||||
return;
|
||||
return -EFAULT;
|
||||
|
||||
/* Check the version */
|
||||
rdmsrl(HV_X64_MSR_SVERSION, version);
|
||||
@ -563,7 +561,7 @@ void hv_synic_init(void *arg)
|
||||
HV_TIMER_FREQUENCY,
|
||||
HV_MIN_DELTA_TICKS,
|
||||
HV_MAX_MAX_DELTA_TICKS);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -583,16 +581,15 @@ void hv_synic_clockevents_cleanup(void)
|
||||
/*
|
||||
* hv_synic_cleanup - Cleanup routine for hv_synic_init().
|
||||
*/
|
||||
void hv_synic_cleanup(void *arg)
|
||||
int hv_synic_cleanup(unsigned int cpu)
|
||||
{
|
||||
union hv_synic_sint shared_sint;
|
||||
union hv_synic_simp simp;
|
||||
union hv_synic_siefp siefp;
|
||||
union hv_synic_scontrol sctrl;
|
||||
int cpu = smp_processor_id();
|
||||
|
||||
if (!hv_context.synic_initialized)
|
||||
return;
|
||||
return -EFAULT;
|
||||
|
||||
/* Turn off clockevent device */
|
||||
if (ms_hyperv.features & HV_X64_MSR_SYNTIMER_AVAILABLE) {
|
||||
@ -624,4 +621,6 @@ void hv_synic_cleanup(void *arg)
|
||||
rdmsrl(HV_X64_MSR_SCONTROL, sctrl.as_uint64);
|
||||
sctrl.enable = 0;
|
||||
wrmsrl(HV_X64_MSR_SCONTROL, sctrl.as_uint64);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -505,9 +505,9 @@ extern int hv_synic_alloc(void);
|
||||
|
||||
extern void hv_synic_free(void);
|
||||
|
||||
extern void hv_synic_init(void *irqarg);
|
||||
extern int hv_synic_init(unsigned int cpu);
|
||||
|
||||
extern void hv_synic_cleanup(void *arg);
|
||||
extern int hv_synic_cleanup(unsigned int cpu);
|
||||
|
||||
extern void hv_synic_clockevents_cleanup(void);
|
||||
|
||||
|
@ -54,6 +54,7 @@ static struct acpi_device *hv_acpi_dev;
|
||||
|
||||
static struct completion probe_event;
|
||||
|
||||
static int hyperv_cpuhp_online;
|
||||
|
||||
static void hyperv_report_panic(struct pt_regs *regs)
|
||||
{
|
||||
@ -997,7 +998,12 @@ static int vmbus_bus_init(void)
|
||||
* Initialize the per-cpu interrupt state and
|
||||
* connect to the host.
|
||||
*/
|
||||
on_each_cpu(hv_synic_init, NULL, 1);
|
||||
ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "x86/hyperv:online",
|
||||
hv_synic_init, hv_synic_cleanup);
|
||||
if (ret < 0)
|
||||
goto err_alloc;
|
||||
hyperv_cpuhp_online = ret;
|
||||
|
||||
ret = vmbus_connect();
|
||||
if (ret)
|
||||
goto err_connect;
|
||||
@ -1019,7 +1025,7 @@ static int vmbus_bus_init(void)
|
||||
return 0;
|
||||
|
||||
err_connect:
|
||||
on_each_cpu(hv_synic_cleanup, NULL, 1);
|
||||
cpuhp_remove_state(hyperv_cpuhp_online);
|
||||
err_alloc:
|
||||
hv_synic_free();
|
||||
hv_remove_vmbus_irq();
|
||||
@ -1478,12 +1484,9 @@ static struct acpi_driver vmbus_acpi_driver = {
|
||||
|
||||
static void hv_kexec_handler(void)
|
||||
{
|
||||
int cpu;
|
||||
|
||||
hv_synic_clockevents_cleanup();
|
||||
vmbus_initiate_unload(false);
|
||||
for_each_online_cpu(cpu)
|
||||
smp_call_function_single(cpu, hv_synic_cleanup, NULL, 1);
|
||||
cpuhp_remove_state(hyperv_cpuhp_online);
|
||||
hv_cleanup(false);
|
||||
};
|
||||
|
||||
@ -1495,7 +1498,7 @@ static void hv_crash_handler(struct pt_regs *regs)
|
||||
* doing the cleanup for current CPU only. This should be sufficient
|
||||
* for kdump.
|
||||
*/
|
||||
hv_synic_cleanup(NULL);
|
||||
hv_synic_cleanup(smp_processor_id());
|
||||
hv_cleanup(true);
|
||||
};
|
||||
|
||||
@ -1559,8 +1562,8 @@ static void __exit vmbus_exit(void)
|
||||
hv_cleanup(false);
|
||||
for_each_online_cpu(cpu) {
|
||||
tasklet_kill(hv_context.event_dpc[cpu]);
|
||||
smp_call_function_single(cpu, hv_synic_cleanup, NULL, 1);
|
||||
}
|
||||
cpuhp_remove_state(hyperv_cpuhp_online);
|
||||
hv_synic_free();
|
||||
acpi_bus_unregister_driver(&vmbus_acpi_driver);
|
||||
if (vmbus_proto_version > VERSION_WIN7)
|
||||
|
Loading…
Reference in New Issue
Block a user