1 #ifdef __KERNEL__
2 #ifndef __ASM_HARDIRQ_H
3 #define __ASM_HARDIRQ_H
4
5 #include <linux/config.h>
6 #include <asm/smp.h>
7
8 /* entry.S is sensitive to the offsets of these fields */
9 /* The __last_jiffy_stamp field is needed to ensure that no decrementer
10 * interrupt is lost on SMP machines. Since on most CPUs it is in the same
11 * cache line as local_irq_count, it is cheap to access and is also used on UP
12 * for uniformity.
13 */
14 typedef struct {
15 unsigned int __softirq_active;
16 unsigned int __softirq_mask;
17 unsigned int __local_irq_count;
18 unsigned int __local_bh_count;
19 unsigned int __syscall_count;
20 unsigned int __last_jiffy_stamp;
21 } ____cacheline_aligned irq_cpustat_t;
22
23 #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
24
25 #define last_jiffy_stamp(cpu) __IRQ_STAT((cpu), __last_jiffy_stamp)
26 /*
27 * Are we in an interrupt context? Either doing bottom half
28 * or hardware interrupt processing?
29 */
30 #define in_interrupt() ({ int __cpu = smp_processor_id(); \
31 (local_irq_count(__cpu) + local_bh_count(__cpu) != 0); })
32
33 #define in_irq() (local_irq_count(smp_processor_id()) != 0)
34
35 #ifndef CONFIG_SMP
36
37 #define hardirq_trylock(cpu) (local_irq_count(cpu) == 0)
38 #define hardirq_endlock(cpu) do { } while (0)
39
40 #define hardirq_enter(cpu) (local_irq_count(cpu)++)
41 #define hardirq_exit(cpu) (local_irq_count(cpu)--)
42
43 #define synchronize_irq() do { } while (0)
44
45 #else /* CONFIG_SMP */
46
47 #include <asm/atomic.h>
48
49 extern unsigned char global_irq_holder;
50 extern unsigned volatile int global_irq_lock;
51 extern atomic_t global_irq_count;
52
53 static inline void release_irqlock(int cpu)
54 {
55 /* if we didn't own the irq lock, just ignore.. */
56 if (global_irq_holder == (unsigned char) cpu) {
57 global_irq_holder = NO_PROC_ID;
58 clear_bit(0,&global_irq_lock);
59 }
60 }
61
62 static inline void hardirq_enter(int cpu)
63 {
64 unsigned int loops = 10000000;
65
66 ++local_irq_count(cpu);
67 atomic_inc(&global_irq_count);
68 while (test_bit(0,&global_irq_lock)) {
69 if (smp_processor_id() == global_irq_holder) {
70 printk("uh oh, interrupt while we hold global irq lock!\n");
71 #ifdef CONFIG_XMON
72 xmon(0);
73 #endif
74 break;
75 }
76 if (loops-- == 0) {
77 printk("do_IRQ waiting for irq lock (holder=%d)\n", global_irq_holder);
78 #ifdef CONFIG_XMON
79 xmon(0);
80 #endif
81 }
82 }
83 }
84
85 static inline void hardirq_exit(int cpu)
86 {
87 atomic_dec(&global_irq_count);
88 --local_irq_count(cpu);
89 }
90
91 static inline int hardirq_trylock(int cpu)
92 {
93 return !atomic_read(&global_irq_count) && !test_bit(0,&global_irq_lock);
94 }
95
96 #define hardirq_endlock(cpu) do { } while (0)
97
98 extern void synchronize_irq(void);
99
100 #endif /* CONFIG_SMP */
101
102 #endif /* __ASM_HARDIRQ_H */
103 #endif /* __KERNEL__ */
104
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.