aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2003-05-08 18:17:45 +0000
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2003-05-08 18:17:45 +0000
commit3be360c3385cf0337ea7806d9fc8906db7ac0ae2 (patch)
tree86c2c2aade2204cd1c795a37c5cdebf5d701c454
parent8cca9e4e2057dd159871a65a2f061b1c59d7ff7e (diff)
downloadxen-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.c35
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;