cpu_hotplug.c 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #include <linux/notifier.h>
  2. #include <xen/xenbus.h>
  3. #include <asm/xen/hypervisor.h>
  4. #include <asm/cpu.h>
  5. static void enable_hotplug_cpu(int cpu)
  6. {
  7. if (!cpu_present(cpu))
  8. arch_register_cpu(cpu);
  9. cpu_set(cpu, cpu_present_map);
  10. }
  11. static void disable_hotplug_cpu(int cpu)
  12. {
  13. if (cpu_present(cpu))
  14. arch_unregister_cpu(cpu);
  15. cpu_clear(cpu, cpu_present_map);
  16. }
  17. static void vcpu_hotplug(unsigned int cpu)
  18. {
  19. int err;
  20. char dir[32], state[32];
  21. if (!cpu_possible(cpu))
  22. return;
  23. sprintf(dir, "cpu/%u", cpu);
  24. err = xenbus_scanf(XBT_NIL, dir, "availability", "%s", state);
  25. if (err != 1) {
  26. printk(KERN_ERR "XENBUS: Unable to read cpu state\n");
  27. return;
  28. }
  29. if (strcmp(state, "online") == 0) {
  30. enable_hotplug_cpu(cpu);
  31. } else if (strcmp(state, "offline") == 0) {
  32. (void)cpu_down(cpu);
  33. disable_hotplug_cpu(cpu);
  34. } else {
  35. printk(KERN_ERR "XENBUS: unknown state(%s) on CPU%d\n",
  36. state, cpu);
  37. }
  38. }
  39. static void handle_vcpu_hotplug_event(struct xenbus_watch *watch,
  40. const char **vec, unsigned int len)
  41. {
  42. unsigned int cpu;
  43. char *cpustr;
  44. const char *node = vec[XS_WATCH_PATH];
  45. cpustr = strstr(node, "cpu/");
  46. if (cpustr != NULL) {
  47. sscanf(cpustr, "cpu/%u", &cpu);
  48. vcpu_hotplug(cpu);
  49. }
  50. }
  51. static int setup_cpu_watcher(struct notifier_block *notifier,
  52. unsigned long event, void *data)
  53. {
  54. static struct xenbus_watch cpu_watch = {
  55. .node = "cpu",
  56. .callback = handle_vcpu_hotplug_event};
  57. (void)register_xenbus_watch(&cpu_watch);
  58. return NOTIFY_DONE;
  59. }
  60. static int __init setup_vcpu_hotplug_event(void)
  61. {
  62. static struct notifier_block xsn_cpu = {
  63. .notifier_call = setup_cpu_watcher };
  64. if (!xen_pv_domain())
  65. return -ENODEV;
  66. register_xenstore_notifier(&xsn_cpu);
  67. return 0;
  68. }
  69. arch_initcall(setup_vcpu_hotplug_event);