diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/xen/balloon.c | 3 | ||||
| -rw-r--r-- | drivers/xen/xen-balloon.c | 22 |
2 files changed, 15 insertions, 10 deletions
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index 50dcb68d8070..ab609255a0f3 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c | |||
| @@ -780,6 +780,9 @@ static int __init balloon_init(void) | |||
| 780 | } | 780 | } |
| 781 | #endif | 781 | #endif |
| 782 | 782 | ||
| 783 | /* Init the xen-balloon driver. */ | ||
| 784 | xen_balloon_init(); | ||
| 785 | |||
| 783 | return 0; | 786 | return 0; |
| 784 | } | 787 | } |
| 785 | subsys_initcall(balloon_init); | 788 | subsys_initcall(balloon_init); |
diff --git a/drivers/xen/xen-balloon.c b/drivers/xen/xen-balloon.c index e7715cb62eef..e89136ab851e 100644 --- a/drivers/xen/xen-balloon.c +++ b/drivers/xen/xen-balloon.c | |||
| @@ -59,6 +59,8 @@ static void watch_target(struct xenbus_watch *watch, | |||
| 59 | { | 59 | { |
| 60 | unsigned long long new_target; | 60 | unsigned long long new_target; |
| 61 | int err; | 61 | int err; |
| 62 | static bool watch_fired; | ||
| 63 | static long target_diff; | ||
| 62 | 64 | ||
| 63 | err = xenbus_scanf(XBT_NIL, "memory", "target", "%llu", &new_target); | 65 | err = xenbus_scanf(XBT_NIL, "memory", "target", "%llu", &new_target); |
| 64 | if (err != 1) { | 66 | if (err != 1) { |
| @@ -69,7 +71,14 @@ static void watch_target(struct xenbus_watch *watch, | |||
| 69 | /* The given memory/target value is in KiB, so it needs converting to | 71 | /* The given memory/target value is in KiB, so it needs converting to |
| 70 | * pages. PAGE_SHIFT converts bytes to pages, hence PAGE_SHIFT - 10. | 72 | * pages. PAGE_SHIFT converts bytes to pages, hence PAGE_SHIFT - 10. |
| 71 | */ | 73 | */ |
| 72 | balloon_set_new_target(new_target >> (PAGE_SHIFT - 10)); | 74 | new_target >>= PAGE_SHIFT - 10; |
| 75 | if (watch_fired) { | ||
| 76 | balloon_set_new_target(new_target - target_diff); | ||
| 77 | return; | ||
| 78 | } | ||
| 79 | |||
| 80 | watch_fired = true; | ||
| 81 | target_diff = new_target - balloon_stats.target_pages; | ||
| 73 | } | 82 | } |
| 74 | static struct xenbus_watch target_watch = { | 83 | static struct xenbus_watch target_watch = { |
| 75 | .node = "memory/target", | 84 | .node = "memory/target", |
| @@ -94,22 +103,15 @@ static struct notifier_block xenstore_notifier = { | |||
| 94 | .notifier_call = balloon_init_watcher, | 103 | .notifier_call = balloon_init_watcher, |
| 95 | }; | 104 | }; |
| 96 | 105 | ||
| 97 | static int __init balloon_init(void) | 106 | void xen_balloon_init(void) |
| 98 | { | 107 | { |
| 99 | if (!xen_domain()) | ||
| 100 | return -ENODEV; | ||
| 101 | |||
| 102 | pr_info("Initialising balloon driver\n"); | ||
| 103 | |||
| 104 | register_balloon(&balloon_dev); | 108 | register_balloon(&balloon_dev); |
| 105 | 109 | ||
| 106 | register_xen_selfballooning(&balloon_dev); | 110 | register_xen_selfballooning(&balloon_dev); |
| 107 | 111 | ||
| 108 | register_xenstore_notifier(&xenstore_notifier); | 112 | register_xenstore_notifier(&xenstore_notifier); |
| 109 | |||
| 110 | return 0; | ||
| 111 | } | 113 | } |
| 112 | subsys_initcall(balloon_init); | 114 | EXPORT_SYMBOL_GPL(xen_balloon_init); |
| 113 | 115 | ||
| 114 | #define BALLOON_SHOW(name, format, args...) \ | 116 | #define BALLOON_SHOW(name, format, args...) \ |
| 115 | static ssize_t show_##name(struct device *dev, \ | 117 | static ssize_t show_##name(struct device *dev, \ |
