diff options
author | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2008-10-17 13:27:03 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-10-20 08:05:03 -0400 |
commit | a4c2f00f5cb848af7a8c816426b413c8e41834df (patch) | |
tree | f99d376ae43fe7e19db0f5f268c6925d8cda2107 | |
parent | ffda12a17a324103e9900fa1035309811eecbfe5 (diff) |
sched: fair scheduler should not resched rt tasks
With use of ftrace Steven noticed that some RT tasks got rescheduled due
to sched_fair interaction.
What happens is that we reprogram the hrtick from enqueue/dequeue_fair_task()
because that can change nr_running, and thus a current tasks ideal runtime.
However, its possible the current task isn't a fair_sched_class task, and thus
doesn't have a hrtick set to change.
Fix this by wrapping those hrtick_start_fair() calls in a hrtick_update()
function, which will check for the right conditions.
Reported-by: Steven Rostedt <srostedt@redhat.com>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Steven Rostedt <srostedt@redhat.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r-- | kernel/sched_fair.c | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 67084936b602..0c4bcac54761 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c | |||
@@ -73,6 +73,8 @@ unsigned int sysctl_sched_wakeup_granularity = 5000000UL; | |||
73 | 73 | ||
74 | const_debug unsigned int sysctl_sched_migration_cost = 500000UL; | 74 | const_debug unsigned int sysctl_sched_migration_cost = 500000UL; |
75 | 75 | ||
76 | static const struct sched_class fair_sched_class; | ||
77 | |||
76 | /************************************************************** | 78 | /************************************************************** |
77 | * CFS operations on generic schedulable entities: | 79 | * CFS operations on generic schedulable entities: |
78 | */ | 80 | */ |
@@ -848,11 +850,31 @@ static void hrtick_start_fair(struct rq *rq, struct task_struct *p) | |||
848 | hrtick_start(rq, delta); | 850 | hrtick_start(rq, delta); |
849 | } | 851 | } |
850 | } | 852 | } |
853 | |||
854 | /* | ||
855 | * called from enqueue/dequeue and updates the hrtick when the | ||
856 | * current task is from our class and nr_running is low enough | ||
857 | * to matter. | ||
858 | */ | ||
859 | static void hrtick_update(struct rq *rq) | ||
860 | { | ||
861 | struct task_struct *curr = rq->curr; | ||
862 | |||
863 | if (curr->sched_class != &fair_sched_class) | ||
864 | return; | ||
865 | |||
866 | if (cfs_rq_of(&curr->se)->nr_running < sched_nr_latency) | ||
867 | hrtick_start_fair(rq, curr); | ||
868 | } | ||
851 | #else /* !CONFIG_SCHED_HRTICK */ | 869 | #else /* !CONFIG_SCHED_HRTICK */ |
852 | static inline void | 870 | static inline void |
853 | hrtick_start_fair(struct rq *rq, struct task_struct *p) | 871 | hrtick_start_fair(struct rq *rq, struct task_struct *p) |
854 | { | 872 | { |
855 | } | 873 | } |
874 | |||
875 | static inline void hrtick_update(struct rq *rq) | ||
876 | { | ||
877 | } | ||
856 | #endif | 878 | #endif |
857 | 879 | ||
858 | /* | 880 | /* |
@@ -873,7 +895,7 @@ static void enqueue_task_fair(struct rq *rq, struct task_struct *p, int wakeup) | |||
873 | wakeup = 1; | 895 | wakeup = 1; |
874 | } | 896 | } |
875 | 897 | ||
876 | hrtick_start_fair(rq, rq->curr); | 898 | hrtick_update(rq); |
877 | } | 899 | } |
878 | 900 | ||
879 | /* | 901 | /* |
@@ -895,7 +917,7 @@ static void dequeue_task_fair(struct rq *rq, struct task_struct *p, int sleep) | |||
895 | sleep = 1; | 917 | sleep = 1; |
896 | } | 918 | } |
897 | 919 | ||
898 | hrtick_start_fair(rq, rq->curr); | 920 | hrtick_update(rq); |
899 | } | 921 | } |
900 | 922 | ||
901 | /* | 923 | /* |
@@ -1001,8 +1023,6 @@ static inline int wake_idle(int cpu, struct task_struct *p) | |||
1001 | 1023 | ||
1002 | #ifdef CONFIG_SMP | 1024 | #ifdef CONFIG_SMP |
1003 | 1025 | ||
1004 | static const struct sched_class fair_sched_class; | ||
1005 | |||
1006 | #ifdef CONFIG_FAIR_GROUP_SCHED | 1026 | #ifdef CONFIG_FAIR_GROUP_SCHED |
1007 | /* | 1027 | /* |
1008 | * effective_load() calculates the load change as seen from the root_task_group | 1028 | * effective_load() calculates the load change as seen from the root_task_group |