Blame view

kernel/softirq.c 18.5 KB
767a67b0b   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-only
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
4
5
6
  /*
   *	linux/kernel/softirq.c
   *
   *	Copyright (C) 1992 Linus Torvalds
   *
b10db7f0d   Pavel Machek   time: more timer ...
7
   *	Rewritten. Old one was good in 2.2, but in 2.3 it was immoral. --ANK (990903)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
8
   */
403227641   Joe Perches   softirq: convert ...
9
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
9984de1a5   Paul Gortmaker   kernel: Map most ...
10
  #include <linux/export.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
11
12
13
14
15
16
17
  #include <linux/kernel_stat.h>
  #include <linux/interrupt.h>
  #include <linux/init.h>
  #include <linux/mm.h>
  #include <linux/notifier.h>
  #include <linux/percpu.h>
  #include <linux/cpu.h>
831441862   Rafael J. Wysocki   Freezer: make ker...
18
  #include <linux/freezer.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
19
20
  #include <linux/kthread.h>
  #include <linux/rcupdate.h>
7e49fcce1   Steven Rostedt   trace, lockdep: m...
21
  #include <linux/ftrace.h>
78eef01b0   Andrew Morton   [PATCH] on_each_c...
22
  #include <linux/smp.h>
3e339b5da   Thomas Gleixner   softirq: Use hotp...
23
  #include <linux/smpboot.h>
79bf2bb33   Thomas Gleixner   [PATCH] tick-mana...
24
  #include <linux/tick.h>
d532676cc   Thomas Gleixner   softirq: Add linu...
25
  #include <linux/irq.h>
a0e39ed37   Heiko Carstens   tracing: fix buil...
26
27
  
  #define CREATE_TRACE_POINTS
ad8d75fff   Steven Rostedt   tracing/events: m...
28
  #include <trace/events/irq.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
29

fed91561d   Prasad Sodagudi   ANDROID: softirq:...
30
  EXPORT_TRACEPOINT_SYMBOL_GPL(irq_handler_entry);
b011ee088   Changki Kim   ANDROID: softirq:...
31
  EXPORT_TRACEPOINT_SYMBOL_GPL(irq_handler_exit);
fed91561d   Prasad Sodagudi   ANDROID: softirq:...
32

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
  /*
     - No shared variables, all the data are CPU local.
     - If a softirq needs serialization, let it serialize itself
       by its own spinlocks.
     - Even if softirq is serialized, only local cpu is marked for
       execution. Hence, we get something sort of weak cpu binding.
       Though it is still not clear, will it result in better locality
       or will not.
  
     Examples:
     - NET RX softirq. It is multithreaded and does not require
       any global serialization.
     - NET TX softirq. It kicks software netdevice queues, hence
       it is logically serialized per device, but this serialization
       is invisible to common code.
     - Tasklets: serialized wrt itself.
   */
  
  #ifndef __ARCH_IRQ_STAT
0f6f47bac   Frederic Weisbecker   softirq/core: Tur...
52
53
  DEFINE_PER_CPU_ALIGNED(irq_cpustat_t, irq_stat);
  EXPORT_PER_CPU_SYMBOL(irq_stat);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
54
  #endif
978b0116c   Alexey Dobriyan   softirq: allocate...
55
  static struct softirq_action softirq_vec[NR_SOFTIRQS] __cacheline_aligned_in_smp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
56

4dd53d891   Venkatesh Pallipadi   softirqs: Free up...
57
  DEFINE_PER_CPU(struct task_struct *, ksoftirqd);
