1 /******************************************************************************
4 * Xen balloon driver - enables returning/claiming memory to/from Xen.
6 * Copyright (c) 2003, B Dragovic
7 * Copyright (c) 2003-2004, M Williamson, K Fraser
9 * This file may be distributed separately from the Linux kernel, or
10 * incorporated into other software packages, subject to the following license:
12 * Permission is hereby granted, free of charge, to any person obtaining a copy
13 * of this source file (the "Software"), to deal in the Software without
14 * restriction, including without limitation the rights to use, copy, modify,
15 * merge, publish, distribute, sublicense, and/or sell copies of the Software,
16 * and to permit persons to whom the Software is furnished to do so, subject to
17 * the following conditions:
19 * The above copyright notice and this permission notice shall be included in
20 * all copies or substantial portions of the Software.
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
31 #include <linux/config.h>
32 #include <linux/kernel.h>
33 #include <linux/module.h>
34 #include <linux/sched.h>
35 #include <linux/errno.h>
37 #include <linux/mman.h>
38 #include <linux/smp_lock.h>
39 #include <linux/pagemap.h>
40 #include <linux/bootmem.h>
41 #include <linux/highmem.h>
42 #include <linux/vmalloc.h>
43 #include <asm-xen/xen_proc.h>
44 #include <asm-xen/hypervisor.h>
45 #include <asm-xen/ctrl_if.h>
46 #include <asm-xen/balloon.h>
47 #include <asm/pgalloc.h>
48 #include <asm/pgtable.h>
49 #include <asm/uaccess.h>
51 #include <linux/list.h>
53 static struct proc_dir_entry *balloon_pde;
55 static DECLARE_MUTEX(balloon_mutex);
56 spinlock_t balloon_lock = SPIN_LOCK_UNLOCKED;
58 /* We aim for 'current allocation' == 'target allocation'. */
59 static unsigned long current_pages;
60 static unsigned long target_pages;
62 /* We may hit the hard limit in Xen. If we do then we remember it. */
63 static unsigned long hard_limit;
66 * Drivers may alter the memory reservation independently, but they must
67 * inform the balloon driver so that we can avoid hitting the hard limit.
69 static unsigned long driver_pages;
71 /* List of ballooned pages, threaded through the mem_map array. */
72 static LIST_HEAD(ballooned_pages);
73 static unsigned long balloon_low, balloon_high;
75 /* Main work function, always executed in process context. */
76 static void balloon_process(void *unused);
77 static DECLARE_WORK(balloon_worker, balloon_process, NULL);
78 static struct timer_list balloon_timer;
80 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
81 /* Use the private and mapping fields of struct page as a list. */
82 #define PAGE_TO_LIST(p) ( (struct list_head *)&p->private )
83 #define LIST_TO_PAGE(l) ( list_entry( ((unsigned long *)l), \
84 struct page, private ) )
85 #define UNLIST_PAGE(p) do { list_del(PAGE_TO_LIST(p)); \
87 p->private = 0; } while(0)
89 /* There's a dedicated list field in struct page we can use. */
90 #define PAGE_TO_LIST(p) ( &p->list )
91 #define LIST_TO_PAGE(l) ( list_entry(l, struct page, list) )
92 #define UNLIST_PAGE(p) ( list_del(&p->list) )
93 #define pte_offset_kernel pte_offset
95 #define pud_offset(d, va) d
98 #define subsys_initcall(_fn) __initcall(_fn)
99 #define pfn_to_page(_pfn) (mem_map + (_pfn))
102 #define IPRINTK(fmt, args...) \
103 printk(KERN_INFO "xen_mem: " fmt, ##args)
104 #define WPRINTK(fmt, args...) \
105 printk(KERN_WARNING "xen_mem: " fmt, ##args)
107 /* balloon_append: add the given page to the balloon. */
108 static void balloon_append(struct page *page)
110 /* Low memory is re-populated first, so highmem pages go at list tail. */
111 if ( PageHighMem(page) )
113 list_add_tail(PAGE_TO_LIST(page), &ballooned_pages);
118 list_add(PAGE_TO_LIST(page), &ballooned_pages);
123 /* balloon_retrieve: rescue a page from the balloon, if it is not empty. */
124 static struct page *balloon_retrieve(void)
128 if ( list_empty(&ballooned_pages) )
131 page = LIST_TO_PAGE(ballooned_pages.next);
134 if ( PageHighMem(page) )
142 static void balloon_alarm(unsigned long unused)
144 schedule_work(&balloon_worker);
147 static unsigned long current_target(void)
149 unsigned long target = min(target_pages, hard_limit);
150 if ( target > (current_pages + balloon_low + balloon_high) )
151 target = current_pages + balloon_low + balloon_high;
156 * We avoid multiple worker processes conflicting via the balloon mutex.
157 * We may of course race updates of the target counts (which are protected
158 * by the balloon lock), or with changes to the Xen hard limit, but we will
159 * recover from these in time.
161 static void balloon_process(void *unused)
163 unsigned long *mfn_list, pfn, i, flags;
165 long credit, debt, rc;
168 down(&balloon_mutex);
173 if ( (credit = current_target() - current_pages) > 0 )
175 mfn_list = (unsigned long *)vmalloc(credit * sizeof(*mfn_list));
176 if ( mfn_list == NULL )
180 rc = HYPERVISOR_dom_mem_op(
181 MEMOP_increase_reservation, mfn_list, credit, 0);
182 balloon_unlock(flags);
185 /* We hit the Xen hard limit: reprobe. */
186 if ( HYPERVISOR_dom_mem_op(
187 MEMOP_decrease_reservation, mfn_list, rc, 0) != rc )
189 hard_limit = current_pages + rc - driver_pages;
194 for ( i = 0; i < credit; i++ )
196 if ( (page = balloon_retrieve()) == NULL )
199 pfn = page - mem_map;
200 if ( phys_to_machine_mapping[pfn] != INVALID_P2M_ENTRY )
203 /* Update P->M and M->P tables. */
204 phys_to_machine_mapping[pfn] = mfn_list[i];
205 xen_machphys_update(mfn_list[i], pfn);
207 /* Link back into the page tables if it's not a highmem page. */
208 if ( pfn < max_low_pfn )
210 HYPERVISOR_update_va_mapping(
211 (unsigned long)__va(pfn << PAGE_SHIFT),
212 __pte_ma((mfn_list[i] << PAGE_SHIFT) |
213 pgprot_val(PAGE_KERNEL)),
217 /* Finally, relinquish the memory back to the system allocator. */
218 ClearPageReserved(page);
219 set_page_count(page, 1);
223 current_pages += credit;
225 else if ( credit < 0 )
229 mfn_list = (unsigned long *)vmalloc(debt * sizeof(*mfn_list));
230 if ( mfn_list == NULL )
233 for ( i = 0; i < debt; i++ )
235 if ( (page = alloc_page(GFP_HIGHUSER)) == NULL )
241 pfn = page - mem_map;
242 mfn_list[i] = phys_to_machine_mapping[pfn];
244 if ( !PageHighMem(page) )
246 v = phys_to_virt(pfn << PAGE_SHIFT);
248 HYPERVISOR_update_va_mapping(
249 (unsigned long)v, __pte_ma(0), 0);
251 #ifdef CONFIG_XEN_SCRUB_PAGES
261 /* Ensure that ballooned highmem pages don't have cached mappings. */
265 /* No more mappings: invalidate pages in P2M and add to balloon. */
266 for ( i = 0; i < debt; i++ )
268 pfn = mfn_to_pfn(mfn_list[i]);
269 phys_to_machine_mapping[pfn] = INVALID_P2M_ENTRY;
270 balloon_append(pfn_to_page(pfn));
273 if ( HYPERVISOR_dom_mem_op(
274 MEMOP_decrease_reservation, mfn_list, debt, 0) != debt )
277 current_pages -= debt;
281 if ( mfn_list != NULL )
284 /* Schedule more work if there is some still to be done. */
285 if ( current_target() != current_pages )
286 mod_timer(&balloon_timer, jiffies + HZ);
291 /* Resets the Xen limit, sets new target, and kicks off processing. */
292 static void set_new_target(unsigned long target)
294 /* No need for lock. Not read-modify-write updates. */
296 target_pages = target;
297 schedule_work(&balloon_worker);
300 static void balloon_ctrlif_rx(ctrl_msg_t *msg, unsigned long id)
302 switch ( msg->subtype )
304 case CMSG_MEM_REQUEST_SET:
306 mem_request_t *req = (mem_request_t *)&msg->msg[0];
307 set_new_target(req->target);
317 ctrl_if_send_response(msg);
320 static int balloon_write(struct file *file, const char __user *buffer,
321 unsigned long count, void *data)
323 char memstring[64], *endchar;
324 unsigned long long target_bytes;
326 if ( !capable(CAP_SYS_ADMIN) )
330 return -EBADMSG; /* runt */
331 if ( count > sizeof(memstring) )
332 return -EFBIG; /* too long */
334 if ( copy_from_user(memstring, buffer, count) )
336 memstring[sizeof(memstring)-1] = '\0';
338 target_bytes = memparse(memstring, &endchar);
339 set_new_target(target_bytes >> PAGE_SHIFT);
344 static int balloon_read(char *page, char **start, off_t off,
345 int count, int *eof, void *data)
349 #define K(_p) ((_p)<<(PAGE_SHIFT-10))
352 "Current allocation: %8lu kB\n"
353 "Requested target: %8lu kB\n"
354 "Low-mem balloon: %8lu kB\n"
355 "High-mem balloon: %8lu kB\n"
357 K(current_pages), K(target_pages), K(balloon_low), K(balloon_high));
359 if ( hard_limit != ~0UL )
362 "%8lu kB (inc. %8lu kB driver headroom)\n",
363 K(hard_limit), K(driver_pages));
373 static int __init balloon_init(void)
378 IPRINTK("Initialising balloon driver.\n");
380 current_pages = min(xen_start_info.nr_pages, max_pfn);
381 target_pages = current_pages;
387 init_timer(&balloon_timer);
388 balloon_timer.data = 0;
389 balloon_timer.function = balloon_alarm;
391 if ( (balloon_pde = create_xen_proc_entry("balloon", 0644)) == NULL )
393 WPRINTK("Unable to create /proc/xen/balloon.\n");
397 balloon_pde->read_proc = balloon_read;
398 balloon_pde->write_proc = balloon_write;
400 (void)ctrl_if_register_receiver(CMSG_MEM_REQUEST, balloon_ctrlif_rx, 0);
402 /* Initialise the balloon with excess memory space. */
403 for ( pfn = xen_start_info.nr_pages; pfn < max_pfn; pfn++ )
405 page = &mem_map[pfn];
406 if ( !PageReserved(page) )
407 balloon_append(page);
413 subsys_initcall(balloon_init);
415 void balloon_update_driver_allowance(long delta)
419 driver_pages += delta; /* non-atomic update */
420 balloon_unlock(flags);
423 void balloon_put_pages(unsigned long *mfn_list, unsigned long nr_mfns)
428 if ( HYPERVISOR_dom_mem_op(MEMOP_decrease_reservation,
429 mfn_list, nr_mfns, 0) != nr_mfns )
431 current_pages -= nr_mfns; /* non-atomic update */
432 balloon_unlock(flags);
434 schedule_work(&balloon_worker);
437 EXPORT_SYMBOL(balloon_update_driver_allowance);
438 EXPORT_SYMBOL(balloon_put_pages);