aboutsummaryrefslogtreecommitdiffstats
path: root/xen
diff options
context:
space:
mode:
authorkaf24@labyrinth.cl.cam.ac.uk <kaf24@labyrinth.cl.cam.ac.uk>2003-02-24 17:56:39 +0000
committerkaf24@labyrinth.cl.cam.ac.uk <kaf24@labyrinth.cl.cam.ac.uk>2003-02-24 17:56:39 +0000
commit2b1c361bee7ecb1dc6d68b8ddadbaaf85f03587f (patch)
tree515cb0e4c0f07cd3720525dc69cc6a6e850655ff /xen
parent704f9b012699742823381c48873de8e18f660366 (diff)
downloadxen-2b1c361bee7ecb1dc6d68b8ddadbaaf85f03587f.tar.gz
xen-2b1c361bee7ecb1dc6d68b8ddadbaaf85f03587f.tar.bz2
xen-2b1c361bee7ecb1dc6d68b8ddadbaaf85f03587f.zip
bitkeeper revision 1.96 (3e5a5cd7-6YCRyx9vceH0j_ljuOe-Q)
hypervisor-ifs: new file Many files: Allow forced killing of domains with 'kill_domain -f'. task_structs now reference counted. .del-network.h~823d28e86ebe9d9b: Delete: xenolinux-2.4.21-pre4-sparse/include/asm-xeno/hypervisor-ifs/network.h .del-hypervisor-if.h~d1f6a7dd4307ddfe: Delete: xenolinux-2.4.21-pre4-sparse/include/asm-xeno/hypervisor-ifs/hypervisor-if.h .del-block.h~81aa08f4e2012da6: Delete: xenolinux-2.4.21-pre4-sparse/include/asm-xeno/hypervisor-ifs/block.h
Diffstat (limited to 'xen')
-rw-r--r--xen/common/dom0_ops.c4
-rw-r--r--xen/common/domain.c35
-rw-r--r--xen/common/network.c6
-rw-r--r--xen/include/asm-i386/processor.h9
-rw-r--r--xen/include/xeno/dom0_ops.h1
-rw-r--r--xen/include/xeno/sched.h6
6 files changed, 38 insertions, 23 deletions
diff --git a/xen/common/dom0_ops.c b/xen/common/dom0_ops.c
index 1d43f641ba..e451a8f3e7 100644
--- a/xen/common/dom0_ops.c
+++ b/xen/common/dom0_ops.c
@@ -81,6 +81,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
wake_up(p);
reschedule(p);
ret = p->domain;
+ free_task_struct(p);
}
break;
@@ -113,13 +114,14 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
case DOM0_KILLDOMAIN:
{
unsigned int dom = op.u.killdomain.domain;
+ int force = op.u.killdomain.force;
if ( dom == IDLE_DOMAIN_ID )
{
ret = -EPERM;
}
else
{
- ret = kill_other_domain(dom);
+ ret = kill_other_domain(dom, force);
}
}
break;
diff --git a/xen/common/domain.c b/xen/common/domain.c
index 5e862ada6d..89efe59f64 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -40,6 +40,8 @@ struct task_struct *do_newdomain(unsigned int dom_id, unsigned int cpu)
if (!p) goto newdomain_out;
memset(p, 0, sizeof(*p));
+ atomic_set(&p->refcnt, 1);
+
p->domain = dom_id;
p->processor = cpu;
@@ -82,6 +84,7 @@ struct task_struct *find_domain_by_id(unsigned int dom)
read_lock_irq(&tasklist_lock);
do {
if ( (p->domain == dom) ) {
+ get_task_struct(p); /* increment the refcnt for caller */
read_unlock_irq(&tasklist_lock);
return (p);
}
@@ -117,27 +120,27 @@ void kill_domain(void)
}
-long kill_other_domain(unsigned int dom)
+long kill_other_domain(unsigned int dom, int force)
{
- struct task_struct *p = &idle0_task;
+ struct task_struct *p;
unsigned long cpu_mask = 0;
- long ret = -ESRCH;
- read_lock_irq(&tasklist_lock);
- do {
- if ( p->domain == dom )
- {
- cpu_mask = mark_guest_event(p, _EVENT_DIE);
- ret = 0;
- break;
- }
- }
- while ( (p = p->next_task) != &idle0_task );
- read_unlock_irq(&tasklist_lock);
+ p = find_domain_by_id(dom);
+ if ( p == NULL ) return -ESRCH;
- hyp_event_notify(cpu_mask);
+ if ( force )
+ {
+ cpu_mask = mark_hyp_event(p, _HYP_EVENT_DIE);
+ hyp_event_notify(cpu_mask);
+ }
+ else
+ {
+ cpu_mask = mark_guest_event(p, _EVENT_DIE);
+ guest_event_notify(cpu_mask);
+ }
- return ret;
+ free_task_struct(p);
+ return 0;
}
diff --git a/xen/common/network.c b/xen/common/network.c
index f761ca9ba2..cd726621f1 100644
--- a/xen/common/network.c
+++ b/xen/common/network.c
@@ -81,7 +81,7 @@ net_vif_t *create_net_vif(int domain)
new_vif->net_ring = new_ring;
new_vif->shadow_ring = shadow_ring;
- new_vif->domain = find_domain_by_id(domain);
+ new_vif->domain = dom_task;
new_vif->list.next = NULL;
@@ -93,6 +93,7 @@ net_vif_t *create_net_vif(int domain)
dom_task->net_vif_list[dom_task->num_net_vifs] = new_vif;
dom_task->num_net_vifs++;
+ free_task_struct(dom_task);
return new_vif;
fail:
@@ -103,6 +104,8 @@ fail:
if ( shadow_ring->tx_ring ) kfree(shadow_ring->tx_ring);
kfree(shadow_ring);
}
+
+ free_task_struct(dom_task);
return NULL;
}
@@ -149,6 +152,7 @@ void vif_query(vif_query_t *vq)
copy_to_user(vq->buf, buf, strlen(buf) + 1);
+ free_task_struct(dom_task);
}
diff --git a/xen/include/asm-i386/processor.h b/xen/include/asm-i386/processor.h
index 36a50b2976..e5d2e420ac 100644
--- a/xen/include/asm-i386/processor.h
+++ b/xen/include/asm-i386/processor.h
@@ -440,9 +440,12 @@ unsigned long get_wchan(struct task_struct *p);
#define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1022])
#define THREAD_SIZE (2*PAGE_SIZE)
-#define alloc_task_struct() ((struct task_struct *) __get_free_pages(GFP_KERNEL,1))
-#define free_task_struct(p) free_pages((unsigned long) (p), 1)
-#define get_task_struct(tsk) atomic_inc(&virt_to_page(tsk)->count)
+#define alloc_task_struct() \
+ ((struct task_struct *) __get_free_pages(GFP_KERNEL,1))
+#define free_task_struct(_p) \
+ if ( atomic_dec_and_test(&(_p)->refcnt) ) free_pages((unsigned long)(_p), 1)
+#define get_task_struct(_p) \
+ atomic_inc(&(_p)->refcnt)
#define idle0_task (idle0_task_union.task)
#define idle0_stack (idle0_task_union.stack)
diff --git a/xen/include/xeno/dom0_ops.h b/xen/include/xeno/dom0_ops.h
index 49a5842fab..5e498de1bc 100644
--- a/xen/include/xeno/dom0_ops.h
+++ b/xen/include/xeno/dom0_ops.h
@@ -27,6 +27,7 @@ typedef struct dom0_newdomain_st
typedef struct dom0_killdomain_st
{
unsigned int domain;
+ int force;
} dom0_killdomain_t;
typedef struct dom0_getmemlist_st
diff --git a/xen/include/xeno/sched.h b/xen/include/xeno/sched.h
index 3cffa46bf1..b0855f7b0a 100644
--- a/xen/include/xeno/sched.h
+++ b/xen/include/xeno/sched.h
@@ -60,7 +60,7 @@ struct task_struct {
int processor;
int state;
- int hyp_events;
+ int hyp_events;
unsigned int domain;
/* An unsafe pointer into a shared data area. */
@@ -101,6 +101,8 @@ struct task_struct {
struct task_struct *prev_task, *next_task;
unsigned long flags;
+
+ atomic_t refcnt;
};
/*
@@ -163,7 +165,7 @@ struct task_struct *find_domain_by_id(unsigned int dom);
extern void release_task(struct task_struct *);
extern void kill_domain(void);
extern void kill_domain_with_errmsg(const char *err);
-extern long kill_other_domain(unsigned int dom);
+extern long kill_other_domain(unsigned int dom, int force);
/* arch/process.c */
void new_thread(struct task_struct *p,