ia64/xen-unstable

changeset 1813:66e83b24aca7

bitkeeper revision 1.1103 (40f832cfY5flkPnN6fgkffTZGuEDcg)

New ballooning interface from David Becker. A much more sensible
'memory target' value is exported via /proc.
author kaf24@scramble.cl.cam.ac.uk
date Fri Jul 16 19:55:59 2004 +0000 (2004-07-16)
parents bd80b2bba0ce
children ae33aca75a3e
files linux-2.4.26-xen-sparse/arch/xen/drivers/balloon/balloon.c
line diff
     1.1 --- a/linux-2.4.26-xen-sparse/arch/xen/drivers/balloon/balloon.c	Fri Jul 16 12:33:42 2004 +0000
     1.2 +++ b/linux-2.4.26-xen-sparse/arch/xen/drivers/balloon/balloon.c	Fri Jul 16 19:55:59 2004 +0000
     1.3 @@ -39,6 +39,7 @@ typedef struct user_balloon_op {
     1.4  
     1.5  static struct proc_dir_entry *balloon_pde;
     1.6  unsigned long credit;
     1.7 +static unsigned long current_pages, max_pages;
     1.8  
     1.9  static inline pte_t *get_ptep(unsigned long addr)
    1.10  {
    1.11 @@ -221,50 +222,86 @@ unsigned long deflate_balloon(unsigned l
    1.12      return ret;
    1.13  }
    1.14  
    1.15 +#define PAGE_TO_MB_SHIFT 8
    1.16 +
    1.17  static int balloon_write(struct file *file, const char *buffer,
    1.18                           u_long count, void *data)
    1.19  {
    1.20 -    user_balloon_op_t bop;
    1.21 +    char memstring[64], *endchar;
    1.22 +    int len, i, pages;
    1.23 +    unsigned long long target;
    1.24  
    1.25      /* Only admin can play with the balloon :) */
    1.26      if ( !capable(CAP_SYS_ADMIN) )
    1.27          return -EPERM;
    1.28  
    1.29 -    if ( copy_from_user(&bop, buffer, sizeof(bop)) )
    1.30 +    if (count>sizeof memstring) {
    1.31 +	    return -EFBIG;
    1.32 +    }
    1.33 +
    1.34 +    len = strnlen_user(buffer, count);
    1.35 +    if (len==0) return -EBADMSG;
    1.36 +    if (len==1) return 1; /* input starts with a NUL char */
    1.37 +    if ( strncpy_from_user(memstring, buffer, len) < 0)
    1.38          return -EFAULT;
    1.39  
    1.40 -    switch ( bop.op )
    1.41 -    {
    1.42 -    case USER_INFLATE_BALLOON:
    1.43 -        if ( inflate_balloon(bop.size) < bop.size )
    1.44 -            return -EAGAIN;
    1.45 -        break;
    1.46 -        
    1.47 -    case USER_DEFLATE_BALLOON:
    1.48 -        deflate_balloon(bop.size);
    1.49 -        break;
    1.50 +    endchar = memstring;
    1.51 +    for(i=0; i<len; ++i,++endchar) {
    1.52 +	    if ('0'>memstring[i] || memstring[i]>'9') break;
    1.53 +    }
    1.54 +    if (i==0) return -EBADMSG;
    1.55 +
    1.56 +    target = memparse(memstring,&endchar);
    1.57 +    pages = target >> PAGE_SHIFT;
    1.58  
    1.59 -    default:
    1.60 -        printk("Unknown command to balloon driver.");
    1.61 -        return -EFAULT;
    1.62 +    if (pages < current_pages) {
    1.63 +	    int change = inflate_balloon(current_pages-pages);
    1.64 +	    if (change<0) return change;
    1.65 +
    1.66 +	    current_pages -= change;
    1.67 +    	    printk("Relinquish %dMB to xen. Domain now has %dMB\n",
    1.68 +		    change>>PAGE_TO_MB_SHIFT, current_pages>>PAGE_TO_MB_SHIFT);
    1.69 +    }
    1.70 +    else if (pages > current_pages) {
    1.71 +	    int change = deflate_balloon(min(pages,max_pages) - current_pages);
    1.72 +	    if (change<0) return change;
    1.73 +
    1.74 +	    current_pages += change;
    1.75 +    	    printk("Reclaim %dMB from xen. Domain now has %dMB\n",
    1.76 +		    change>>PAGE_TO_MB_SHIFT, current_pages>>PAGE_TO_MB_SHIFT);
    1.77      }
    1.78  
    1.79 -    return sizeof(bop);
    1.80 +    return len;
    1.81 +}
    1.82 +
    1.83 +
    1.84 +static int balloon_read(char *page, char **start, off_t off,
    1.85 +	  int count, int *eof, void *data)
    1.86 +{
    1.87 +	int len;
    1.88 +	len = sprintf(page,"%ul\n",current_pages<<PAGE_SHIFT);
    1.89 +
    1.90 +	if (len <= off+count) *eof = 1;
    1.91 +	*start = page + off;
    1.92 +	len -= off;
    1.93 +	if (len>count) len = count;
    1.94 +	if (len<0) len = 0;
    1.95 +	return len;
    1.96  }
    1.97  
    1.98  static int __init init_module(void)
    1.99  {
   1.100      printk(KERN_ALERT "Starting Xen Balloon driver\n");
   1.101  
   1.102 -    credit = 0;
   1.103 -
   1.104 -    if ( (balloon_pde = create_xen_proc_entry("balloon", 0600)) == NULL )
   1.105 +    max_pages = current_pages = start_info.nr_pages;
   1.106 +    if ( (balloon_pde = create_xen_proc_entry("memory_target", 0644)) == NULL )
   1.107      {
   1.108          printk(KERN_ALERT "Unable to create balloon driver proc entry!");
   1.109          return -1;
   1.110      }
   1.111  
   1.112      balloon_pde->write_proc = balloon_write;
   1.113 +    balloon_pde->read_proc = balloon_read;
   1.114  
   1.115      return 0;
   1.116  }