aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/softirq.c142
-rw-r--r--litmus/Kconfig16
2 files changed, 52 insertions, 106 deletions
diff --git a/kernel/softirq.c b/kernel/softirq.c
index 48d6bde692a1..7c562558a863 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -214,105 +214,67 @@ EXPORT_SYMBOL(local_bh_enable_ip);
214 */ 214 */
215#define MAX_SOFTIRQ_RESTART 10 215#define MAX_SOFTIRQ_RESTART 10
216 216
217static void ____do_softirq(void) 217asmlinkage void __do_softirq(void)
218{ 218{
219 __u32 pending; 219 struct softirq_action *h;
220 220 __u32 pending;
221 struct softirq_action *h; 221 int max_restart = MAX_SOFTIRQ_RESTART;
222 int cpu; 222 int cpu;
223
224 pending = local_softirq_pending();
225
226 account_system_vtime(current);
227 223
228 __local_bh_disable((unsigned long)__builtin_return_address(0), 224 pending = local_softirq_pending();
229 SOFTIRQ_OFFSET); 225 account_system_vtime(current);
230 lockdep_softirq_enter();
231 226
232 cpu = smp_processor_id(); 227 __local_bh_disable((unsigned long)__builtin_return_address(0),
228 SOFTIRQ_OFFSET);
229 lockdep_softirq_enter();
233 230
234 set_softirq_pending(0); 231 cpu = smp_processor_id();
235 232restart:
236 local_irq_enable(); 233 /* Reset the pending bitmask before enabling irqs */
237 234 set_softirq_pending(0);
238 h = softirq_vec;
239
240 do {
241 if (pending & 1) {
242 unsigned int vec_nr = h - softirq_vec;
243 int prev_count = preempt_count();
244
245 kstat_incr_softirqs_this_cpu(vec_nr);
246
247 trace_softirq_entry(vec_nr);
248 h->action(h);
249 trace_softirq_exit(vec_nr);
250 if (unlikely(prev_count != preempt_count())) {
251 printk(KERN_ERR "huh, entered softirq %u %s %p"
252 "with preempt_count %08x,"
253 " exited with %08x?\n", vec_nr,
254 softirq_to_name[vec_nr], h->action,
255 prev_count, preempt_count());
256 preempt_count() = prev_count;
257 }
258
259 rcu_bh_qs(cpu);
260 }
261 h++;
262 pending >>= 1;
263 } while (pending);
264
265 local_irq_disable();
266}
267 235
268static void ___do_softirq(void) 236 local_irq_enable();
269{
270 int max_restart = MAX_SOFTIRQ_RESTART;
271 __u32 pending;
272 237
273restart: 238 h = softirq_vec;
274 ____do_softirq();
275 239
276 pending = local_softirq_pending(); 240 do {
277 if (pending && --max_restart) 241 if (pending & 1) {
278 goto restart; 242 unsigned int vec_nr = h - softirq_vec;
243 int prev_count = preempt_count();
279 244
280 if (pending) 245 kstat_incr_softirqs_this_cpu(vec_nr);
281 wakeup_softirqd();
282}
283 246
284asmlinkage void __do_softirq(void) 247 trace_softirq_entry(vec_nr);
285{ 248 h->action(h);
286#ifdef LITMUS_THREAD_ALL_SOFTIRQ 249 trace_softirq_exit(vec_nr);
287 /* Skip straight to wakeup_softirqd() if we're using 250 if (unlikely(prev_count != preempt_count())) {
288 LITMUS_THREAD_ALL_SOFTIRQ (unless there's really high prio-stuff waiting.). */ 251 printk(KERN_ERR "huh, entered softirq %u %s %p"
289 struct task_struct *tsk = __get_cpu_var(ksoftirqd); 252 "with preempt_count %08x,"
290 253 " exited with %08x?\n", vec_nr,
291 if(tsk) 254 softirq_to_name[vec_nr], h->action,
292 { 255 prev_count, preempt_count());
293 __u32 pending = local_softirq_pending(); 256 preempt_count() = prev_count;
294 const __u32 high_prio_softirq = (1<<HI_SOFTIRQ) | (1<<TIMER_SOFTIRQ) | (1<<HRTIMER_SOFTIRQ); 257 }
295 if(pending && !(pending & high_prio_softirq)) 258
296 { 259 rcu_bh_qs(cpu);
297 wakeup_softirqd(); 260 }
298 return; 261 h++;
299 } 262 pending >>= 1;
300 } 263 } while (pending);
301#endif 264
302 265 local_irq_disable();
303 /* 266
304 * 'immediate' softirq execution: 267 pending = local_softirq_pending();
305 */ 268 if (pending && --max_restart)
306 __local_bh_disable((unsigned long)__builtin_return_address(0), 269 goto restart;
307 SOFTIRQ_OFFSET); 270
308 lockdep_softirq_enter(); 271 if (pending)
309 272 wakeup_softirqd();
310 ___do_softirq(); 273
311 274 lockdep_softirq_exit();
312 lockdep_softirq_exit(); 275
313 276 account_system_vtime(current);
314 account_system_vtime(current); 277 __local_bh_enable(SOFTIRQ_OFFSET);
315 __local_bh_enable(SOFTIRQ_OFFSET);
316} 278}
317 279
318#ifndef __ARCH_HAS_DO_SOFTIRQ 280#ifndef __ARCH_HAS_DO_SOFTIRQ
diff --git a/litmus/Kconfig b/litmus/Kconfig
index 158261e0ed08..478e82570bac 100644
--- a/litmus/Kconfig
+++ b/litmus/Kconfig
@@ -217,22 +217,6 @@ endmenu
217 217
218menu "Interrupt Handling" 218menu "Interrupt Handling"
219 219
220config LITMUS_THREAD_ALL_SOFTIRQ
221 bool "Process all softirqs in ksoftirqd threads."
222 default n
223 help
224 (Experimental) Thread all softirqs to ksoftirqd
225 daemon threads, similar to PREEMPT_RT. I/O
226 throughput will will drop with this enabled, but
227 latencies due to interrupts will be reduced.
228
229 WARNING: Timer responsiveness will likely be
230 decreased as timer callbacks are also threaded.
231 This is unlike PREEEMPT_RTs hardirqs.
232
233 If unsure, say No.
234
235
236choice 220choice
237 prompt "Scheduling of interrupt bottom-halves in Litmus." 221 prompt "Scheduling of interrupt bottom-halves in Litmus."
238 default LITMUS_SOFTIRQD_NONE 222 default LITMUS_SOFTIRQD_NONE