5a920a650   Shaleen Agrawal   ANDROID: Sched: E...
58
  EXPORT_PER_CPU_SYMBOL_GPL(ksoftirqd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
59

8d19443b0   John Dias   ANDROID: sched: a...
60
61
62
63
64
65
  /*
   * active_softirqs -- per cpu, a mask of softirqs that are being handled,
   * with the expectation that approximate answers are acceptable and therefore
   * no synchronization.
   */
  DEFINE_PER_CPU(__u32, active_softirqs);
ce85b4f2e   Joe Perches   softirq: use cons...
66
  const char * const softirq_to_name[NR_SOFTIRQS] = {
f660f6066   Sagi Grimberg   softirq: Display ...
67
  	"HI", "TIMER", "NET_TX", "NET_RX", "BLOCK", "IRQ_POLL",
09223371d   Shaohua Li   rcu: Use softirq ...
68
  	"TASKLET", "SCHED", "HRTIMER", "RCU"
5d592b44b   Jason Baron   tracing: tracepoi...
69
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
70
71
72
73
74
75
  /*
   * we cannot loop indefinitely here to avoid userspace starvation,
   * but we also don't want to introduce a worst case 1/HZ latency
   * to the pending events, so lets the scheduler to balance
   * the softirq load for us.
   */
676cb02dc   Thomas Gleixner   softirqs: Make wa...
76
  static void wakeup_softirqd(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
77
78
  {
  	/* Interrupts are disabled: no need to stop preemption */
909ea9646   Christoph Lameter   core: Replace __g...
79
  	struct task_struct *tsk = __this_cpu_read(ksoftirqd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
80
81
82
83
84
85
  
  	if (tsk && tsk->state != TASK_RUNNING)
  		wake_up_process(tsk);
  }
  
  /*
75e1056f5   Venkatesh Pallipadi   sched: Fix softir...
86
87
88
89
90
91
92
93
94
95
   * preempt_count and SOFTIRQ_OFFSET usage:
   * - preempt_count is changed by SOFTIRQ_OFFSET on entering or leaving
   *   softirq processing.
   * - preempt_count is changed by SOFTIRQ_DISABLE_OFFSET (= 2 * SOFTIRQ_OFFSET)
   *   on local_bh_disable or local_bh_enable.
   * This lets us distinguish between whether we are currently processing
   * softirq and whether we just have bh disabled.
   */
  
  /*
de30a2b35   Ingo Molnar   [PATCH] lockdep: ...
96
97
98
   * This one is for softirq.c-internal use,
   * where hardirqs are disabled legitimately:
   */
3c829c367   Tim Chen   [PATCH] Reducing ...
99
  #ifdef CONFIG_TRACE_IRQFLAGS
a21ee6055   Peter Zijlstra   lockdep: Change h...
100
101
102
103
104
  
  DEFINE_PER_CPU(int, hardirqs_enabled);
  DEFINE_PER_CPU(int, hardirq_context);
  EXPORT_PER_CPU_SYMBOL_GPL(hardirqs_enabled);
  EXPORT_PER_CPU_SYMBOL_GPL(hardirq_context);
0bd3a173d   Peter Zijlstra   sched/preempt, lo...
105
  void __local_bh_disable_ip(unsigned long ip, unsigned int cnt)
de30a2b35   Ingo Molnar   [PATCH] lockdep: ...
106
107
108
109
110
111
  {
  	unsigned long flags;
  
  	WARN_ON_ONCE(in_irq());
  
  	raw_local_irq_save(flags);
7e49fcce1   Steven Rostedt   trace, lockdep: m...
112
  	/*
bdb438065   Peter Zijlstra   sched: Extract th...
113
  	 * The preempt tracer hooks into preempt_count_add and will break
7e49fcce1   Steven Rostedt   trace, lockdep: m...
114
115
116
117
118
  	 * lockdep because it calls back into lockdep after SOFTIRQ_OFFSET
  	 * is set and before current->softirq_enabled is cleared.
  	 * We must manually increment preempt_count here and manually
  	 * call the trace_preempt_off later.
  	 */
bdb438065   Peter Zijlstra   sched: Extract th...
119
  	__preempt_count_add(cnt);
de30a2b35   Ingo Molnar   [PATCH] lockdep: ...
120
121
122
  	/*
  	 * Were softirqs turned off above:
  	 */
9ea4c3800   Peter Zijlstra   locking: Optimize...
123
  	if (softirq_count() == (cnt & SOFTIRQ_MASK))
0d38453c8   Peter Zijlstra   lockdep: Rename t...
124
  		lockdep_softirqs_off(ip);
de30a2b35   Ingo Molnar   [PATCH] lockdep: ...
125
  	raw_local_irq_restore(flags);
7e49fcce1   Steven Rostedt   trace, lockdep: m...
126

0f1ba9a2c   Heiko Carstens   softirq/preempt: ...
127
128
  	if (preempt_count() == cnt) {
  #ifdef CONFIG_DEBUG_PREEMPT
f904f5826   Sebastian Andrzej Siewior   sched/debug: Fix ...
129
  		current->preempt_disable_ip = get_lock_parent_ip();
0f1ba9a2c   Heiko Carstens   softirq/preempt: ...
130
  #endif
f904f5826   Sebastian Andrzej Siewior   sched/debug: Fix ...
131
  		trace_preempt_off(CALLER_ADDR0, get_lock_parent_ip());
0f1ba9a2c   Heiko Carstens   softirq/preempt: ...
132
  	}
de30a2b35   Ingo Molnar   [PATCH] lockdep: ...
133
  }
0bd3a173d   Peter Zijlstra   sched/preempt, lo...
134
  EXPORT_SYMBOL(__local_bh_disable_ip);
3c829c367   Tim Chen   [PATCH] Reducing ...
135
  #endif /* CONFIG_TRACE_IRQFLAGS */
de30a2b35   Ingo Molnar   [PATCH] lockdep: ...
136

75e1056f5   Venkatesh Pallipadi   sched: Fix softir...
137
138
  static void __local_bh_enable(unsigned int cnt)
  {
f71b74bca   Frederic Weisbecker   irq/softirqs: Use...
139
  	lockdep_assert_irqs_disabled();
75e1056f5   Venkatesh Pallipadi   sched: Fix softir...
140

1a63dcd87   Joel Fernandes (Google)   softirq: Reorder ...
141
142
  	if (preempt_count() == cnt)
  		trace_preempt_on(CALLER_ADDR0, get_lock_parent_ip());
9ea4c3800   Peter Zijlstra   locking: Optimize...
143
  	if (softirq_count() == (cnt & SOFTIRQ_MASK))
0d38453c8   Peter Zijlstra   lockdep: Rename t...
144
  		lockdep_softirqs_on(_RET_IP_);
1a63dcd87   Joel Fernandes (Google)   softirq: Reorder ...
145
146
  
  	__preempt_count_sub(cnt);
75e1056f5   Venkatesh Pallipadi   sched: Fix softir...
147
  }
de30a2b35   Ingo Molnar   [PATCH] lockdep: ...
148
  /*
c3442697c   Paul E. McKenney   softirq: Eliminat...
149
   * Special-case - softirqs can safely be enabled by __do_softirq(),
de30a2b35   Ingo Molnar   [PATCH] lockdep: ...
150
151
152
153
   * without processing still-pending softirqs:
   */
  void _local_bh_enable(void)
  {
5d60d3e7c   Frederic Weisbecker   irq: Improve a bi...
154
  	WARN_ON_ONCE(in_irq());
75e1056f5   Venkatesh Pallipadi   sched: Fix softir...
155
  	__local_bh_enable(SOFTIRQ_DISABLE_OFFSET);
de30a2b35   Ingo Molnar   [PATCH] lockdep: ...
156
  }
de30a2b35   Ingo Molnar   [PATCH] lockdep: ...
157
  EXPORT_SYMBOL(_local_bh_enable);
0bd3a173d   Peter Zijlstra   sched/preempt, lo...
158
  void __local_bh_enable_ip(unsigned long ip, unsigned int cnt)
de30a2b35   Ingo Molnar   [PATCH] lockdep: ...
159
  {
f71b74bca   Frederic Weisbecker   irq/softirqs: Use...
160
161
  	WARN_ON_ONCE(in_irq());
  	lockdep_assert_irqs_enabled();
3c829c367   Tim Chen   [PATCH] Reducing ...
162
  #ifdef CONFIG_TRACE_IRQFLAGS
0f476b6d9   Johannes Berg   softirq: remove i...
163
  	local_irq_disable();
3c829c367   Tim Chen   [PATCH] Reducing ...
164
  #endif
de30a2b35   Ingo Molnar   [PATCH] lockdep: ...
165
166
167
  	/*
  	 * Are softirqs going to be turned on now:
  	 */
75e1056f5   Venkatesh Pallipadi   sched: Fix softir...
168
  	if (softirq_count() == SOFTIRQ_DISABLE_OFFSET)
0d38453c8   Peter Zijlstra   lockdep: Rename t...
169
  		lockdep_softirqs_on(ip);
de30a2b35   Ingo Molnar   [PATCH] lockdep: ...
170
171
172
  	/*
  	 * Keep preemption disabled until we are done with
  	 * softirq processing:
ce85b4f2e   Joe Perches   softirq: use cons...
173
  	 */
0bd3a173d   Peter Zijlstra   sched/preempt, lo...
174
  	preempt_count_sub(cnt - 1);
de30a2b35   Ingo Molnar   [PATCH] lockdep: ...
175

0bed698a3   Frederic Weisbecker   irq: Justify the ...
176
177
178
179
180
  	if (unlikely(!in_interrupt() && local_softirq_pending())) {
  		/*
  		 * Run softirq if any pending. And do it in its own stack
  		 * as we may be calling this deep in a task call stack already.
  		 */
de30a2b35   Ingo Molnar   [PATCH] lockdep: ...
181
  		do_softirq();
0bed698a3   Frederic Weisbecker   irq: Justify the ...
182
  	}
de30a2b35   Ingo Molnar   [PATCH] lockdep: ...
183

bdb438065   Peter Zijlstra   sched: Extract th...
184
  	preempt_count_dec();
3c829c367   Tim Chen   [PATCH] Reducing ...
185
  #ifdef CONFIG_TRACE_IRQFLAGS
0f476b6d9   Johannes Berg   softirq: remove i...
186
  	local_irq_enable();
3c829c367   Tim Chen   [PATCH] Reducing ...
187
  #endif
de30a2b35   Ingo Molnar   [PATCH] lockdep: ...
188
189
  	preempt_check_resched();
  }
0bd3a173d   Peter Zijlstra   sched/preempt, lo...
190
  EXPORT_SYMBOL(__local_bh_enable_ip);
de30a2b35   Ingo Molnar   [PATCH] lockdep: ...
191
192
  
  /*
34376a50f   Ben Greear   Fix lockup relate...
193
194
195
196
197
198
   * We restart softirq processing for at most MAX_SOFTIRQ_RESTART times,
   * but break the loop if need_resched() is set or after 2 ms.
   * The MAX_SOFTIRQ_TIME provides a nice upper bound in most cases, but in
   * certain cases, such as stop_machine(), jiffies may cease to
   * increment and so we need the MAX_SOFTIRQ_RESTART limit as
   * well to make sure we eventually return from this method.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
199
   *
c10d73671   Eric Dumazet   softirq: reduce l...
200
   * These limits have been established via experimentation.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
201
202
203
204
   * The two things to balance is latency against fairness -
   * we want to handle softirqs as soon as possible, but they
   * should not be able to lock up the box.
   */
c10d73671   Eric Dumazet   softirq: reduce l...
205
  #define MAX_SOFTIRQ_TIME  msecs_to_jiffies(2)
34376a50f   Ben Greear   Fix lockup relate...
206
  #define MAX_SOFTIRQ_RESTART 10
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
207

f1a83e652   Peter Zijlstra   lockdep: Correctl...
208
209
  #ifdef CONFIG_TRACE_IRQFLAGS
  /*
f1a83e652   Peter Zijlstra   lockdep: Correctl...
210
211
212
213
   * When we run softirqs from irq_exit() and thus on the hardirq stack we need
   * to keep the lockdep irq context tracking as tight as possible in order to
   * not miss-qualify lock contexts and miss possible deadlocks.
   */
f1a83e652   Peter Zijlstra   lockdep: Correctl...
214

5c4853b60   Frederic Weisbecker   lockdep: Simplify...
215
  static inline bool lockdep_softirq_start(void)
f1a83e652   Peter Zijlstra   lockdep: Correctl...
216
  {
5c4853b60   Frederic Weisbecker   lockdep: Simplify...
217
  	bool in_hardirq = false;
f1a83e652   Peter Zijlstra   lockdep: Correctl...
218

f9ad4a5f3   Peter Zijlstra   lockdep: Remove l...
219
  	if (lockdep_hardirq_context()) {
5c4853b60   Frederic Weisbecker   lockdep: Simplify...
220
  		in_hardirq = true;
2502ec37a   Thomas Gleixner   lockdep: Rename t...
221
  		lockdep_hardirq_exit();
5c4853b60   Frederic Weisbecker   lockdep: Simplify...
222
  	}
f1a83e652   Peter Zijlstra   lockdep: Correctl...
223
  	lockdep_softirq_enter();
5c4853b60   Frederic Weisbecker   lockdep: Simplify...
224
225
  
  	return in_hardirq;
f1a83e652   Peter Zijlstra   lockdep: Correctl...
226
  }
5c4853b60   Frederic Weisbecker   lockdep: Simplify...
227
  static inline void lockdep_softirq_end(bool in_hardirq)
f1a83e652   Peter Zijlstra   lockdep: Correctl...
228
229
  {
  	lockdep_softirq_exit();
5c4853b60   Frederic Weisbecker   lockdep: Simplify...
230
231
  
  	if (in_hardirq)
2502ec37a   Thomas Gleixner   lockdep: Rename t...
232
  		lockdep_hardirq_enter();
f1a83e652   Peter Zijlstra   lockdep: Correctl...
233
  }
f1a83e652   Peter Zijlstra   lockdep: Correctl...
234
  #else
5c4853b60   Frederic Weisbecker   lockdep: Simplify...
235
236
  static inline bool lockdep_softirq_start(void) { return false; }
  static inline void lockdep_softirq_end(bool in_hardirq) { }
f1a83e652   Peter Zijlstra   lockdep: Correctl...
237
  #endif
0578248be   Pavankumar Kondeti   ANDROID: softirq:...
238
239
240
241
242
243
244
245
246
  #define softirq_deferred_for_rt(pending)		\
  ({							\
  	__u32 deferred = 0;				\
  	if (cpupri_check_rt()) {			\
  		deferred = pending & LONG_SOFTIRQ_MASK; \
  		pending &= ~LONG_SOFTIRQ_MASK;		\
  	}						\
  	deferred;					\
  })
be7635e72   Alexander Potapenko   arch, ftrace: for...
247
  asmlinkage __visible void __softirq_entry __do_softirq(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
248
  {
c10d73671   Eric Dumazet   softirq: reduce l...
249
  	unsigned long end = jiffies + MAX_SOFTIRQ_TIME;
907aed48f   Mel Gorman   mm: allow PF_MEMA...
250
  	unsigned long old_flags = current->flags;
34376a50f   Ben Greear   Fix lockup relate...
251
  	int max_restart = MAX_SOFTIRQ_RESTART;
f1a83e652   Peter Zijlstra   lockdep: Correctl...
252
  	struct softirq_action *h;
5c4853b60   Frederic Weisbecker   lockdep: Simplify...
253
  	bool in_hardirq;
0578248be   Pavankumar Kondeti   ANDROID: softirq:...
254
  	__u32 deferred;
f1a83e652   Peter Zijlstra   lockdep: Correctl...
255
  	__u32 pending;
2e702b9f6   Joe Perches   softirq: use ffs(...
256
  	int softirq_bit;
907aed48f   Mel Gorman   mm: allow PF_MEMA...
257
258
  
  	/*
e45506ac0   Yangtao Li   softirq: Fix typo...
259
260
261
  	 * Mask out PF_MEMALLOC as the current task context is borrowed for the
  	 * softirq. A softirq handled, such as network RX, might set PF_MEMALLOC
  	 * again if the socket is related to swapping.
907aed48f   Mel Gorman   mm: allow PF_MEMA...
262
263
  	 */
  	current->flags &= ~PF_MEMALLOC;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
264
265
  
  	pending = local_softirq_pending();
0578248be   Pavankumar Kondeti   ANDROID: softirq:...
266
  	deferred = softirq_deferred_for_rt(pending);
6a61671bb   Frederic Weisbecker   cputime: Safely r...
267
  	account_irq_enter_time(current);
0bd3a173d   Peter Zijlstra   sched/preempt, lo...
268
  	__local_bh_disable_ip(_RET_IP_, SOFTIRQ_OFFSET);
5c4853b60   Frederic Weisbecker   lockdep: Simplify...
269
  	in_hardirq = lockdep_softirq_start();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
270

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
271
272
  restart:
  	/* Reset the pending bitmask before enabling irqs */
0578248be   Pavankumar Kondeti   ANDROID: softirq:...
273
  	set_softirq_pending(deferred);
8d19443b0   John Dias   ANDROID: sched: a...
274
  	__this_cpu_write(active_softirqs, pending);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
275

c70f5d661   Andrew Morton   [PATCH] revert bo...
276
  	local_irq_enable();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
277
278
  
  	h = softirq_vec;
2e702b9f6   Joe Perches   softirq: use ffs(...
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
  	while ((softirq_bit = ffs(pending))) {
  		unsigned int vec_nr;
  		int prev_count;
  
  		h += softirq_bit - 1;
  
  		vec_nr = h - softirq_vec;
  		prev_count = preempt_count();
  
  		kstat_incr_softirqs_this_cpu(vec_nr);
  
  		trace_softirq_entry(vec_nr);
  		h->action(h);
  		trace_softirq_exit(vec_nr);
  		if (unlikely(prev_count != preempt_count())) {
403227641   Joe Perches   softirq: convert ...
294
295
  			pr_err("huh, entered softirq %u %s %p with preempt_count %08x, exited with %08x?
  ",
2e702b9f6   Joe Perches   softirq: use ffs(...
296
297
298
  			       vec_nr, softirq_to_name[vec_nr], h->action,
  			       prev_count, preempt_count());
  			preempt_count_set(prev_count);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
299
300
  		}
  		h++;
2e702b9f6   Joe Perches   softirq: use ffs(...
301
302
  		pending >>= softirq_bit;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
303

8d19443b0   John Dias   ANDROID: sched: a...
304
  	__this_cpu_write(active_softirqs, 0);
d28139c4e   Paul E. McKenney   rcu: Apply RCU-bh...
305
306
  	if (__this_cpu_read(ksoftirqd) == current)
  		rcu_softirq_qs();
c70f5d661   Andrew Morton   [PATCH] revert bo...
307
  	local_irq_disable();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
308
309
  
  	pending = local_softirq_pending();
0578248be   Pavankumar Kondeti   ANDROID: softirq:...
310
  	deferred = softirq_deferred_for_rt(pending);
c10d73671   Eric Dumazet   softirq: reduce l...
311
  	if (pending) {
34376a50f   Ben Greear   Fix lockup relate...
312
313
  		if (time_before(jiffies, end) && !need_resched() &&
  		    --max_restart)
c10d73671   Eric Dumazet   softirq: reduce l...
314
  			goto restart;
c10d73671   Eric Dumazet   softirq: reduce l...
315
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
316

0578248be   Pavankumar Kondeti   ANDROID: softirq:...
317
318
319
320
  #ifdef CONFIG_RT_SOFTINT_OPTIMIZATION
  	if (pending | deferred)
  		wakeup_softirqd();
  #endif
5c4853b60   Frederic Weisbecker   lockdep: Simplify...
321
  	lockdep_softirq_end(in_hardirq);
6a61671bb   Frederic Weisbecker   cputime: Safely r...
322
  	account_irq_exit_time(current);
75e1056f5   Venkatesh Pallipadi   sched: Fix softir...
323
  	__local_bh_enable(SOFTIRQ_OFFSET);
5d60d3e7c   Frederic Weisbecker   irq: Improve a bi...
324
  	WARN_ON_ONCE(in_interrupt());
717a94b5f   NeilBrown   sched/core: Remov...
325
  	current_restore_flags(old_flags, PF_MEMALLOC);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
326
  }
722a9f929   Andi Kleen   asmlinkage: Add e...
327
  asmlinkage __visible void do_softirq(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
328
329
330
331
332
333
334
335
336
337
  {
  	__u32 pending;
  	unsigned long flags;
  
  	if (in_interrupt())
  		return;
  
  	local_irq_save(flags);
  
  	pending = local_softirq_pending();
1bcefd388   Lingutla Chandrasekhar   ANDROID: Revert "...
338
  	if (pending)
7d65f4a65   Frederic Weisbecker   irq: Consolidate ...
339
  		do_softirq_own_stack();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
340
341
342
  
  	local_irq_restore(flags);
  }
8a6bc4787   Thomas Gleixner   genirq: Provide i...
343
344
  /**
   * irq_enter_rcu - Enter an interrupt context with RCU watching
dde4b2b5f   Ingo Molnar   [PATCH] uninline ...
345
   */
8a6bc4787   Thomas Gleixner   genirq: Provide i...
346
  void irq_enter_rcu(void)
dde4b2b5f   Ingo Molnar   [PATCH] uninline ...
347
  {
0a8a2e78b   Frederic Weisbecker   timer: Fix bad id...
348
  	if (is_idle_task(current) && !in_interrupt()) {
d267f87fb   Venkatesh Pallipadi   sched: Call tick_...
349
350
351
352
353
  		/*
  		 * Prevent raise_softirq from needlessly waking up ksoftirqd
  		 * here, as softirq will be serviced on return from interrupt.
  		 */
  		local_bh_disable();
5acac1be4   Frederic Weisbecker   tick: Rename tick...
354
  		tick_irq_enter();
d267f87fb   Venkatesh Pallipadi   sched: Call tick_...
355
356
  		_local_bh_enable();
  	}
d267f87fb   Venkatesh Pallipadi   sched: Call tick_...
357
  	__irq_enter();
dde4b2b5f   Ingo Molnar   [PATCH] uninline ...
358
  }
8a6bc4787   Thomas Gleixner   genirq: Provide i...
359
360
361
362
363
364
365
366
  /**
   * irq_enter - Enter an interrupt context including RCU update
   */
  void irq_enter(void)
  {
  	rcu_irq_enter();
  	irq_enter_rcu();
  }
8d32a307e   Thomas Gleixner   genirq: Provide f...
367
368
  static inline void invoke_softirq(void)
  {
ded797547   Frederic Weisbecker   irq: Force hardir...
369
  	if (!force_irqthreads) {
cc1f02745   Frederic Weisbecker   irq: Optimize sof...
370
  #ifdef CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK
ded797547   Frederic Weisbecker   irq: Force hardir...
371
372
373
  		/*
  		 * We can safely execute softirq on the current stack if
  		 * it is the irq stack, because it should be near empty
cc1f02745   Frederic Weisbecker   irq: Optimize sof...
374
375
376
377
378
379
380
381
  		 * at this stage.
  		 */
  		__do_softirq();
  #else
  		/*
  		 * Otherwise, irq_exit() is called on the task stack that can
  		 * be potentially deep already. So call softirq in its own stack
  		 * to prevent from any overrun.
ded797547   Frederic Weisbecker   irq: Force hardir...
382
  		 */
be6e10164   Frederic Weisbecker   irq: Optimize cal...
383
  		do_softirq_own_stack();
cc1f02745   Frederic Weisbecker   irq: Optimize sof...
384
  #endif
ded797547   Frederic Weisbecker   irq: Force hardir...
385
  	} else {
8d32a307e   Thomas Gleixner   genirq: Provide f...
386
  		wakeup_softirqd();
ded797547   Frederic Weisbecker   irq: Force hardir...
387
  	}
8d32a307e   Thomas Gleixner   genirq: Provide f...
388
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
389

67826eae8   Frederic Weisbecker   nohz: Disable the...
390
391
392
393
394
395
396
  static inline void tick_irq_exit(void)
  {
  #ifdef CONFIG_NO_HZ_COMMON
  	int cpu = smp_processor_id();
  
  	/* Make sure that timer wheel updates are propagated */
  	if ((idle_cpu(cpu) && !need_resched()) || tick_nohz_full_cpu(cpu)) {
0a0e0829f   Frederic Weisbecker   nohz: Fix missing...
397
  		if (!in_irq())
67826eae8   Frederic Weisbecker   nohz: Disable the...
398
399
400
401
  			tick_nohz_irq_exit();
  	}
  #endif
  }
59bc300b7   Peter Zijlstra   x86/entry: Clarif...
402
  static inline void __irq_exit_rcu(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
403
  {
74eed0163   Thomas Gleixner   irq: Ensure irq_e...
404
  #ifndef __ARCH_IRQ_EXIT_IRQS_DISABLED
4cd5d1115   Frederic Weisbecker   irq: Don't re-ena...
405
  	local_irq_disable();
74eed0163   Thomas Gleixner   irq: Ensure irq_e...
406
  #else
f71b74bca   Frederic Weisbecker   irq/softirqs: Use...
407
  	lockdep_assert_irqs_disabled();
74eed0163   Thomas Gleixner   irq: Ensure irq_e...
408
  #endif
6a61671bb   Frederic Weisbecker   cputime: Safely r...
409
  	account_irq_exit_time(current);
bdb438065   Peter Zijlstra   sched: Extract th...
410
  	preempt_count_sub(HARDIRQ_OFFSET);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
411
412
  	if (!in_interrupt() && local_softirq_pending())
  		invoke_softirq();
79bf2bb33   Thomas Gleixner   [PATCH] tick-mana...
413

67826eae8   Frederic Weisbecker   nohz: Disable the...
414
  	tick_irq_exit();
8a6bc4787   Thomas Gleixner   genirq: Provide i...
415
416
417
  }
  
  /**
59bc300b7   Peter Zijlstra   x86/entry: Clarif...
418
419
420
421
422
423
424
425
426
427
428
429
   * irq_exit_rcu() - Exit an interrupt context without updating RCU
   *
   * Also processes softirqs if needed and possible.
   */
  void irq_exit_rcu(void)
  {
  	__irq_exit_rcu();
  	 /* must be last! */
  	lockdep_hardirq_exit();
  }
  
  /**
8a6bc4787   Thomas Gleixner   genirq: Provide i...
430
431
432
433
434
435
   * irq_exit - Exit an interrupt context, update RCU and lockdep
   *
   * Also processes softirqs if needed and possible.
   */
  void irq_exit(void)
  {
59bc300b7   Peter Zijlstra   x86/entry: Clarif...
436
  	__irq_exit_rcu();
416eb33cd   Frederic Weisbecker   rcu: Fix early ca...
437
  	rcu_irq_exit();
2502ec37a   Thomas Gleixner   lockdep: Rename t...
438
439
  	 /* must be last! */
  	lockdep_hardirq_exit();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
440
441
442
443
444
  }
  
  /*
   * This function must run with irqs disabled!
   */
7ad5b3a50   Harvey Harrison   kernel: remove fa...
445
  inline void raise_softirq_irqoff(unsigned int nr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
  {
  	__raise_softirq_irqoff(nr);
  
  	/*
  	 * If we're in an interrupt or softirq, we're done
  	 * (this also catches softirq-disabled code). We will
  	 * actually run the softirq once we return from
  	 * the irq or softirq.
  	 *
  	 * Otherwise we wake up ksoftirqd to make sure we
  	 * schedule the softirq soon.
  	 */
  	if (!in_interrupt())
  		wakeup_softirqd();
  }
7ad5b3a50   Harvey Harrison   kernel: remove fa...
461
  void raise_softirq(unsigned int nr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
462
463
464
465
466
467
468
  {
  	unsigned long flags;
  
  	local_irq_save(flags);
  	raise_softirq_irqoff(nr);
  	local_irq_restore(flags);
  }
f069686e4   Steven Rostedt   tracing/softirq: ...
469
470
  void __raise_softirq_irqoff(unsigned int nr)
  {
cdabce2e3   Jiafei Pan   softirq: Add debu...
471
  	lockdep_assert_irqs_disabled();
f069686e4   Steven Rostedt   tracing/softirq: ...
472
473
474
  	trace_softirq_raise(nr);
  	or_softirq_pending(1UL << nr);
  }
962cf36c5   Carlos R. Mafra   Remove argument f...
475
  void open_softirq(int nr, void (*action)(struct softirq_action *))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
476
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
477
478
  	softirq_vec[nr].action = action;
  }
9ba5f005c   Peter Zijlstra   softirq: introduc...
479
480
481
  /*
   * Tasklets
   */
ce85b4f2e   Joe Perches   softirq: use cons...
482
  struct tasklet_head {
48f20a9a9   Olof Johansson   tasklets: execute...
483
484
  	struct tasklet_struct *head;
  	struct tasklet_struct **tail;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
485
  };
4620b49f7   Vegard Nossum   softirq: remove i...
486
487
  static DEFINE_PER_CPU(struct tasklet_head, tasklet_vec);
  static DEFINE_PER_CPU(struct tasklet_head, tasklet_hi_vec);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
488

6498ddad3   Ingo Molnar   softirq: Consolid...
489
490
491
  static void __tasklet_schedule_common(struct tasklet_struct *t,
  				      struct tasklet_head __percpu *headp,
  				      unsigned int softirq_nr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
492
  {
6498ddad3   Ingo Molnar   softirq: Consolid...
493
  	struct tasklet_head *head;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
494
495
496
  	unsigned long flags;
  
  	local_irq_save(flags);
6498ddad3   Ingo Molnar   softirq: Consolid...
497
  	head = this_cpu_ptr(headp);
48f20a9a9   Olof Johansson   tasklets: execute...
498
  	t->next = NULL;
6498ddad3   Ingo Molnar   softirq: Consolid...
499
500
501
  	*head->tail = t;
  	head->tail = &(t->next);
  	raise_softirq_irqoff(softirq_nr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
502
503
  	local_irq_restore(flags);
  }
6498ddad3   Ingo Molnar   softirq: Consolid...
504
505
506
507
508
509
  
  void __tasklet_schedule(struct tasklet_struct *t)
  {
  	__tasklet_schedule_common(t, &tasklet_vec,
  				  TASKLET_SOFTIRQ);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
510
  EXPORT_SYMBOL(__tasklet_schedule);
7ad5b3a50   Harvey Harrison   kernel: remove fa...
511
  void __tasklet_hi_schedule(struct tasklet_struct *t)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
512
  {
6498ddad3   Ingo Molnar   softirq: Consolid...
513
514
  	__tasklet_schedule_common(t, &tasklet_hi_vec,
  				  HI_SOFTIRQ);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
515
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
516
  EXPORT_SYMBOL(__tasklet_hi_schedule);
82b691bed   Ingo Molnar   softirq: Consolid...
517
518
519
  static void tasklet_action_common(struct softirq_action *a,
  				  struct tasklet_head *tl_head,
  				  unsigned int softirq_nr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
520
521
522
523
  {
  	struct tasklet_struct *list;
  
  	local_irq_disable();
82b691bed   Ingo Molnar   softirq: Consolid...
524
525
526
  	list = tl_head->head;
  	tl_head->head = NULL;
  	tl_head->tail = &tl_head->head;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
527
528
529
530
531
532
533
534
535
  	local_irq_enable();
  
  	while (list) {
  		struct tasklet_struct *t = list;
  
  		list = list->next;
  
  		if (tasklet_trylock(t)) {
  			if (!atomic_read(&t->count)) {
ce85b4f2e   Joe Perches   softirq: use cons...
536
537
  				if (!test_and_clear_bit(TASKLET_STATE_SCHED,
  							&t->state))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
538
  					BUG();
9889f08de   Lingutla Chandrasekhar   ANDROID: trace: A...
539
540
  				if (t->use_callback) {
  					trace_tasklet_entry(t->callback);
12cc923f1   Romain Perier   tasklet: Introduc...
541
  					t->callback(t);
9889f08de   Lingutla Chandrasekhar   ANDROID: trace: A...
542
543
544
  					trace_tasklet_exit(t->callback);
  				} else {
  					trace_tasklet_entry(t->func);
12cc923f1   Romain Perier   tasklet: Introduc...
545
  					t->func(t->data);
9889f08de   Lingutla Chandrasekhar   ANDROID: trace: A...
546
547
  					trace_tasklet_exit(t->func);
  				}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
548
549
550
551
552
553
554
  				tasklet_unlock(t);
  				continue;
  			}
  			tasklet_unlock(t);
  		}
  
  		local_irq_disable();
48f20a9a9   Olof Johansson   tasklets: execute...
555
  		t->next = NULL;
82b691bed   Ingo Molnar   softirq: Consolid...
556
557
558
  		*tl_head->tail = t;
  		tl_head->tail = &t->next;
  		__raise_softirq_irqoff(softirq_nr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
559
560
561
  		local_irq_enable();
  	}
  }
82b691bed   Ingo Molnar   softirq: Consolid...
562
  static __latent_entropy void tasklet_action(struct softirq_action *a)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
563
  {
82b691bed   Ingo Molnar   softirq: Consolid...
564
565
  	tasklet_action_common(a, this_cpu_ptr(&tasklet_vec), TASKLET_SOFTIRQ);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
566

82b691bed   Ingo Molnar   softirq: Consolid...
567
568
569
  static __latent_entropy void tasklet_hi_action(struct softirq_action *a)
  {
  	tasklet_action_common(a, this_cpu_ptr(&tasklet_hi_vec), HI_SOFTIRQ);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
570
  }
12cc923f1   Romain Perier   tasklet: Introduc...
571
572
573
574
575
576
577
578
579
580
581
  void tasklet_setup(struct tasklet_struct *t,
  		   void (*callback)(struct tasklet_struct *))
  {
  	t->next = NULL;
  	t->state = 0;
  	atomic_set(&t->count, 0);
  	t->callback = callback;
  	t->use_callback = true;
  	t->data = 0;
  }
  EXPORT_SYMBOL(tasklet_setup);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
582
583
584
585
586
587
588
  void tasklet_init(struct tasklet_struct *t,
  		  void (*func)(unsigned long), unsigned long data)
  {
  	t->next = NULL;
  	t->state = 0;
  	atomic_set(&t->count, 0);
  	t->func = func;
12cc923f1   Romain Perier   tasklet: Introduc...
589
  	t->use_callback = false;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
590
591
  	t->data = data;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
592
593
594
595
596
  EXPORT_SYMBOL(tasklet_init);
  
  void tasklet_kill(struct tasklet_struct *t)
  {
  	if (in_interrupt())
403227641   Joe Perches   softirq: convert ...
597
598
  		pr_notice("Attempt to kill tasklet from interrupt
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
599
600
  
  	while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) {
79d381c9f   H Hartley Sweeten   kernel/softirq.c:...
601
  		do {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
602
  			yield();
79d381c9f   H Hartley Sweeten   kernel/softirq.c:...
603
  		} while (test_bit(TASKLET_STATE_SCHED, &t->state));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
604
605
606
607
  	}
  	tasklet_unlock_wait(t);
  	clear_bit(TASKLET_STATE_SCHED, &t->state);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
608
609
610
611
  EXPORT_SYMBOL(tasklet_kill);
  
  void __init softirq_init(void)
  {
48f20a9a9   Olof Johansson   tasklets: execute...
612
613
614
615
616
617
618
619
  	int cpu;
  
  	for_each_possible_cpu(cpu) {
  		per_cpu(tasklet_vec, cpu).tail =
  			&per_cpu(tasklet_vec, cpu).head;
  		per_cpu(tasklet_hi_vec, cpu).tail =
  			&per_cpu(tasklet_hi_vec, cpu).head;
  	}
962cf36c5   Carlos R. Mafra   Remove argument f...
620
621
  	open_softirq(TASKLET_SOFTIRQ, tasklet_action);
  	open_softirq(HI_SOFTIRQ, tasklet_hi_action);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
622
  }
3e339b5da   Thomas Gleixner   softirq: Use hotp...
623
  static int ksoftirqd_should_run(unsigned int cpu)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
624
  {
3e339b5da   Thomas Gleixner   softirq: Use hotp...
625
626
  	return local_softirq_pending();
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
627

3e339b5da   Thomas Gleixner   softirq: Use hotp...
628
629
630
631
  static void run_ksoftirqd(unsigned int cpu)
  {
  	local_irq_disable();
  	if (local_softirq_pending()) {
0bed698a3   Frederic Weisbecker   irq: Justify the ...
632
633
634
635
  		/*
  		 * We can safely run softirq on inline stack, as we are not deep
  		 * in the task stack here.
  		 */
3e339b5da   Thomas Gleixner   softirq: Use hotp...
636
  		__do_softirq();
3e339b5da   Thomas Gleixner   softirq: Use hotp...
637
  		local_irq_enable();
edf22f4ca   Paul E. McKenney   softirq: Eliminat...
638
  		cond_resched();
3e339b5da   Thomas Gleixner   softirq: Use hotp...
639
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
640
  	}
3e339b5da   Thomas Gleixner   softirq: Use hotp...
641
  	local_irq_enable();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
  }
  
  #ifdef CONFIG_HOTPLUG_CPU
  /*
   * tasklet_kill_immediate is called to remove a tasklet which can already be
   * scheduled for execution on @cpu.
   *
   * Unlike tasklet_kill, this function removes the tasklet
   * _immediately_, even if the tasklet is in TASKLET_STATE_SCHED state.
   *
   * When this function is called, @cpu must be in the CPU_DEAD state.
   */
  void tasklet_kill_immediate(struct tasklet_struct *t, unsigned int cpu)
  {
  	struct tasklet_struct **i;
  
  	BUG_ON(cpu_online(cpu));
  	BUG_ON(test_bit(TASKLET_STATE_RUN, &t->state));
  
  	if (!test_bit(TASKLET_STATE_SCHED, &t->state))
  		return;
  
  	/* CPU is dead, so no lock needed. */
48f20a9a9   Olof Johansson   tasklets: execute...
665
  	for (i = &per_cpu(tasklet_vec, cpu).head; *i; i = &(*i)->next) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
666
667
  		if (*i == t) {
  			*i = t->next;
48f20a9a9   Olof Johansson   tasklets: execute...
668
669
670
  			/* If this was the tail element, move the tail ptr */
  			if (*i == NULL)
  				per_cpu(tasklet_vec, cpu).tail = i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
671
672
673
674
675
  			return;
  		}
  	}
  	BUG();
  }
c4544dbc7   Sebastian Andrzej Siewior   kernel/softirq: C...
676
  static int takeover_tasklets(unsigned int cpu)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
677
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
678
679
680
681
  	/* CPU is dead, so no lock needed. */
  	local_irq_disable();
  
  	/* Find end, append list for that CPU. */
e5e417232   Christian Borntraeger   Fix cpu hotplug p...
682
  	if (&per_cpu(tasklet_vec, cpu).head != per_cpu(tasklet_vec, cpu).tail) {
909ea9646   Christoph Lameter   core: Replace __g...
683
  		*__this_cpu_read(tasklet_vec.tail) = per_cpu(tasklet_vec, cpu).head;
8afecaa68   Muchun Song   softirq: Use __th...
684
  		__this_cpu_write(tasklet_vec.tail, per_cpu(tasklet_vec, cpu).tail);
e5e417232   Christian Borntraeger   Fix cpu hotplug p...
685
686
687
  		per_cpu(tasklet_vec, cpu).head = NULL;
  		per_cpu(tasklet_vec, cpu).tail = &per_cpu(tasklet_vec, cpu).head;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
688
  	raise_softirq_irqoff(TASKLET_SOFTIRQ);
e5e417232   Christian Borntraeger   Fix cpu hotplug p...
689
  	if (&per_cpu(tasklet_hi_vec, cpu).head != per_cpu(tasklet_hi_vec, cpu).tail) {
909ea9646   Christoph Lameter   core: Replace __g...
690
691
  		*__this_cpu_read(tasklet_hi_vec.tail) = per_cpu(tasklet_hi_vec, cpu).head;
  		__this_cpu_write(tasklet_hi_vec.tail, per_cpu(tasklet_hi_vec, cpu).tail);
e5e417232   Christian Borntraeger   Fix cpu hotplug p...
692
693
694
  		per_cpu(tasklet_hi_vec, cpu).head = NULL;
  		per_cpu(tasklet_hi_vec, cpu).tail = &per_cpu(tasklet_hi_vec, cpu).head;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
695
696
697
  	raise_softirq_irqoff(HI_SOFTIRQ);
  
  	local_irq_enable();
c4544dbc7   Sebastian Andrzej Siewior   kernel/softirq: C...
698
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
699
  }
c4544dbc7   Sebastian Andrzej Siewior   kernel/softirq: C...
700
701
  #else
  #define takeover_tasklets	NULL
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
702
  #endif /* CONFIG_HOTPLUG_CPU */
3e339b5da   Thomas Gleixner   softirq: Use hotp...
703
704
705
706
707
708
  static struct smp_hotplug_thread softirq_threads = {
  	.store			= &ksoftirqd,
  	.thread_should_run	= ksoftirqd_should_run,
  	.thread_fn		= run_ksoftirqd,
  	.thread_comm		= "ksoftirqd/%u",
  };
7babe8db9   Eduard - Gabriel Munteanu   Full conversion t...
709
  static __init int spawn_ksoftirqd(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
710
  {
c4544dbc7   Sebastian Andrzej Siewior   kernel/softirq: C...
711
712
  	cpuhp_setup_state_nocalls(CPUHP_SOFTIRQ_DEAD, "softirq:dead", NULL,
  				  takeover_tasklets);
3e339b5da   Thomas Gleixner   softirq: Use hotp...
713
  	BUG_ON(smpboot_register_percpu_thread(&softirq_threads));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
714
715
  	return 0;
  }
7babe8db9   Eduard - Gabriel Munteanu   Full conversion t...
716
  early_initcall(spawn_ksoftirqd);
78eef01b0   Andrew Morton   [PATCH] on_each_c...
717

43a256322   Yinghai Lu   sparseirq: move _...
718
719
720
721
722
723
724
725
726
  /*
   * [ These __weak aliases are kept in a separate compilation unit, so that
   *   GCC does not inline them incorrectly. ]
   */
  
  int __init __weak early_irq_init(void)
  {
  	return 0;
  }
4a046d175   Yinghai Lu   x86: arch_probe_n...
727
728
  int __init __weak arch_probe_nr_irqs(void)
  {
b683de2b3   Thomas Gleixner   genirq: Query arc...
729
  	return NR_IRQS_LEGACY;
4a046d175   Yinghai Lu   x86: arch_probe_n...
730
  }
43a256322   Yinghai Lu   sparseirq: move _...
731
732
733
734
  int __init __weak arch_early_irq_init(void)
  {
  	return 0;
  }
62a08ae2a   Thomas Gleixner   genirq: x86: Ensu...
735
736
737
738
739
  
  unsigned int __weak arch_dynirq_lower_bound(unsigned int from)
  {
  	return from;
  }