ia64/xen-unstable

view xen/common/softirq.c @ 19835:edfdeb150f27

Fix buildsystem to detect udev > version 124

udev removed the udevinfo symlink from versions higher than 123 and
xen's build-system could not detect if udev is in place and has the
required version.

Signed-off-by: Marc-A. Dahlhaus <mad@wol.de>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Jun 25 13:02:37 2009 +0100 (2009-06-25)
parents 98b89c2b1cde
children
line source
1 /******************************************************************************
2 * common/softirq.c
3 *
4 * Softirqs in Xen are only executed in an outermost activation (e.g., never
5 * within an interrupt activation). This simplifies some things and generally
6 * seems a good thing.
7 *
8 * Copyright (c) 2003, K A Fraser
9 * Copyright (c) 1992, Linus Torvalds
10 */
12 #include <xen/config.h>
13 #include <xen/init.h>
14 #include <xen/mm.h>
15 #include <xen/sched.h>
16 #include <xen/rcupdate.h>
17 #include <xen/softirq.h>
19 #ifndef __ARCH_IRQ_STAT
20 irq_cpustat_t irq_stat[NR_CPUS];
21 #endif
23 static softirq_handler softirq_handlers[NR_SOFTIRQS];
25 asmlinkage void do_softirq(void)
26 {
27 unsigned int i, cpu;
28 unsigned long pending;
30 for ( ; ; )
31 {
32 /*
33 * Initialise @cpu on every iteration: SCHEDULE_SOFTIRQ may move
34 * us to another processor.
35 */
36 cpu = smp_processor_id();
38 if ( rcu_pending(cpu) )
39 rcu_check_callbacks(cpu);
41 if ( (pending = softirq_pending(cpu)) == 0 )
42 break;
44 i = find_first_set_bit(pending);
45 clear_bit(i, &softirq_pending(cpu));
46 (*softirq_handlers[i])();
47 }
48 }
50 void open_softirq(int nr, softirq_handler handler)
51 {
52 ASSERT(nr < NR_SOFTIRQS);
53 softirq_handlers[nr] = handler;
54 }
56 static LIST_HEAD(tasklet_list);
57 static DEFINE_SPINLOCK(tasklet_lock);
59 void tasklet_schedule(struct tasklet *t)
60 {
61 unsigned long flags;
63 spin_lock_irqsave(&tasklet_lock, flags);
65 if ( !t->is_dead )
66 {
67 if ( !t->is_scheduled && !t->is_running )
68 {
69 BUG_ON(!list_empty(&t->list));
70 list_add_tail(&t->list, &tasklet_list);
71 }
72 t->is_scheduled = 1;
73 raise_softirq(TASKLET_SOFTIRQ);
74 }
76 spin_unlock_irqrestore(&tasklet_lock, flags);
77 }
79 static void tasklet_action(void)
80 {
81 struct tasklet *t;
83 spin_lock_irq(&tasklet_lock);
85 if ( list_empty(&tasklet_list) )
86 {
87 spin_unlock_irq(&tasklet_lock);
88 return;
89 }
91 t = list_entry(tasklet_list.next, struct tasklet, list);
92 list_del_init(&t->list);
94 BUG_ON(t->is_dead || t->is_running || !t->is_scheduled);
95 t->is_scheduled = 0;
96 t->is_running = 1;
98 spin_unlock_irq(&tasklet_lock);
99 t->func(t->data);
100 spin_lock_irq(&tasklet_lock);
102 t->is_running = 0;
104 if ( t->is_scheduled )
105 {
106 BUG_ON(t->is_dead || !list_empty(&t->list));
107 list_add_tail(&t->list, &tasklet_list);
108 }
110 /*
111 * If there is more work to do then reschedule. We don't grab more work
112 * immediately as we want to allow other softirq work to happen first.
113 */
114 if ( !list_empty(&tasklet_list) )
115 raise_softirq(TASKLET_SOFTIRQ);
117 spin_unlock_irq(&tasklet_lock);
118 }
120 void tasklet_kill(struct tasklet *t)
121 {
122 unsigned long flags;
124 spin_lock_irqsave(&tasklet_lock, flags);
126 if ( !list_empty(&t->list) )
127 {
128 BUG_ON(t->is_dead || t->is_running || !t->is_scheduled);
129 list_del_init(&t->list);
130 }
131 t->is_scheduled = 0;
132 t->is_dead = 1;
134 while ( t->is_running )
135 {
136 spin_unlock_irqrestore(&tasklet_lock, flags);
137 cpu_relax();
138 spin_lock_irqsave(&tasklet_lock, flags);
139 }
141 spin_unlock_irqrestore(&tasklet_lock, flags);
142 }
144 void tasklet_init(
145 struct tasklet *t, void (*func)(unsigned long), unsigned long data)
146 {
147 memset(t, 0, sizeof(*t));
148 INIT_LIST_HEAD(&t->list);
149 t->func = func;
150 t->data = data;
151 }
153 void __init softirq_init(void)
154 {
155 open_softirq(TASKLET_SOFTIRQ, tasklet_action);
156 }
158 /*
159 * Local variables:
160 * mode: C
161 * c-set-style: "BSD"
162 * c-basic-offset: 4
163 * tab-width: 4
164 * indent-tabs-mode: nil
165 * End:
166 */