aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/sched.h
diff options
context:
space:
mode:
authorVenkatesh Pallipadi <venki@google.com>2010-10-04 20:03:16 -0400
committerIngo Molnar <mingo@elte.hu>2010-10-18 14:52:20 -0400
commit75e1056f5c57050415b64cb761a3acc35d91f013 (patch)
treee7cd483e38f9bf9131a3b212301a009890b8de49 /include/linux/sched.h
parent75dd321d79d495a0ee579e6249ebc38ddbb2667f (diff)
sched: Fix softirq time accounting
Peter Zijlstra found a bug in the way softirq time is accounted in VIRT_CPU_ACCOUNTING on this thread: http://lkml.indiana.edu/hypermail//linux/kernel/1009.2/01366.html The problem is, softirq processing uses local_bh_disable internally. There is no way, later in the flow, to differentiate between whether softirq is being processed or is it just that bh has been disabled. So, a hardirq when bh is disabled results in time being wrongly accounted as softirq. Looking at the code a bit more, the problem exists in !VIRT_CPU_ACCOUNTING as well. As account_system_time() in normal tick based accouting also uses softirq_count, which will be set even when not in softirq with bh disabled. Peter also suggested solution of using 2*SOFTIRQ_OFFSET as irq count for local_bh_{disable,enable} and using just SOFTIRQ_OFFSET while softirq processing. The patch below does that and adds API in_serving_softirq() which returns whether we are currently processing softirq or not. Also changes one of the usages of softirq_count in net/sched/cls_cgroup.c to in_serving_softirq. Looks like many usages of in_softirq really want in_serving_softirq. Those changes can be made individually on a case by case basis. Signed-off-by: Venkatesh Pallipadi <venki@google.com> Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> LKML-Reference: <1286237003-12406-2-git-send-email-venki@google.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'include/linux/sched.h')
-rw-r--r--include/linux/sched.h6
1 files changed, 3 insertions, 3 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h
index cdf56693ecbf..8744e50cb083 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -2366,9 +2366,9 @@ extern int __cond_resched_lock(spinlock_t *lock);
2366 2366
2367extern int __cond_resched_softirq(void); 2367extern int __cond_resched_softirq(void);
2368 2368
2369#define cond_resched_softirq() ({ \ 2369#define cond_resched_softirq() ({ \
2370 __might_sleep(__FILE__, __LINE__, SOFTIRQ_OFFSET); \ 2370 __might_sleep(__FILE__, __LINE__, SOFTIRQ_DISABLE_OFFSET); \
2371 __cond_resched_softirq(); \ 2371 __cond_resched_softirq(); \
2372}) 2372})
2373 2373
2374/* 2374/*