diff options
author | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2003-05-08 18:17:45 +0000 |
---|---|---|
committer | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2003-05-08 18:17:45 +0000 |
commit | 3be360c3385cf0337ea7806d9fc8906db7ac0ae2 (patch) | |
tree | 86c2c2aade2204cd1c795a37c5cdebf5d701c454 | |
parent | 8cca9e4e2057dd159871a65a2f061b1c59d7ff7e (diff) | |
download | xen-3be360c3385cf0337ea7806d9fc8906db7ac0ae2.tar.gz xen-3be360c3385cf0337ea7806d9fc8906db7ac0ae2.tar.bz2 xen-3be360c3385cf0337ea7806d9fc8906db7ac0ae2.zip |
bitkeeper revision 1.222 (3eba9f498RAq8VzoEW7GBoEnFA1WGw)
dom0_ops.c:
Fix domain creation to avoid conflicts in domain-id space.
-rw-r--r-- | xen/common/dom0_ops.c | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/xen/common/dom0_ops.c b/xen/common/dom0_ops.c index 7a13d135c5..52f8b4b1cd 100644 --- a/xen/common/dom0_ops.c +++ b/xen/common/dom0_ops.c @@ -17,12 +17,24 @@ extern unsigned int alloc_new_dom_mem(struct task_struct *, unsigned int); +/* Basically used to protect the domain-id space. */ +static spinlock_t create_dom_lock = SPIN_LOCK_UNLOCKED; + static unsigned int get_domnr(void) { static unsigned int domnr = 0; - do { domnr = (domnr+1) & ((1<<20)-1); } - while ( find_domain_by_id(domnr) != NULL ); - return domnr; + struct task_struct *p; + int tries = 0; + + for ( tries = 0; tries < 1024; tries++ ) + { + domnr = (domnr+1) & ((1<<20)-1); + if ( (p = find_domain_by_id(domnr)) == NULL ) + return domnr; + free_task_struct(p); + } + + return 0; } static void build_page_list(struct task_struct *p) @@ -97,16 +109,18 @@ long do_dom0_op(dom0_op_t *u_dom0_op) { struct task_struct *p; static unsigned int pro = 0; - unsigned int dom = get_domnr(); + unsigned int dom; ret = -ENOMEM; - - if ( dom == 0 ) - break; + + spin_lock_irq(&create_dom_lock); + + if ( (dom = get_domnr()) == 0 ) + goto exit_create; pro = (pro+1) % smp_num_cpus; p = do_newdomain(dom, pro); if ( p == NULL ) - break; + goto exit_create; if (op.u.newdomain.name[0]) { strncpy (p -> name, op.u.newdomain.name, MAX_DOMAIN_NAME); @@ -117,7 +131,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op) if ( ret != 0 ) { __kill_domain(p); - break; + goto exit_create; } build_page_list(p); @@ -129,6 +143,9 @@ long do_dom0_op(dom0_op_t *u_dom0_op) list_entry(p->pg_head.next, struct pfn_info, list) - frame_table; copy_to_user(u_dom0_op, &op, sizeof(op)); + + exit_create: + spin_unlock_irq(&create_dom_lock); } break; |