kernel/softirq.c
29070 /*
29071 * linux/kernel/softirq.c
29072 *
29073 * Copyright (C) 1992 Linus Torvalds
29074 *
29075 * do_bottom_half() runs at normal kernel priority: all
29076 * interrupts enabled. do_bottom_half() is atomic with
29077 * respect to itself: a bottom_half handler need not be
29078 * re-entrant.
29079 *
29080 * Fixed a disable_bh()/enable_bh() race (was causing a
29081 * console lockup) due bh_mask_count not atomic
29082 * handling. Copyright (C) 1998 Andrea Arcangeli
29083 */
29084
29085 #include <linux/mm.h>
29086 #include <linux/kernel_stat.h>
29087 #include <linux/interrupt.h>
29088 #include <linux/smp_lock.h>
29089
29090 #include <asm/io.h>
29091
29092 /* intr_count died a painless death... -DaveM */
29093
29094 atomic_t bh_mask_count[32];
29095 unsigned long bh_active = 0;
29096 unsigned long bh_mask = 0;
29097 void (*bh_base[32])(void);
29098
29099 /* This needs to make sure that only one bottom half
29100 * handler is ever active at a time. We do this without
29101 * locking by doing an atomic increment on the
29102 * intr_count, and checking (nonatomically) against
29103 * 1. Only if it's 1 do we schedule the bottom half.
29104 *
29105 * Note that the non-atomicity of the test (as opposed to
29106 * the actual update) means that the test may fail, and
29107 * _nobody_ runs the handlers if there is a race that
29108 * makes multiple CPU's get here at the same time. That's
29109 * ok, we'll run them next time around. */
29110 static inline void run_bottom_halves(void)
29111 {
29112 unsigned long active;
29113 void (**bh)(void);
29114
29115 active = get_active_bhs();
29116 clear_active_bhs(active);
29117 bh = bh_base;
29118 do {
29119 if (active & 1)
29120 (*bh)();
29121 bh++;
29122 active >>= 1;
29123 } while (active);
29124 }
29125
29126 asmlinkage void do_bottom_half(void)
29127 {
29128 int cpu = smp_processor_id();
29129
29130 if (softirq_trylock(cpu)) {
29131 if (hardirq_trylock(cpu)) {
29132 __sti();
29133 run_bottom_halves();
29134 __cli();
29135 hardirq_endlock(cpu);
29136 }
29137 softirq_endlock(cpu);
29138 }
29139 }
Сайт управляется системой
uCoz