aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/00-INDEX2
-rw-r--r--Documentation/cli-sti-removal.txt133
-rw-r--r--include/linux/interrupt.h29
3 files changed, 0 insertions, 164 deletions
diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX
index 6de71308a906..5b5aba404aac 100644
--- a/Documentation/00-INDEX
+++ b/Documentation/00-INDEX
@@ -89,8 +89,6 @@ cciss.txt
89 - info, major/minor #'s for Compaq's SMART Array Controllers. 89 - info, major/minor #'s for Compaq's SMART Array Controllers.
90cdrom/ 90cdrom/
91 - directory with information on the CD-ROM drivers that Linux has. 91 - directory with information on the CD-ROM drivers that Linux has.
92cli-sti-removal.txt
93 - cli()/sti() removal guide.
94computone.txt 92computone.txt
95 - info on Computone Intelliport II/Plus Multiport Serial Driver. 93 - info on Computone Intelliport II/Plus Multiport Serial Driver.
96connector/ 94connector/
diff --git a/Documentation/cli-sti-removal.txt b/Documentation/cli-sti-removal.txt
deleted file mode 100644
index 60932b02fcb3..000000000000
--- a/Documentation/cli-sti-removal.txt
+++ /dev/null
@@ -1,133 +0,0 @@
1
2#### cli()/sti() removal guide, started by Ingo Molnar <mingo@redhat.com>
3
4
5as of 2.5.28, five popular macros have been removed on SMP, and
6are being phased out on UP:
7
8 cli(), sti(), save_flags(flags), save_flags_cli(flags), restore_flags(flags)
9
10until now it was possible to protect driver code against interrupt
11handlers via a cli(), but from now on other, more lightweight methods
12have to be used for synchronization, such as spinlocks or semaphores.
13
14for example, driver code that used to do something like:
15
16 struct driver_data;
17
18 irq_handler (...)
19 {
20 ....
21 driver_data.finish = 1;
22 driver_data.new_work = 0;
23 ....
24 }
25
26 ...
27
28 ioctl_func (...)
29 {
30 ...
31 cli();
32 ...
33 driver_data.finish = 0;
34 driver_data.new_work = 2;
35 ...
36 sti();
37 ...
38 }
39
40was SMP-correct because the cli() function ensured that no
41interrupt handler (amongst them the above irq_handler()) function
42would execute while the cli()-ed section is executing.
43
44but from now on a more direct method of locking has to be used:
45
46 DEFINE_SPINLOCK(driver_lock);
47 struct driver_data;
48
49 irq_handler (...)
50 {
51 unsigned long flags;
52 ....
53 spin_lock_irqsave(&driver_lock, flags);
54 ....
55 driver_data.finish = 1;
56 driver_data.new_work = 0;
57 ....
58 spin_unlock_irqrestore(&driver_lock, flags);
59 ....
60 }
61
62 ...
63
64 ioctl_func (...)
65 {
66 ...
67 spin_lock_irq(&driver_lock);
68 ...
69 driver_data.finish = 0;
70 driver_data.new_work = 2;
71 ...
72 spin_unlock_irq(&driver_lock);
73 ...
74 }
75
76the above code has a number of advantages:
77
78- the locking relation is easier to understand - actual lock usage
79 pinpoints the critical sections. cli() usage is too opaque.
80 Easier to understand means it's easier to debug.
81
82- it's faster, because spinlocks are faster to acquire than the
83 potentially heavily-used IRQ lock. Furthermore, your driver does
84 not have to wait eg. for a big heavy SCSI interrupt to finish,
85 because the driver_lock spinlock is only used by your driver.
86 cli() on the other hand was used by many drivers, and extended
87 the critical section to the whole IRQ handler function - creating
88 serious lock contention.
89
90
91to make the transition easier, we've still kept the cli(), sti(),
92save_flags(), save_flags_cli() and restore_flags() macros defined
93on UP systems - but their usage will be phased out until 2.6 is
94released.
95
96drivers that want to disable local interrupts (interrupts on the
97current CPU), can use the following five macros:
98
99 local_irq_disable(), local_irq_enable(), local_save_flags(flags),
100 local_irq_save(flags), local_irq_restore(flags)
101
102but beware, their meaning and semantics are much simpler, far from
103that of the old cli(), sti(), save_flags(flags) and restore_flags(flags)
104SMP meaning:
105
106 local_irq_disable() => turn local IRQs off
107
108 local_irq_enable() => turn local IRQs on
109
110 local_save_flags(flags) => save the current IRQ state into flags. The
111 state can be on or off. (on some
112 architectures there's even more bits in it.)
113
114 local_irq_save(flags) => save the current IRQ state into flags and
115 disable interrupts.
116
117 local_irq_restore(flags) => restore the IRQ state from flags.
118
119(local_irq_save can save both irqs on and irqs off state, and
120local_irq_restore can restore into both irqs on and irqs off state.)
121
122another related change is that synchronize_irq() now takes a parameter:
123synchronize_irq(irq). This change too has the purpose of making SMP
124synchronization more lightweight - this way you can wait for your own
125interrupt handler to finish, no need to wait for other IRQ sources.
126
127
128why were these changes done? The main reason was the architectural burden
129of maintaining the cli()/sti() interface - it became a real problem. The
130new interrupt system is much more streamlined, easier to understand, debug,
131and it's also a bit faster - the same happened to it that will happen to
132cli()/sti() using drivers once they convert to spinlocks :-)
133
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 62aa4f895abe..58ff4e74b2f3 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -223,35 +223,6 @@ static inline int disable_irq_wake(unsigned int irq)
223#define or_softirq_pending(x) (local_softirq_pending() |= (x)) 223#define or_softirq_pending(x) (local_softirq_pending() |= (x))
224#endif 224#endif
225 225
226/*
227 * Temporary defines for UP kernels, until all code gets fixed.
228 */
229#ifndef CONFIG_SMP
230static inline void __deprecated cli(void)
231{
232 local_irq_disable();
233}
234static inline void __deprecated sti(void)
235{
236 local_irq_enable();
237}
238static inline void __deprecated save_flags(unsigned long *x)
239{
240 local_save_flags(*x);
241}
242#define save_flags(x) save_flags(&x)
243static inline void __deprecated restore_flags(unsigned long x)
244{
245 local_irq_restore(x);
246}
247
248static inline void __deprecated save_and_cli(unsigned long *x)
249{
250 local_irq_save(*x);
251}
252#define save_and_cli(x) save_and_cli(&x)
253#endif /* CONFIG_SMP */
254
255/* Some architectures might implement lazy enabling/disabling of 226/* Some architectures might implement lazy enabling/disabling of
256 * interrupts. In some cases, such as stop_machine, we might want 227 * interrupts. In some cases, such as stop_machine, we might want
257 * to ensure that after a local_irq_disable(), interrupts have 228 * to ensure that after a local_irq_disable(), interrupts have