static int __cpuinit setup_cpu_watcher(struct notifier_block *notifier, unsigned long event, void *data) { unsigned int i; static struct xenbus_watch __cpuinitdata cpu_watch = { .node = "cpu", .callback = handle_vcpu_hotplug_event, .flags = XBWF_new_thread }; (void)register_xenbus_watch(&cpu_watch); if (!is_initial_xendomain()) { for_each_possible_cpu(i) vcpu_hotplug(i); printk(KERN_INFO "Brought up %ld CPUs\n", (long)num_online_cpus()); } return NOTIFY_DONE; } static int __init setup_vcpu_hotplug_event(void) { static struct notifier_block hotplug_cpu = { .notifier_call = smpboot_cpu_notify }; static struct notifier_block __cpuinitdata xsn_cpu = { .notifier_call = setup_cpu_watcher }; if (!is_running_on_xen()) return -ENODEV; register_cpu_notifier(&hotplug_cpu); register_xenstore_notifier(&xsn_cpu); return 0; } arch_initcall(setup_vcpu_hotplug_event); int __ref smp_suspend(void) { unsigned int cpu; int err; for_each_online_cpu(cpu) { if (cpu == 0) continue; err = cpu_down(cpu); if (err) { printk(KERN_CRIT "Failed to take all CPUs " "down: %d.\n", err); for_each_possible_cpu(cpu) vcpu_hotplug(cpu); return err; } } return 0; }
void smp_resume(void) { int cpu; for_each_possible_cpu(cpu) vcpu_hotplug(cpu); }
void __ref smp_resume(void) { unsigned int cpu; for_each_possible_cpu(cpu) { if (cpu == 0) continue; vcpu_hotplug(cpu); } }
static void handle_vcpu_hotplug_event(struct xenbus_watch *watch, const char *path, const char *token) { unsigned int cpu; char *cpustr; cpustr = strstr(path, "cpu/"); if (cpustr != NULL) { sscanf(cpustr, "cpu/%u", &cpu); vcpu_hotplug(cpu); } }
static void handle_vcpu_hotplug_event( struct xenbus_watch *watch, const char **vec, unsigned int len) { int cpu; char *cpustr; const char *node = vec[XS_WATCH_PATH]; if ((cpustr = strstr(node, "cpu/")) != NULL) { sscanf(cpustr, "cpu/%d", &cpu); vcpu_hotplug(cpu); } }