37#include <sys/kernel.h>
38#include <sys/kthread.h>
39#include <sys/malloc.h>
41#include <sys/sysctl.h>
42#include <sys/module.h>
45#include <vm/vm_page.h>
47#include <xen/xen-os.h>
48#include <xen/hypervisor.h>
49#include <xen/features.h>
50#include <xen/xenstore/xenstorevar.h>
55#define KB_TO_PAGE_SHIFT (PAGE_SHIFT - 10)
60static xen_pfn_t
frame_list[PAGE_SIZE /
sizeof(xen_pfn_t)];
79#define bs balloon_stats
83 CTLFLAG_RD | CTLFLAG_MPSAFE, NULL,
86 &
bs.current_pages, 0,
"Current allocation");
88 &
bs.target_pages, 0,
"Target allocation");
90 &
bs.driver_pages, 0,
"Driver pages");
92 &
bs.hard_limit, 0,
"Xen hard limit");
94 &
bs.balloon_low, 0,
"Low-mem balloon");
96 &
bs.balloon_high, 0,
"High-mem balloon");
104#define IPRINTK(fmt, args...) \
105 printk(KERN_INFO "xen_mem: " fmt, ##args)
106#define WPRINTK(fmt, args...) \
107 printk(KERN_WARNING "xen_mem: " fmt, ##args)
112 unsigned long target = min(
bs.target_pages,
bs.hard_limit);
113 if (target > (
bs.current_pages +
bs.balloon_low +
bs.balloon_high))
114 target =
bs.current_pages +
bs.balloon_low +
bs.balloon_high;
121 unsigned long min_pages, curr_pages = current_target();
123#define MB2PAGES(mb) ((mb) << (20 - PAGE_SHIFT))
138 min_pages =
MB2PAGES(8) + (realmem >> 1);
140 min_pages =
MB2PAGES(40) + (realmem >> 2);
142 min_pages =
MB2PAGES(104) + (realmem >> 3);
144 min_pages =
MB2PAGES(296) + (realmem >> 5);
148 return (min(min_pages, curr_pages));
157 struct xen_memory_reservation reservation = {
168 for (page = TAILQ_FIRST(&ballooned_pages), i = 0;
169 i < nr_pages; i++, page = TAILQ_NEXT(page, plinks.q)) {
170 KASSERT(page != NULL, (
"ballooned_pages list corrupt"));
171 frame_list[i] = (VM_PAGE_TO_PHYS(page) >> PAGE_SHIFT);
174 set_xen_guest_handle(reservation.extent_start,
frame_list);
175 reservation.nr_extents = nr_pages;
176 rc = HYPERVISOR_memory_op(
177 XENMEM_populate_physmap, &reservation);
183 reservation.nr_extents = rc;
184 ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
186 KASSERT(ret == rc, (
"HYPERVISOR_memory_op failed"));
189 bs.hard_limit = (
bs.current_pages + rc -
194 for (i = 0; i < nr_pages; i++) {
195 page = TAILQ_FIRST(&ballooned_pages);
196 KASSERT(page != NULL, (
"Unable to get ballooned page"));
197 TAILQ_REMOVE(&ballooned_pages, page, plinks.q);
200 KASSERT(xen_feature(XENFEAT_auto_translated_physmap),
201 (
"auto translated physmap but mapping is valid"));
206 bs.current_pages += nr_pages;
219 struct xen_memory_reservation reservation = {
230 for (i = 0; i < nr_pages; i++) {
237 if ((page = vm_page_alloc_noobj(VM_ALLOC_ZERO)) == NULL) {
243 frame_list[i] = (VM_PAGE_TO_PHYS(page) >> PAGE_SHIFT);
245 TAILQ_INSERT_HEAD(&ballooned_pages, page, plinks.q);
249 set_xen_guest_handle(reservation.extent_start,
frame_list);
250 reservation.nr_extents = nr_pages;
251 ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation);
252 KASSERT(ret == nr_pages, (
"HYPERVISOR_memory_op failed"));
254 bs.current_pages -= nr_pages;
276 credit = current_target() -
bs.current_pages;
282 }
while ((credit != 0) && !need_sleep);
285 if (current_target() !=
bs.current_pages)
301 bs.hard_limit = ~0UL;
308 .node =
"memory/target",
315 const char **vec,
unsigned int len)
317 unsigned long long new_target;
320 err =
xs_scanf(XST_NIL,
"memory",
"target", NULL,
321 "%llu", &new_target);
348 BUS_ADD_CHILD(parent, 0, driver->name, 0);
362 device_set_desc(dev,
"Xen Balloon Device");
381 bs.current_pages = realmem;
382 bs.target_pages =
bs.current_pages;
385 bs.driver_pages = 0UL;
386 bs.hard_limit = ~0UL;
395 "xenballon: failed to set balloon watcher\n");
SYSCTL_ULONG(_dev_xen_balloon, OID_AUTO, current, CTLFLAG_RD, &bs.current_pages, 0, "Current allocation")
static void set_new_target(unsigned long target)
static int decrease_reservation(unsigned long nr_pages)
devclass_t xenballoon_devclass
DRIVER_MODULE(xenballoon, xenstore, xenballoon_driver, xenballoon_devclass, NULL, NULL)
static void xenballoon_identify(driver_t *driver __unused, device_t parent)
Identify instances of this device type in the system.
static device_method_t xenballoon_methods[]
static int xenballoon_attach(device_t dev)
Attach the Xen Balloon device.
static TAILQ_HEAD(vm_page)
static int increase_reservation(unsigned long nr_pages)
static unsigned long minimum_target(void)
DEFINE_CLASS_0(xenballoon, xenballoon_driver, xenballoon_methods, 0)
static void balloon_process(void *unused)
static struct xs_watch target_watch
static SYSCTL_NODE(_dev_xen, OID_AUTO, balloon, CTLFLAG_RD|CTLFLAG_MPSAFE, NULL, "Balloon")
static int xenballoon_probe(device_t dev)
Probe for the existence of the Xen Balloon device.
static MALLOC_DEFINE(M_BALLOON, "Balloon", "Xen Balloon Driver")
static xen_pfn_t frame_list[PAGE_SIZE/sizeof(xen_pfn_t)]
static void watch_target(struct xs_watch *watch, const char **vec, unsigned int len)
unsigned long current_pages
unsigned long driver_pages
unsigned long target_pages
unsigned long balloon_high
unsigned long balloon_low
static int xs_watch(const char *path, const char *token)
int xs_scanf(struct xs_transaction t, const char *dir, const char *node, int *scancountp, const char *fmt,...)
int xs_register_watch(struct xs_watch *watch)