ia64/xen-unstable

annotate 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
rev   line source
kaf24@982 1 /******************************************************************************
kaf24@982 2 * common/softirq.c
kaf24@982 3 *
kaf24@1505 4 * Softirqs in Xen are only executed in an outermost activation (e.g., never
kaf24@1505 5 * within an interrupt activation). This simplifies some things and generally
kaf24@1505 6 * seems a good thing.
kaf24@982 7 *
kaf24@982 8 * Copyright (c) 2003, K A Fraser
kaf24@1505 9 * Copyright (c) 1992, Linus Torvalds
iap10@236 10 */
iap10@236 11
kaf24@1210 12 #include <xen/config.h>
kaf24@1506 13 #include <xen/init.h>
kaf24@1210 14 #include <xen/mm.h>
kaf24@1210 15 #include <xen/sched.h>
kaf24@13662 16 #include <xen/rcupdate.h>
kaf24@1506 17 #include <xen/softirq.h>
iap10@236 18
kaf24@3477 19 #ifndef __ARCH_IRQ_STAT
iap10@236 20 irq_cpustat_t irq_stat[NR_CPUS];
kaf24@3477 21 #endif
iap10@236 22
kaf24@3075 23 static softirq_handler softirq_handlers[NR_SOFTIRQS];
iap10@236 24
kaf24@9552 25 asmlinkage void do_softirq(void)
iap10@236 26 {
kfraser@10620 27 unsigned int i, cpu;
kaf24@9552 28 unsigned long pending;
iap10@236 29
kfraser@10620 30 for ( ; ; )
kfraser@10620 31 {
kfraser@10620 32 /*
kfraser@10620 33 * Initialise @cpu on every iteration: SCHEDULE_SOFTIRQ may move
kfraser@10620 34 * us to another processor.
kfraser@10620 35 */
kfraser@10620 36 cpu = smp_processor_id();
kaf24@13662 37
kaf24@13662 38 if ( rcu_pending(cpu) )
kaf24@13662 39 rcu_check_callbacks(cpu);
kaf24@13662 40
kfraser@10620 41 if ( (pending = softirq_pending(cpu)) == 0 )
kfraser@10620 42 break;
kaf24@2814 43
kaf24@2804 44 i = find_first_set_bit(pending);
kaf24@2804 45 clear_bit(i, &softirq_pending(cpu));
kaf24@2804 46 (*softirq_handlers[i])();
kfraser@10620 47 }
iap10@236 48 }
iap10@236 49
kaf24@1505 50 void open_softirq(int nr, softirq_handler handler)
iap10@236 51 {
keir@18408 52 ASSERT(nr < NR_SOFTIRQS);
kaf24@1505 53 softirq_handlers[nr] = handler;
iap10@236 54 }
kaf24@3914 55
keir@17450 56 static LIST_HEAD(tasklet_list);
keir@17450 57 static DEFINE_SPINLOCK(tasklet_lock);
keir@17444 58
keir@17444 59 void tasklet_schedule(struct tasklet *t)
keir@17444 60 {
keir@17444 61 unsigned long flags;
keir@17444 62
keir@17450 63 spin_lock_irqsave(&tasklet_lock, flags);
keir@17444 64
keir@17456 65 if ( !t->is_dead )
keir@17450 66 {
keir@17456 67 if ( !t->is_scheduled && !t->is_running )
keir@17456 68 {
keir@17456 69 BUG_ON(!list_empty(&t->list));
keir@17456 70 list_add_tail(&t->list, &tasklet_list);
keir@17456 71 }
keir@17450 72 t->is_scheduled = 1;
keir@17456 73 raise_softirq(TASKLET_SOFTIRQ);
keir@17450 74 }
keir@17450 75
keir@17450 76 spin_unlock_irqrestore(&tasklet_lock, flags);
keir@17444 77 }
keir@17444 78
keir@17444 79 static void tasklet_action(void)
keir@17444 80 {
keir@17450 81 struct tasklet *t;
keir@17444 82
keir@17450 83 spin_lock_irq(&tasklet_lock);
keir@17450 84
keir@17456 85 if ( list_empty(&tasklet_list) )
keir@17444 86 {
keir@17456 87 spin_unlock_irq(&tasklet_lock);
keir@17456 88 return;
keir@17456 89 }
keir@17444 90
keir@17456 91 t = list_entry(tasklet_list.next, struct tasklet, list);
keir@17456 92 list_del_init(&t->list);
keir@17450 93
keir@17456 94 BUG_ON(t->is_dead || t->is_running || !t->is_scheduled);
keir@17456 95 t->is_scheduled = 0;
keir@17456 96 t->is_running = 1;
keir@17444 97
keir@17456 98 spin_unlock_irq(&tasklet_lock);
keir@17456 99 t->func(t->data);
keir@17456 100 spin_lock_irq(&tasklet_lock);
keir@17456 101
keir@17456 102 t->is_running = 0;
keir@17456 103
keir@17456 104 if ( t->is_scheduled )
keir@17456 105 {
keir@17456 106 BUG_ON(t->is_dead || !list_empty(&t->list));
keir@17456 107 list_add_tail(&t->list, &tasklet_list);
keir@17444 108 }
keir@17450 109
keir@17456 110 /*
keir@17456 111 * If there is more work to do then reschedule. We don't grab more work
keir@17456 112 * immediately as we want to allow other softirq work to happen first.
keir@17456 113 */
keir@17456 114 if ( !list_empty(&tasklet_list) )
keir@17456 115 raise_softirq(TASKLET_SOFTIRQ);
keir@17456 116
keir@17450 117 spin_unlock_irq(&tasklet_lock);
keir@17444 118 }
keir@17444 119
keir@17444 120 void tasklet_kill(struct tasklet *t)
keir@17444 121 {
keir@17450 122 unsigned long flags;
keir@17450 123
keir@17450 124 spin_lock_irqsave(&tasklet_lock, flags);
keir@17450 125
keir@17450 126 if ( !list_empty(&t->list) )
keir@17456 127 {
keir@17456 128 BUG_ON(t->is_dead || t->is_running || !t->is_scheduled);
keir@17456 129 list_del_init(&t->list);
keir@17456 130 }
keir@17456 131 t->is_scheduled = 0;
keir@17456 132 t->is_dead = 1;
keir@17444 133
keir@17444 134 while ( t->is_running )
keir@17450 135 {
keir@17450 136 spin_unlock_irqrestore(&tasklet_lock, flags);
keir@17444 137 cpu_relax();
keir@17450 138 spin_lock_irqsave(&tasklet_lock, flags);
keir@17450 139 }
keir@17444 140
keir@17450 141 spin_unlock_irqrestore(&tasklet_lock, flags);
keir@17444 142 }
keir@17444 143
keir@17444 144 void tasklet_init(
keir@17444 145 struct tasklet *t, void (*func)(unsigned long), unsigned long data)
keir@17444 146 {
keir@17444 147 memset(t, 0, sizeof(*t));
keir@17456 148 INIT_LIST_HEAD(&t->list);
keir@17444 149 t->func = func;
keir@17444 150 t->data = data;
keir@17444 151 }
keir@17444 152
keir@17444 153 void __init softirq_init(void)
keir@17444 154 {
keir@17444 155 open_softirq(TASKLET_SOFTIRQ, tasklet_action);
keir@17444 156 }
keir@17444 157
kaf24@3914 158 /*
kaf24@3914 159 * Local variables:
kaf24@3914 160 * mode: C
kaf24@3914 161 * c-set-style: "BSD"
kaf24@3914 162 * c-basic-offset: 4
kaf24@3914 163 * tab-width: 4
kaf24@3914 164 * indent-tabs-mode: nil
kaf24@3988 165 * End:
kaf24@3914 166 */