diff options
-rw-r--r-- | kernel/softirq.c | 142 | ||||
-rw-r--r-- | litmus/Kconfig | 16 |
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 | ||
217 | static void ____do_softirq(void) | 217 | asmlinkage 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 | 232 | restart: | |
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 | ||
268 | static void ___do_softirq(void) | 236 | local_irq_enable(); |
269 | { | ||
270 | int max_restart = MAX_SOFTIRQ_RESTART; | ||
271 | __u32 pending; | ||
272 | 237 | ||
273 | restart: | 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 | ||
284 | asmlinkage 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 | ||
218 | menu "Interrupt Handling" | 218 | menu "Interrupt Handling" |
219 | 219 | ||
220 | config 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 | |||
236 | choice | 220 | choice |
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 |