649f64c402d25a9213a2e71bc112d0c50c705fd4
[linux-2.6.git] / drivers / xen / balloon / balloon.c
1 /******************************************************************************
2  * balloon.c
3  *
4  * Xen balloon driver - enables returning/claiming memory to/from Xen.
5  *
6  * Copyright (c) 2003, B Dragovic
7  * Copyright (c) 2003-2004, M Williamson, K Fraser
8  * 
9  * This file may be distributed separately from the Linux kernel, or
10  * incorporated into other software packages, subject to the following license:
11  * 
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:
18  * 
19  * The above copyright notice and this permission notice shall be included in
20  * all copies or substantial portions of the Software.
21  * 
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
28  * IN THE SOFTWARE.
29  */
30
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>
36 #include <linux/mm.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>
50 #include <asm/tlb.h>
51 #include <linux/list.h>
52
53 static struct proc_dir_entry *balloon_pde;
54
55 static DECLARE_MUTEX(balloon_mutex);
56 spinlock_t balloon_lock = SPIN_LOCK_UNLOCKED;
57
58 /* We aim for 'current allocation' == 'target allocation'. */
59 static unsigned long current_pages;
60 static unsigned long target_pages;
61
62 /* We may hit the hard limit in Xen. If we do then we remember it. */
63 static unsigned long hard_limit;
64
65 /*
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.
68  */
69 static unsigned long driver_pages;
70
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;
74
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;
79
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));       \
86                              p->mapping = NULL;               \
87                              p->private = 0; } while(0)
88 #else
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
94 #define pud_t pgd_t
95 #define pud_offset(d, va) d
96 #define pud_none(d) 0
97 #define pud_bad(d) 0
98 #define subsys_initcall(_fn) __initcall(_fn)
99 #define pfn_to_page(_pfn) (mem_map + (_pfn))
100 #endif
101
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)
106
107 /* balloon_append: add the given page to the balloon. */
108 static void balloon_append(struct page *page)
109 {
110     /* Low memory is re-populated first, so highmem pages go at list tail. */
111     if ( PageHighMem(page) )
112     {
113         list_add_tail(PAGE_TO_LIST(page), &ballooned_pages);
114         balloon_high++;
115     }
116     else
117     {
118         list_add(PAGE_TO_LIST(page), &ballooned_pages);
119         balloon_low++;
120     }
121 }
122
123 /* balloon_retrieve: rescue a page from the balloon, if it is not empty. */
124 static struct page *balloon_retrieve(void)
125 {
126     struct page *page;
127
128     if ( list_empty(&ballooned_pages) )
129         return NULL;
130
131     page = LIST_TO_PAGE(ballooned_pages.next);
132     UNLIST_PAGE(page);
133
134     if ( PageHighMem(page) )
135         balloon_high--;
136     else
137         balloon_low--;
138
139     return page;
140 }
141
142 static void balloon_alarm(unsigned long unused)
143 {
144     schedule_work(&balloon_worker);
145 }
146
147 static unsigned long current_target(void)
148 {
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;
152     return target;
153 }
154
155 /*
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.
160  */
161 static void balloon_process(void *unused)
162 {
163     unsigned long *mfn_list, pfn, i, flags;
164     struct page   *page;
165     long           credit, debt, rc;
166     void          *v;
167
168     down(&balloon_mutex);
169
170  retry:
171     mfn_list = NULL;
172
173     if ( (credit = current_target() - current_pages) > 0 )
174     {
175         mfn_list = (unsigned long *)vmalloc(credit * sizeof(*mfn_list));
176         if ( mfn_list == NULL )
177             goto out;
178
179         balloon_lock(flags);
180         rc = HYPERVISOR_dom_mem_op(
181             MEMOP_increase_reservation, mfn_list, credit, 0);
182         balloon_unlock(flags);
183         if ( rc < credit )
184         {
185             /* We hit the Xen hard limit: reprobe. */
186             if ( HYPERVISOR_dom_mem_op(
187                 MEMOP_decrease_reservation, mfn_list, rc, 0) != rc )
188                 BUG();
189             hard_limit = current_pages + rc - driver_pages;
190             vfree(mfn_list);
191             goto retry;
192         }
193
194         for ( i = 0; i < credit; i++ )
195         {
196             if ( (page = balloon_retrieve()) == NULL )
197                 BUG();
198
199             pfn = page - mem_map;
200             if ( phys_to_machine_mapping[pfn] != INVALID_P2M_ENTRY )
201                 BUG();
202
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);
206             
207             /* Link back into the page tables if it's not a highmem page. */
208             if ( pfn < max_low_pfn )
209             {
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)),
214                     0);
215             }
216
217             /* Finally, relinquish the memory back to the system allocator. */
218             ClearPageReserved(page);
219             set_page_count(page, 1);
220             __free_page(page);
221         }
222
223         current_pages += credit;
224     }
225     else if ( credit < 0 )
226     {
227         debt = -credit;
228
229         mfn_list = (unsigned long *)vmalloc(debt * sizeof(*mfn_list));
230         if ( mfn_list == NULL )
231             goto out;
232
233         for ( i = 0; i < debt; i++ )
234         {
235             if ( (page = alloc_page(GFP_HIGHUSER)) == NULL )
236             {
237                 debt = i;
238                 break;
239             }
240
241             pfn = page - mem_map;
242             mfn_list[i] = phys_to_machine_mapping[pfn];
243
244             if ( !PageHighMem(page) )
245             {
246                 v = phys_to_virt(pfn << PAGE_SHIFT);
247                 scrub_pages(v, 1);
248                 HYPERVISOR_update_va_mapping(
249                     (unsigned long)v, __pte_ma(0), 0);
250             }
251 #ifdef CONFIG_XEN_SCRUB_PAGES
252             else
253             {
254                 v = kmap(page);
255                 scrub_pages(v, 1);
256                 kunmap(page);
257             }
258 #endif
259         }
260
261         /* Ensure that ballooned highmem pages don't have cached mappings. */
262         kmap_flush_unused();
263         flush_tlb_all();
264
265         /* No more mappings: invalidate pages in P2M and add to balloon. */
266         for ( i = 0; i < debt; i++ )
267         {
268             pfn = mfn_to_pfn(mfn_list[i]);
269             phys_to_machine_mapping[pfn] = INVALID_P2M_ENTRY;
270             balloon_append(pfn_to_page(pfn));
271         }
272
273         if ( HYPERVISOR_dom_mem_op(
274             MEMOP_decrease_reservation, mfn_list, debt, 0) != debt )
275             BUG();
276
277         current_pages -= debt;
278     }
279
280  out:
281     if ( mfn_list != NULL )
282         vfree(mfn_list);
283
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);
287
288     up(&balloon_mutex);
289 }
290
291 /* Resets the Xen limit, sets new target, and kicks off processing. */
292 static void set_new_target(unsigned long target)
293 {
294     /* No need for lock. Not read-modify-write updates. */
295     hard_limit   = ~0UL;
296     target_pages = target;
297     schedule_work(&balloon_worker);
298 }
299
300 static void balloon_ctrlif_rx(ctrl_msg_t *msg, unsigned long id)
301 {
302     switch ( msg->subtype )
303     {
304     case CMSG_MEM_REQUEST_SET:
305     {
306         mem_request_t *req = (mem_request_t *)&msg->msg[0];
307         set_new_target(req->target);
308         req->status = 0;
309     }
310     break;        
311
312     default:
313         msg->length = 0;
314         break;
315     }
316
317     ctrl_if_send_response(msg);
318 }
319
320 static int balloon_write(struct file *file, const char __user *buffer,
321                          unsigned long count, void *data)
322 {
323     char memstring[64], *endchar;
324     unsigned long long target_bytes;
325
326     if ( !capable(CAP_SYS_ADMIN) )
327         return -EPERM;
328
329     if ( count <= 1 )
330         return -EBADMSG; /* runt */
331     if ( count > sizeof(memstring) )
332         return -EFBIG;   /* too long */
333
334     if ( copy_from_user(memstring, buffer, count) )
335         return -EFAULT;
336     memstring[sizeof(memstring)-1] = '\0';
337
338     target_bytes = memparse(memstring, &endchar);
339     set_new_target(target_bytes >> PAGE_SHIFT);
340
341     return count;
342 }
343
344 static int balloon_read(char *page, char **start, off_t off,
345                         int count, int *eof, void *data)
346 {
347     int len;
348
349 #define K(_p) ((_p)<<(PAGE_SHIFT-10))
350     len = sprintf(
351         page,
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"
356         "Xen hard limit:     ",
357         K(current_pages), K(target_pages), K(balloon_low), K(balloon_high));
358
359     if ( hard_limit != ~0UL )
360         len += sprintf(
361             page + len, 
362             "%8lu kB (inc. %8lu kB driver headroom)\n",
363             K(hard_limit), K(driver_pages));
364     else
365         len += sprintf(
366             page + len,
367             "     ??? kB\n");
368
369     *eof = 1;
370     return len;
371 }
372
373 static int __init balloon_init(void)
374 {
375     unsigned long pfn;
376     struct page *page;
377
378     IPRINTK("Initialising balloon driver.\n");
379
380     current_pages = min(xen_start_info.nr_pages, max_pfn);
381     target_pages  = current_pages;
382     balloon_low   = 0;
383     balloon_high  = 0;
384     driver_pages  = 0UL;
385     hard_limit    = ~0UL;
386
387     init_timer(&balloon_timer);
388     balloon_timer.data = 0;
389     balloon_timer.function = balloon_alarm;
390     
391     if ( (balloon_pde = create_xen_proc_entry("balloon", 0644)) == NULL )
392     {
393         WPRINTK("Unable to create /proc/xen/balloon.\n");
394         return -1;
395     }
396
397     balloon_pde->read_proc  = balloon_read;
398     balloon_pde->write_proc = balloon_write;
399
400     (void)ctrl_if_register_receiver(CMSG_MEM_REQUEST, balloon_ctrlif_rx, 0);
401
402     /* Initialise the balloon with excess memory space. */
403     for ( pfn = xen_start_info.nr_pages; pfn < max_pfn; pfn++ )
404     {
405         page = &mem_map[pfn];
406         if ( !PageReserved(page) )
407             balloon_append(page);
408     }
409
410     return 0;
411 }
412
413 subsys_initcall(balloon_init);
414
415 void balloon_update_driver_allowance(long delta)
416 {
417     unsigned long flags;
418     balloon_lock(flags);
419     driver_pages += delta; /* non-atomic update */
420     balloon_unlock(flags);
421 }
422
423 void balloon_put_pages(unsigned long *mfn_list, unsigned long nr_mfns)
424 {
425     unsigned long flags;
426
427     balloon_lock(flags);
428     if ( HYPERVISOR_dom_mem_op(MEMOP_decrease_reservation, 
429                                mfn_list, nr_mfns, 0) != nr_mfns )
430         BUG();
431     current_pages -= nr_mfns; /* non-atomic update */
432     balloon_unlock(flags);
433
434     schedule_work(&balloon_worker);
435 }
436
437 EXPORT_SYMBOL(balloon_update_driver_allowance);
438 EXPORT_SYMBOL(balloon_put_pages);