diff options
-rw-r--r-- | include/linux/sched.h | 9 | ||||
-rw-r--r-- | kernel/sched.c | 24 |
2 files changed, 23 insertions, 10 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h index ab84adf5bb9a..c4fd3fcd3feb 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -684,6 +684,13 @@ static inline void prefetch_stack(struct task_struct *t) { } | |||
684 | struct audit_context; /* See audit.c */ | 684 | struct audit_context; /* See audit.c */ |
685 | struct mempolicy; | 685 | struct mempolicy; |
686 | 686 | ||
687 | enum sleep_type { | ||
688 | SLEEP_NORMAL, | ||
689 | SLEEP_NONINTERACTIVE, | ||
690 | SLEEP_INTERACTIVE, | ||
691 | SLEEP_INTERRUPTED, | ||
692 | }; | ||
693 | |||
687 | struct task_struct { | 694 | struct task_struct { |
688 | volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */ | 695 | volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */ |
689 | struct thread_info *thread_info; | 696 | struct thread_info *thread_info; |
@@ -706,7 +713,7 @@ struct task_struct { | |||
706 | unsigned long sleep_avg; | 713 | unsigned long sleep_avg; |
707 | unsigned long long timestamp, last_ran; | 714 | unsigned long long timestamp, last_ran; |
708 | unsigned long long sched_time; /* sched_clock time spent running */ | 715 | unsigned long long sched_time; /* sched_clock time spent running */ |
709 | int activated; | 716 | enum sleep_type sleep_type; |
710 | 717 | ||
711 | unsigned long policy; | 718 | unsigned long policy; |
712 | cpumask_t cpus_allowed; | 719 | cpumask_t cpus_allowed; |
diff --git a/kernel/sched.c b/kernel/sched.c index 6e52e0adff80..f55ce5adac55 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -704,7 +704,7 @@ static int recalc_task_prio(task_t *p, unsigned long long now) | |||
704 | * prevent them suddenly becoming cpu hogs and starving | 704 | * prevent them suddenly becoming cpu hogs and starving |
705 | * other processes. | 705 | * other processes. |
706 | */ | 706 | */ |
707 | if (p->mm && p->activated != -1 && | 707 | if (p->mm && p->sleep_type != SLEEP_NONINTERACTIVE && |
708 | sleep_time > INTERACTIVE_SLEEP(p)) { | 708 | sleep_time > INTERACTIVE_SLEEP(p)) { |
709 | p->sleep_avg = JIFFIES_TO_NS(MAX_SLEEP_AVG - | 709 | p->sleep_avg = JIFFIES_TO_NS(MAX_SLEEP_AVG - |
710 | DEF_TIMESLICE); | 710 | DEF_TIMESLICE); |
@@ -714,7 +714,7 @@ static int recalc_task_prio(task_t *p, unsigned long long now) | |||
714 | * limited in their sleep_avg rise as they | 714 | * limited in their sleep_avg rise as they |
715 | * are likely to be waiting on I/O | 715 | * are likely to be waiting on I/O |
716 | */ | 716 | */ |
717 | if (p->activated == -1 && p->mm) { | 717 | if (p->sleep_type == SLEEP_NONINTERACTIVE && p->mm) { |
718 | if (p->sleep_avg >= INTERACTIVE_SLEEP(p)) | 718 | if (p->sleep_avg >= INTERACTIVE_SLEEP(p)) |
719 | sleep_time = 0; | 719 | sleep_time = 0; |
720 | else if (p->sleep_avg + sleep_time >= | 720 | else if (p->sleep_avg + sleep_time >= |
@@ -769,7 +769,7 @@ static void activate_task(task_t *p, runqueue_t *rq, int local) | |||
769 | * This checks to make sure it's not an uninterruptible task | 769 | * This checks to make sure it's not an uninterruptible task |
770 | * that is now waking up. | 770 | * that is now waking up. |
771 | */ | 771 | */ |
772 | if (!p->activated) { | 772 | if (p->sleep_type == SLEEP_NORMAL) { |
773 | /* | 773 | /* |
774 | * Tasks which were woken up by interrupts (ie. hw events) | 774 | * Tasks which were woken up by interrupts (ie. hw events) |
775 | * are most likely of interactive nature. So we give them | 775 | * are most likely of interactive nature. So we give them |
@@ -778,13 +778,13 @@ static void activate_task(task_t *p, runqueue_t *rq, int local) | |||
778 | * on a CPU, first time around: | 778 | * on a CPU, first time around: |
779 | */ | 779 | */ |
780 | if (in_interrupt()) | 780 | if (in_interrupt()) |
781 | p->activated = 2; | 781 | p->sleep_type = SLEEP_INTERRUPTED; |
782 | else { | 782 | else { |
783 | /* | 783 | /* |
784 | * Normal first-time wakeups get a credit too for | 784 | * Normal first-time wakeups get a credit too for |
785 | * on-runqueue time, but it will be weighted down: | 785 | * on-runqueue time, but it will be weighted down: |
786 | */ | 786 | */ |
787 | p->activated = 1; | 787 | p->sleep_type = SLEEP_INTERACTIVE; |
788 | } | 788 | } |
789 | } | 789 | } |
790 | p->timestamp = now; | 790 | p->timestamp = now; |
@@ -1272,7 +1272,7 @@ out_activate: | |||
1272 | * Tasks on involuntary sleep don't earn | 1272 | * Tasks on involuntary sleep don't earn |
1273 | * sleep_avg beyond just interactive state. | 1273 | * sleep_avg beyond just interactive state. |
1274 | */ | 1274 | */ |
1275 | p->activated = -1; | 1275 | p->sleep_type = SLEEP_NONINTERACTIVE; |
1276 | } | 1276 | } |
1277 | 1277 | ||
1278 | /* | 1278 | /* |
@@ -2875,6 +2875,12 @@ EXPORT_SYMBOL(sub_preempt_count); | |||
2875 | 2875 | ||
2876 | #endif | 2876 | #endif |
2877 | 2877 | ||
2878 | static inline int interactive_sleep(enum sleep_type sleep_type) | ||
2879 | { | ||
2880 | return (sleep_type == SLEEP_INTERACTIVE || | ||
2881 | sleep_type == SLEEP_INTERRUPTED); | ||
2882 | } | ||
2883 | |||
2878 | /* | 2884 | /* |
2879 | * schedule() is the main scheduler function. | 2885 | * schedule() is the main scheduler function. |
2880 | */ | 2886 | */ |
@@ -2998,12 +3004,12 @@ go_idle: | |||
2998 | queue = array->queue + idx; | 3004 | queue = array->queue + idx; |
2999 | next = list_entry(queue->next, task_t, run_list); | 3005 | next = list_entry(queue->next, task_t, run_list); |
3000 | 3006 | ||
3001 | if (!rt_task(next) && next->activated > 0) { | 3007 | if (!rt_task(next) && interactive_sleep(next->sleep_type)) { |
3002 | unsigned long long delta = now - next->timestamp; | 3008 | unsigned long long delta = now - next->timestamp; |
3003 | if (unlikely((long long)(now - next->timestamp) < 0)) | 3009 | if (unlikely((long long)(now - next->timestamp) < 0)) |
3004 | delta = 0; | 3010 | delta = 0; |
3005 | 3011 | ||
3006 | if (next->activated == 1) | 3012 | if (next->sleep_type == SLEEP_INTERACTIVE) |
3007 | delta = delta * (ON_RUNQUEUE_WEIGHT * 128 / 100) / 128; | 3013 | delta = delta * (ON_RUNQUEUE_WEIGHT * 128 / 100) / 128; |
3008 | 3014 | ||
3009 | array = next->array; | 3015 | array = next->array; |
@@ -3016,7 +3022,7 @@ go_idle: | |||
3016 | } else | 3022 | } else |
3017 | requeue_task(next, array); | 3023 | requeue_task(next, array); |
3018 | } | 3024 | } |
3019 | next->activated = 0; | 3025 | next->sleep_type = SLEEP_NORMAL; |
3020 | switch_tasks: | 3026 | switch_tasks: |
3021 | if (next == rq->idle) | 3027 | if (next == rq->idle) |
3022 | schedstat_inc(rq, sched_goidle); | 3028 | schedstat_inc(rq, sched_goidle); |