diff options
Diffstat (limited to 'drivers/xen/xen-selfballoon.c')
-rw-r--r-- | drivers/xen/xen-selfballoon.c | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/drivers/xen/xen-selfballoon.c b/drivers/xen/xen-selfballoon.c index 146c94897016..7d041cb6da26 100644 --- a/drivers/xen/xen-selfballoon.c +++ b/drivers/xen/xen-selfballoon.c | |||
@@ -105,6 +105,12 @@ static unsigned int selfballoon_interval __read_mostly = 5; | |||
105 | */ | 105 | */ |
106 | static unsigned int selfballoon_min_usable_mb; | 106 | static unsigned int selfballoon_min_usable_mb; |
107 | 107 | ||
108 | /* | ||
109 | * Amount of RAM in MB to add to the target number of pages. | ||
110 | * Can be used to reserve some more room for caches and the like. | ||
111 | */ | ||
112 | static unsigned int selfballoon_reserved_mb; | ||
113 | |||
108 | static void selfballoon_process(struct work_struct *work); | 114 | static void selfballoon_process(struct work_struct *work); |
109 | static DECLARE_DELAYED_WORK(selfballoon_worker, selfballoon_process); | 115 | static DECLARE_DELAYED_WORK(selfballoon_worker, selfballoon_process); |
110 | 116 | ||
@@ -217,7 +223,8 @@ static void selfballoon_process(struct work_struct *work) | |||
217 | cur_pages = totalram_pages; | 223 | cur_pages = totalram_pages; |
218 | tgt_pages = cur_pages; /* default is no change */ | 224 | tgt_pages = cur_pages; /* default is no change */ |
219 | goal_pages = percpu_counter_read_positive(&vm_committed_as) + | 225 | goal_pages = percpu_counter_read_positive(&vm_committed_as) + |
220 | totalreserve_pages; | 226 | totalreserve_pages + |
227 | MB2PAGES(selfballoon_reserved_mb); | ||
221 | #ifdef CONFIG_FRONTSWAP | 228 | #ifdef CONFIG_FRONTSWAP |
222 | /* allow space for frontswap pages to be repatriated */ | 229 | /* allow space for frontswap pages to be repatriated */ |
223 | if (frontswap_selfshrinking && frontswap_enabled) | 230 | if (frontswap_selfshrinking && frontswap_enabled) |
@@ -397,6 +404,30 @@ static DEVICE_ATTR(selfballoon_min_usable_mb, S_IRUGO | S_IWUSR, | |||
397 | show_selfballoon_min_usable_mb, | 404 | show_selfballoon_min_usable_mb, |
398 | store_selfballoon_min_usable_mb); | 405 | store_selfballoon_min_usable_mb); |
399 | 406 | ||
407 | SELFBALLOON_SHOW(selfballoon_reserved_mb, "%d\n", | ||
408 | selfballoon_reserved_mb); | ||
409 | |||
410 | static ssize_t store_selfballoon_reserved_mb(struct device *dev, | ||
411 | struct device_attribute *attr, | ||
412 | const char *buf, | ||
413 | size_t count) | ||
414 | { | ||
415 | unsigned long val; | ||
416 | int err; | ||
417 | |||
418 | if (!capable(CAP_SYS_ADMIN)) | ||
419 | return -EPERM; | ||
420 | err = strict_strtoul(buf, 10, &val); | ||
421 | if (err || val == 0) | ||
422 | return -EINVAL; | ||
423 | selfballoon_reserved_mb = val; | ||
424 | return count; | ||
425 | } | ||
426 | |||
427 | static DEVICE_ATTR(selfballoon_reserved_mb, S_IRUGO | S_IWUSR, | ||
428 | show_selfballoon_reserved_mb, | ||
429 | store_selfballoon_reserved_mb); | ||
430 | |||
400 | 431 | ||
401 | #ifdef CONFIG_FRONTSWAP | 432 | #ifdef CONFIG_FRONTSWAP |
402 | SELFBALLOON_SHOW(frontswap_selfshrinking, "%d\n", frontswap_selfshrinking); | 433 | SELFBALLOON_SHOW(frontswap_selfshrinking, "%d\n", frontswap_selfshrinking); |
@@ -480,6 +511,7 @@ static struct attribute *selfballoon_attrs[] = { | |||
480 | &dev_attr_selfballoon_downhysteresis.attr, | 511 | &dev_attr_selfballoon_downhysteresis.attr, |
481 | &dev_attr_selfballoon_uphysteresis.attr, | 512 | &dev_attr_selfballoon_uphysteresis.attr, |
482 | &dev_attr_selfballoon_min_usable_mb.attr, | 513 | &dev_attr_selfballoon_min_usable_mb.attr, |
514 | &dev_attr_selfballoon_reserved_mb.attr, | ||
483 | #ifdef CONFIG_FRONTSWAP | 515 | #ifdef CONFIG_FRONTSWAP |
484 | &dev_attr_frontswap_selfshrinking.attr, | 516 | &dev_attr_frontswap_selfshrinking.attr, |
485 | &dev_attr_frontswap_hysteresis.attr, | 517 | &dev_attr_frontswap_hysteresis.attr, |