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 <vkuzn...@redhat.com>
---
 drivers/hv/hv.c           | 15 +++++++--------
 drivers/hv/hyperv_vmbus.h |  4 ++--
 drivers/hv/vmbus_drv.c    | 19 +++++++++++--------
 3 files changed, 20 insertions(+), 18 deletions(-)

diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index c11393c..b3f6a1b 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -495,7 +495,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;
@@ -504,10 +504,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);
@@ -562,7 +560,7 @@ void hv_synic_init(void *arg)
                                                HV_TIMER_FREQUENCY,
                                                HV_MIN_DELTA_TICKS,
                                                HV_MAX_MAX_DELTA_TICKS);
-       return;
+       return 0;
 }
 
 /*
@@ -582,16 +580,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) {
@@ -623,4 +620,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;
 }
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index a5b4442..d50d56c 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -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);
 
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 0276d2e..a115c90 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -49,6 +49,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)
 {
@@ -844,7 +845,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;
@@ -866,7 +872,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();
@@ -1320,12 +1326,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);
 };
 
@@ -1337,7 +1340,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);
 };
 
@@ -1401,8 +1404,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)
-- 
2.7.4

_______________________________________________
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

Reply via email to