ia64/xen-unstable
changeset 5961:3a11dbf5e4b6
The attached patch converts the balloon driver and xend to use
xenstore instead of control messages.
Note: Because there is no way to set a watch on a non-existent key,
this patch includes a workaround to account for the fact that dom0's
store keys are not initialized by the tools before it boots.
Signed-off-by: Dan Smith <danms@us.ibm.com>
xenstore instead of control messages.
Note: Because there is no way to set a watch on a non-existent key,
this patch includes a workaround to account for the fact that dom0's
store keys are not initialized by the tools before it boots.
Signed-off-by: Dan Smith <danms@us.ibm.com>
author | kaf24@firebug.cl.cam.ac.uk |
---|---|
date | Tue Aug 02 11:21:11 2005 +0000 (2005-08-02) |
parents | eeb45fed8f91 |
children | 3f1785f02d89 |
files | linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c tools/python/xen/xend/XendDomainInfo.py |
line diff
1.1 --- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Tue Aug 02 11:20:12 2005 +0000 1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Tue Aug 02 11:21:11 2005 +0000 1.3 @@ -5,6 +5,7 @@ 1.4 * 1.5 * Copyright (c) 2003, B Dragovic 1.6 * Copyright (c) 2003-2004, M Williamson, K Fraser 1.7 + * Copyright (c) 2005 Dan M. Smith, IBM Corporation 1.8 * 1.9 * This file may be distributed separately from the Linux kernel, or 1.10 * incorporated into other software packages, subject to the following license: 1.11 @@ -42,7 +43,6 @@ 1.12 #include <linux/vmalloc.h> 1.13 #include <asm-xen/xen_proc.h> 1.14 #include <asm-xen/hypervisor.h> 1.15 -#include <asm-xen/ctrl_if.h> 1.16 #include <asm-xen/balloon.h> 1.17 #include <asm/pgalloc.h> 1.18 #include <asm/pgtable.h> 1.19 @@ -50,6 +50,10 @@ 1.20 #include <asm/tlb.h> 1.21 #include <linux/list.h> 1.22 1.23 +#include<asm-xen/xenbus.h> 1.24 + 1.25 +#define PAGES2KB(_p) ((_p)<<(PAGE_SHIFT-10)) 1.26 + 1.27 static struct proc_dir_entry *balloon_pde; 1.28 1.29 static DECLARE_MUTEX(balloon_mutex); 1.30 @@ -77,11 +81,17 @@ static void balloon_process(void *unused 1.31 static DECLARE_WORK(balloon_worker, balloon_process, NULL); 1.32 static struct timer_list balloon_timer; 1.33 1.34 +/* Flag for dom0 xenstore workaround */ 1.35 +static int balloon_xenbus_init=0; 1.36 + 1.37 +/* Init Function */ 1.38 +void balloon_init_watcher(void); 1.39 + 1.40 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) 1.41 /* Use the private and mapping fields of struct page as a list. */ 1.42 #define PAGE_TO_LIST(p) ( (struct list_head *)&p->private ) 1.43 #define LIST_TO_PAGE(l) ( list_entry( ((unsigned long *)l), \ 1.44 - struct page, private ) ) 1.45 + struct page, private ) ) 1.46 #define UNLIST_PAGE(p) do { list_del(PAGE_TO_LIST(p)); \ 1.47 p->mapping = NULL; \ 1.48 p->private = 0; } while(0) 1.49 @@ -297,26 +307,97 @@ static void set_new_target(unsigned long 1.50 schedule_work(&balloon_worker); 1.51 } 1.52 1.53 -static void balloon_ctrlif_rx(ctrl_msg_t *msg, unsigned long id) 1.54 +static struct xenbus_watch xb_watch = 1.55 +{ 1.56 + .node = "memory" 1.57 +}; 1.58 + 1.59 +/* FIXME: This is part of a dom0 sequencing workaround */ 1.60 +static struct xenbus_watch root_watch = 1.61 { 1.62 - switch ( msg->subtype ) 1.63 - { 1.64 - case CMSG_MEM_REQUEST_SET: 1.65 + .node = "/" 1.66 +}; 1.67 + 1.68 +/* React to a change in the target key */ 1.69 +static void watch_target(struct xenbus_watch *watch, const char *node) 1.70 +{ 1.71 + unsigned long new_target; 1.72 + int err; 1.73 + 1.74 + if(watch == &root_watch) 1.75 { 1.76 - mem_request_t *req = (mem_request_t *)&msg->msg[0]; 1.77 - set_new_target(req->target); 1.78 - req->status = 0; 1.79 - } 1.80 - break; 1.81 - 1.82 - default: 1.83 - msg->length = 0; 1.84 - break; 1.85 + /* FIXME: This is part of a dom0 sequencing workaround */ 1.86 + if(register_xenbus_watch(&xb_watch) == 0) 1.87 + { 1.88 + /* 1.89 + We successfully set a watch on memory/target: 1.90 + now we can stop watching root 1.91 + */ 1.92 + unregister_xenbus_watch(&root_watch); 1.93 + balloon_xenbus_init=1; 1.94 + } 1.95 + else 1.96 + { 1.97 + return; 1.98 + } 1.99 } 1.100 1.101 - ctrl_if_send_response(msg); 1.102 + err = xenbus_scanf("memory", "target", "%lu", &new_target); 1.103 + 1.104 + if(err != 1) 1.105 + { 1.106 + IPRINTK("Unable to read memory/target\n"); 1.107 + return; 1.108 + } 1.109 + 1.110 + set_new_target(new_target >> PAGE_SHIFT); 1.111 + 1.112 } 1.113 1.114 +/* 1.115 + Try to set up our watcher, if not already set 1.116 + 1.117 +*/ 1.118 +void balloon_init_watcher(void) 1.119 +{ 1.120 + int err; 1.121 + 1.122 + if(!xen_start_info.store_evtchn) 1.123 + { 1.124 + IPRINTK("Delaying watcher init until xenstore is available\n"); 1.125 + return; 1.126 + } 1.127 + 1.128 + down(&xenbus_lock); 1.129 + 1.130 + if(! balloon_xenbus_init) 1.131 + { 1.132 + err = register_xenbus_watch(&xb_watch); 1.133 + if(err) 1.134 + { 1.135 + /* BIG FAT FIXME: dom0 sequencing workaround 1.136 + * dom0 can't set a watch on memory/target until 1.137 + * after the tools create it. So, we have to watch 1.138 + * the whole store until that happens. 1.139 + * 1.140 + * This will go away when we have the ability to watch 1.141 + * non-existant keys 1.142 + */ 1.143 + register_xenbus_watch(&root_watch); 1.144 + } 1.145 + else 1.146 + { 1.147 + IPRINTK("Balloon xenbus watcher initialized\n"); 1.148 + balloon_xenbus_init = 1; 1.149 + } 1.150 + } 1.151 + 1.152 + up(&xenbus_lock); 1.153 + 1.154 +} 1.155 + 1.156 +EXPORT_SYMBOL(balloon_init_watcher); 1.157 + 1.158 static int balloon_write(struct file *file, const char __user *buffer, 1.159 unsigned long count, void *data) 1.160 { 1.161 @@ -346,7 +427,6 @@ static int balloon_read(char *page, char 1.162 { 1.163 int len; 1.164 1.165 -#define K(_p) ((_p)<<(PAGE_SHIFT-10)) 1.166 len = sprintf( 1.167 page, 1.168 "Current allocation: %8lu kB\n" 1.169 @@ -354,13 +434,14 @@ static int balloon_read(char *page, char 1.170 "Low-mem balloon: %8lu kB\n" 1.171 "High-mem balloon: %8lu kB\n" 1.172 "Xen hard limit: ", 1.173 - K(current_pages), K(target_pages), K(balloon_low), K(balloon_high)); 1.174 + PAGES2KB(current_pages), PAGES2KB(target_pages), 1.175 + PAGES2KB(balloon_low), PAGES2KB(balloon_high)); 1.176 1.177 if ( hard_limit != ~0UL ) 1.178 len += sprintf( 1.179 page + len, 1.180 "%8lu kB (inc. %8lu kB driver headroom)\n", 1.181 - K(hard_limit), K(driver_pages)); 1.182 + PAGES2KB(hard_limit), PAGES2KB(driver_pages)); 1.183 else 1.184 len += sprintf( 1.185 page + len, 1.186 @@ -396,9 +477,7 @@ static int __init balloon_init(void) 1.187 1.188 balloon_pde->read_proc = balloon_read; 1.189 balloon_pde->write_proc = balloon_write; 1.190 - 1.191 - (void)ctrl_if_register_receiver(CMSG_MEM_REQUEST, balloon_ctrlif_rx, 0); 1.192 - 1.193 + 1.194 /* Initialise the balloon with excess memory space. */ 1.195 for ( pfn = xen_start_info.nr_pages; pfn < max_pfn; pfn++ ) 1.196 { 1.197 @@ -407,6 +486,11 @@ static int __init balloon_init(void) 1.198 balloon_append(page); 1.199 } 1.200 1.201 + xb_watch.callback = watch_target; 1.202 + root_watch.callback = watch_target; 1.203 + 1.204 + balloon_init_watcher(); 1.205 + 1.206 return 0; 1.207 } 1.208
2.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Tue Aug 02 11:20:12 2005 +0000 2.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Tue Aug 02 11:21:11 2005 +0000 2.3 @@ -309,6 +309,9 @@ int do_xenbus_probe(void *unused) 2.4 return err; 2.5 } 2.6 2.7 + /* Initialize non-xenbus drivers */ 2.8 + balloon_init_watcher(); 2.9 + 2.10 down(&xenbus_lock); 2.11 /* Enumerate devices in xenstore. */ 2.12 xenbus_probe_devices("device");
3.1 --- a/tools/python/xen/xend/XendDomainInfo.py Tue Aug 02 11:20:12 2005 +0000 3.2 +++ b/tools/python/xen/xend/XendDomainInfo.py Tue Aug 02 11:21:11 2005 +0000 3.3 @@ -152,6 +152,9 @@ class XendDomainInfo: 3.4 vm = cls(db) 3.5 vm.construct(config) 3.6 vm.saveToDB(sync=True) 3.7 + # Flush info to xenstore immediately 3.8 + vm.exportToDB() 3.9 + 3.10 return vm 3.11 3.12 create = classmethod(create) 3.13 @@ -172,6 +175,7 @@ class XendDomainInfo: 3.14 log.debug('config=' + prettyprintstring(config)) 3.15 3.16 vm.memory = info['mem_kb']/1024 3.17 + vm.target = info['mem_kb'] * 1024 3.18 3.19 if config: 3.20 try: 3.21 @@ -222,6 +226,7 @@ class XendDomainInfo: 3.22 DBVar('restart_state', ty='str'), 3.23 DBVar('restart_time', ty='float'), 3.24 DBVar('restart_count', ty='int'), 3.25 + DBVar('target', ty='long', path="memory/target"), 3.26 ] 3.27 3.28 def __init__(self, db): 3.29 @@ -240,6 +245,8 @@ class XendDomainInfo: 3.30 self.ssidref = None 3.31 self.image = None 3.32 3.33 + self.target = None 3.34 + 3.35 self.channel = None 3.36 self.store_channel = None 3.37 self.store_mfn = None 3.38 @@ -315,6 +322,7 @@ class XendDomainInfo: 3.39 self.info = info 3.40 self.memory = self.info['mem_kb'] / 1024 3.41 self.ssidref = self.info['ssidref'] 3.42 + self.target = self.info['mem_kb'] * 1024 3.43 3.44 def state_set(self, state): 3.45 self.state_updated.acquire() 3.46 @@ -399,7 +407,8 @@ class XendDomainInfo: 3.47 ['id', self.id], 3.48 ['name', self.name], 3.49 ['memory', self.memory], 3.50 - ['ssidref', self.ssidref] ] 3.51 + ['ssidref', self.ssidref], 3.52 + ['target', self.target] ] 3.53 if self.uuid: 3.54 sxpr.append(['uuid', self.uuid]) 3.55 if self.info: 3.56 @@ -536,6 +545,7 @@ class XendDomainInfo: 3.57 self.memory = int(sxp.child_value(config, 'memory')) 3.58 if self.memory is None: 3.59 raise VmError('missing memory size') 3.60 + self.target = self.memory * (1 << 20) 3.61 self.ssidref = int(sxp.child_value(config, 'ssidref')) 3.62 cpu = sxp.child_value(config, 'cpu') 3.63 if self.recreate and self.id and cpu is not None and int(cpu) >= 0: 3.64 @@ -947,11 +957,12 @@ class XendDomainInfo: 3.65 index[field_name] = field_index + 1 3.66 3.67 def mem_target_set(self, target): 3.68 - """Set domain memory target in pages. 3.69 + """Set domain memory target in bytes. 3.70 """ 3.71 - if self.channel: 3.72 - msg = messages.packMsg('mem_request_t', { 'target' : target * (1 << 8)} ) 3.73 - self.channel.writeRequest(msg) 3.74 + if target: 3.75 + self.target = target * (1 << 20) 3.76 + # Commit to XenStore immediately 3.77 + self.exportToDB() 3.78 3.79 def vcpu_hotplug(self, vcpu, state): 3.80 """Disable or enable VCPU in domain.