aboutsummaryrefslogtreecommitdiffstats
path: root/xen/common/softirq.c
diff options
context:
space:
mode:
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2004-06-18 14:46:29 +0000
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2004-06-18 14:46:29 +0000
commit60b6be9ccdd46b8cbddf1d96a89b4e6239248ee9 (patch)
treeb477b901498e1f22504ea55339680079600767d6 /xen/common/softirq.c
parent82eefd80489f629cde550047982bece346aca22e (diff)
downloadxen-60b6be9ccdd46b8cbddf1d96a89b4e6239248ee9.tar.gz
xen-60b6be9ccdd46b8cbddf1d96a89b4e6239248ee9.tar.bz2
xen-60b6be9ccdd46b8cbddf1d96a89b4e6239248ee9.zip
bitkeeper revision 1.982 (40d300456_XUbFFOMxRh4MjyB7AfJA)
Hacked the scheduler interfaces in Xen. We now have synchronous pause. Suspend/death VIRQs have gone away; replace by dom-controller msgs. Xen no longer knows about PS/2 keyboard/mouse; DOM0 can go straight at them.
Diffstat (limited to 'xen/common/softirq.c')
-rw-r--r--xen/common/softirq.c165
1 files changed, 10 insertions, 155 deletions
diff --git a/xen/common/softirq.c b/xen/common/softirq.c
index c8bbdb95ed..63d2c8d859 100644
--- a/xen/common/softirq.c
+++ b/xen/common/softirq.c
@@ -1,13 +1,12 @@
/******************************************************************************
* common/softirq.c
*
- * Modified from the Linux original. Softirqs in Xen are only executed in
- * an outermost activation (e.g., never within an interrupt activation).
- * This simplifies some things and generally seems a good thing.
+ * Softirqs in Xen are only executed in an outermost activation (e.g., never
+ * within an interrupt activation). This simplifies some things and generally
+ * seems a good thing.
*
* Copyright (c) 2003, K A Fraser
- *
- * Copyright (C) 1992 Linus Torvalds
+ * Copyright (c) 1992, Linus Torvalds
*/
#include <xen/config.h>
@@ -18,35 +17,24 @@
irq_cpustat_t irq_stat[NR_CPUS];
-static struct softirq_action softirq_vec[32] __cacheline_aligned;
+static softirq_handler softirq_handlers[NR_SOFTIRQS] __cacheline_aligned;
asmlinkage void do_softirq()
{
unsigned int pending, cpu = smp_processor_id();
- struct softirq_action *h;
-
- if ( unlikely(in_interrupt()) )
- BUG();
-
- /*
- * XEN: This isn't real mutual-exclusion: it just ensures that in_softirq()
- * and in_interrupt() are both TRUE, allowing checks for erroneous reentry.
- */
- cpu_bh_disable(cpu);
+ softirq_handler *h;
while ( (pending = xchg(&softirq_pending(cpu), 0)) != 0 )
{
- h = softirq_vec;
+ h = softirq_handlers;
while ( pending )
{
if ( pending & 1 )
- h->action(h);
+ (*h)();
h++;
pending >>= 1;
}
}
-
- cpu_bh_enable(cpu);
}
inline void cpu_raise_softirq(unsigned int cpu, unsigned int nr)
@@ -63,140 +51,7 @@ void raise_softirq(unsigned int nr)
__cpu_raise_softirq(smp_processor_id(), nr);
}
-void open_softirq(int nr, void (*action)(struct softirq_action*), void *data)
-{
- softirq_vec[nr].data = data;
- softirq_vec[nr].action = action;
-}
-
-
-/* Tasklets */
-
-struct tasklet_head tasklet_vec[NR_CPUS] __cacheline_aligned;
-struct tasklet_head tasklet_hi_vec[NR_CPUS] __cacheline_aligned;
-
-void __tasklet_schedule(struct tasklet_struct *t)
-{
- int cpu = smp_processor_id();
- unsigned long flags;
-
- local_irq_save(flags);
- t->next = tasklet_vec[cpu].list;
- tasklet_vec[cpu].list = t;
- cpu_raise_softirq(cpu, TASKLET_SOFTIRQ);
- local_irq_restore(flags);
-}
-
-void __tasklet_hi_schedule(struct tasklet_struct *t)
-{
- int cpu = smp_processor_id();
- unsigned long flags;
-
- local_irq_save(flags);
- t->next = tasklet_hi_vec[cpu].list;
- tasklet_hi_vec[cpu].list = t;
- cpu_raise_softirq(cpu, HI_SOFTIRQ);
- local_irq_restore(flags);
-}
-
-static void tasklet_action(struct softirq_action *a)
-{
- int cpu = smp_processor_id();
- struct tasklet_struct *list;
-
- local_irq_disable();
- list = tasklet_vec[cpu].list;
- tasklet_vec[cpu].list = NULL;
- local_irq_enable();
-
- while ( list != NULL )
- {
- struct tasklet_struct *t = list;
-
- list = list->next;
-
- if ( likely(tasklet_trylock(t)) )
- {
- if ( likely(!atomic_read(&t->count)) )
- {
- if ( unlikely(!test_and_clear_bit(TASKLET_STATE_SCHED,
- &t->state)) )
- BUG();
- t->func(t->data);
- }
- tasklet_unlock(t);
- continue;
- }
-
- local_irq_disable();
- t->next = tasklet_vec[cpu].list;
- tasklet_vec[cpu].list = t;
- __cpu_raise_softirq(cpu, TASKLET_SOFTIRQ);
- local_irq_enable();
- }
-}
-
-static void tasklet_hi_action(struct softirq_action *a)
-{
- int cpu = smp_processor_id();
- struct tasklet_struct *list;
-
- local_irq_disable();
- list = tasklet_hi_vec[cpu].list;
- tasklet_hi_vec[cpu].list = NULL;
- local_irq_enable();
-
- while ( list != NULL )
- {
- struct tasklet_struct *t = list;
-
- list = list->next;
-
- if ( likely(tasklet_trylock(t)) )
- {
- if ( likely(!atomic_read(&t->count)) )
- {
- if ( unlikely(!test_and_clear_bit(TASKLET_STATE_SCHED,
- &t->state)) )
- BUG();
- t->func(t->data);
- }
- tasklet_unlock(t);
- continue;
- }
-
- local_irq_disable();
- t->next = tasklet_hi_vec[cpu].list;
- tasklet_hi_vec[cpu].list = t;
- __cpu_raise_softirq(cpu, HI_SOFTIRQ);
- local_irq_enable();
- }
-}
-
-
-void tasklet_init(struct tasklet_struct *t,
- void (*func)(unsigned long), unsigned long data)
-{
- t->next = NULL;
- t->state = 0;
- atomic_set(&t->count, 0);
- t->func = func;
- t->data = data;
-}
-
-void tasklet_kill(struct tasklet_struct *t)
-{
- if ( in_interrupt() )
- BUG();
- while ( test_and_set_bit(TASKLET_STATE_SCHED, &t->state) )
- while ( test_bit(TASKLET_STATE_SCHED, &t->state) )
- do_softirq();
- tasklet_unlock_wait(t);
- clear_bit(TASKLET_STATE_SCHED, &t->state);
-}
-
-void __init softirq_init()
+void open_softirq(int nr, softirq_handler handler)
{
- open_softirq(TASKLET_SOFTIRQ, tasklet_action, NULL);
- open_softirq(HI_SOFTIRQ, tasklet_hi_action, NULL);
+ softirq_handlers[nr] = handler;
}