diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-09-10 17:36:49 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-09-10 17:36:49 -0400 |
commit | 53f7b9bccd332bba39be78f9085ac1a26fa387fc (patch) | |
tree | 841d4de4cdb5ce5ccf4b197c0cda570fc17a49df | |
parent | 3c038f97e4b14c322b49f13578e0714e1a2ece53 (diff) | |
parent | 1169783085adb9ac969d21103a6885e8435f7ed3 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/mingo/linux-2.6-sched
* git://git.kernel.org/pub/scm/linux/kernel/git/mingo/linux-2.6-sched:
sched: fix ideal_runtime calculations for reniced tasks
sched: improve prev_sum_exec_runtime setting
sched: simplify __check_preempt_curr_fair()
sched: fix xtensa build warning
sched: debug: fix sum_exec_runtime clearing
sched: debug: fix cfs_rq->wait_runtime accounting
sched: fix niced_granularity() shift
sched: fix MC/HT scheduler optimization, without breaking the FUZZ logic.
-rw-r--r-- | kernel/sched.c | 15 | ||||
-rw-r--r-- | kernel/sched_debug.c | 1 | ||||
-rw-r--r-- | kernel/sched_fair.c | 59 |
3 files changed, 38 insertions, 37 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index b533d6db78aa..deeb1f8e0c30 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -668,7 +668,7 @@ static u64 div64_likely32(u64 divident, unsigned long divisor) | |||
668 | /* | 668 | /* |
669 | * Shift right and round: | 669 | * Shift right and round: |
670 | */ | 670 | */ |
671 | #define RSR(x, y) (((x) + (1UL << ((y) - 1))) >> (y)) | 671 | #define SRR(x, y) (((x) + (1UL << ((y) - 1))) >> (y)) |
672 | 672 | ||
673 | static unsigned long | 673 | static unsigned long |
674 | calc_delta_mine(unsigned long delta_exec, unsigned long weight, | 674 | calc_delta_mine(unsigned long delta_exec, unsigned long weight, |
@@ -684,10 +684,10 @@ calc_delta_mine(unsigned long delta_exec, unsigned long weight, | |||
684 | * Check whether we'd overflow the 64-bit multiplication: | 684 | * Check whether we'd overflow the 64-bit multiplication: |
685 | */ | 685 | */ |
686 | if (unlikely(tmp > WMULT_CONST)) | 686 | if (unlikely(tmp > WMULT_CONST)) |
687 | tmp = RSR(RSR(tmp, WMULT_SHIFT/2) * lw->inv_weight, | 687 | tmp = SRR(SRR(tmp, WMULT_SHIFT/2) * lw->inv_weight, |
688 | WMULT_SHIFT/2); | 688 | WMULT_SHIFT/2); |
689 | else | 689 | else |
690 | tmp = RSR(tmp * lw->inv_weight, WMULT_SHIFT); | 690 | tmp = SRR(tmp * lw->inv_weight, WMULT_SHIFT); |
691 | 691 | ||
692 | return (unsigned long)min(tmp, (u64)(unsigned long)LONG_MAX); | 692 | return (unsigned long)min(tmp, (u64)(unsigned long)LONG_MAX); |
693 | } | 693 | } |
@@ -858,7 +858,6 @@ static void dec_nr_running(struct task_struct *p, struct rq *rq) | |||
858 | 858 | ||
859 | static void set_load_weight(struct task_struct *p) | 859 | static void set_load_weight(struct task_struct *p) |
860 | { | 860 | { |
861 | task_rq(p)->cfs.wait_runtime -= p->se.wait_runtime; | ||
862 | p->se.wait_runtime = 0; | 861 | p->se.wait_runtime = 0; |
863 | 862 | ||
864 | if (task_has_rt_policy(p)) { | 863 | if (task_has_rt_policy(p)) { |
@@ -2512,7 +2511,7 @@ group_next: | |||
2512 | * a think about bumping its value to force at least one task to be | 2511 | * a think about bumping its value to force at least one task to be |
2513 | * moved | 2512 | * moved |
2514 | */ | 2513 | */ |
2515 | if (*imbalance + SCHED_LOAD_SCALE_FUZZ < busiest_load_per_task) { | 2514 | if (*imbalance < busiest_load_per_task) { |
2516 | unsigned long tmp, pwr_now, pwr_move; | 2515 | unsigned long tmp, pwr_now, pwr_move; |
2517 | unsigned int imbn; | 2516 | unsigned int imbn; |
2518 | 2517 | ||
@@ -2564,10 +2563,8 @@ small_imbalance: | |||
2564 | pwr_move /= SCHED_LOAD_SCALE; | 2563 | pwr_move /= SCHED_LOAD_SCALE; |
2565 | 2564 | ||
2566 | /* Move if we gain throughput */ | 2565 | /* Move if we gain throughput */ |
2567 | if (pwr_move <= pwr_now) | 2566 | if (pwr_move > pwr_now) |
2568 | goto out_balanced; | 2567 | *imbalance = busiest_load_per_task; |
2569 | |||
2570 | *imbalance = busiest_load_per_task; | ||
2571 | } | 2568 | } |
2572 | 2569 | ||
2573 | return busiest; | 2570 | return busiest; |
diff --git a/kernel/sched_debug.c b/kernel/sched_debug.c index ab18f45f2ab2..c3ee38bd3426 100644 --- a/kernel/sched_debug.c +++ b/kernel/sched_debug.c | |||
@@ -283,4 +283,5 @@ void proc_sched_set_task(struct task_struct *p) | |||
283 | p->se.wait_runtime_overruns = p->se.wait_runtime_underruns = 0; | 283 | p->se.wait_runtime_overruns = p->se.wait_runtime_underruns = 0; |
284 | #endif | 284 | #endif |
285 | p->se.sum_exec_runtime = 0; | 285 | p->se.sum_exec_runtime = 0; |
286 | p->se.prev_sum_exec_runtime = 0; | ||
286 | } | 287 | } |
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index ce39282d9c0d..892616bf2c77 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c | |||
@@ -194,6 +194,8 @@ __enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se) | |||
194 | update_load_add(&cfs_rq->load, se->load.weight); | 194 | update_load_add(&cfs_rq->load, se->load.weight); |
195 | cfs_rq->nr_running++; | 195 | cfs_rq->nr_running++; |
196 | se->on_rq = 1; | 196 | se->on_rq = 1; |
197 | |||
198 | schedstat_add(cfs_rq, wait_runtime, se->wait_runtime); | ||
197 | } | 199 | } |
198 | 200 | ||
199 | static inline void | 201 | static inline void |
@@ -205,6 +207,8 @@ __dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se) | |||
205 | update_load_sub(&cfs_rq->load, se->load.weight); | 207 | update_load_sub(&cfs_rq->load, se->load.weight); |
206 | cfs_rq->nr_running--; | 208 | cfs_rq->nr_running--; |
207 | se->on_rq = 0; | 209 | se->on_rq = 0; |
210 | |||
211 | schedstat_add(cfs_rq, wait_runtime, -se->wait_runtime); | ||
208 | } | 212 | } |
209 | 213 | ||
210 | static inline struct rb_node *first_fair(struct cfs_rq *cfs_rq) | 214 | static inline struct rb_node *first_fair(struct cfs_rq *cfs_rq) |
@@ -291,7 +295,7 @@ niced_granularity(struct sched_entity *curr, unsigned long granularity) | |||
291 | /* | 295 | /* |
292 | * It will always fit into 'long': | 296 | * It will always fit into 'long': |
293 | */ | 297 | */ |
294 | return (long) (tmp >> WMULT_SHIFT); | 298 | return (long) (tmp >> (WMULT_SHIFT-NICE_0_SHIFT)); |
295 | } | 299 | } |
296 | 300 | ||
297 | static inline void | 301 | static inline void |
@@ -574,7 +578,6 @@ static void __enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se) | |||
574 | 578 | ||
575 | prev_runtime = se->wait_runtime; | 579 | prev_runtime = se->wait_runtime; |
576 | __add_wait_runtime(cfs_rq, se, delta_fair); | 580 | __add_wait_runtime(cfs_rq, se, delta_fair); |
577 | schedstat_add(cfs_rq, wait_runtime, se->wait_runtime); | ||
578 | delta_fair = se->wait_runtime - prev_runtime; | 581 | delta_fair = se->wait_runtime - prev_runtime; |
579 | 582 | ||
580 | /* | 583 | /* |
@@ -662,7 +665,6 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int sleep) | |||
662 | if (tsk->state & TASK_UNINTERRUPTIBLE) | 665 | if (tsk->state & TASK_UNINTERRUPTIBLE) |
663 | se->block_start = rq_of(cfs_rq)->clock; | 666 | se->block_start = rq_of(cfs_rq)->clock; |
664 | } | 667 | } |
665 | cfs_rq->wait_runtime -= se->wait_runtime; | ||
666 | #endif | 668 | #endif |
667 | } | 669 | } |
668 | __dequeue_entity(cfs_rq, se); | 670 | __dequeue_entity(cfs_rq, se); |
@@ -671,22 +673,39 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int sleep) | |||
671 | /* | 673 | /* |
672 | * Preempt the current task with a newly woken task if needed: | 674 | * Preempt the current task with a newly woken task if needed: |
673 | */ | 675 | */ |
674 | static int | 676 | static void |
675 | __check_preempt_curr_fair(struct cfs_rq *cfs_rq, struct sched_entity *se, | 677 | __check_preempt_curr_fair(struct cfs_rq *cfs_rq, struct sched_entity *se, |
676 | struct sched_entity *curr, unsigned long granularity) | 678 | struct sched_entity *curr, unsigned long granularity) |
677 | { | 679 | { |
678 | s64 __delta = curr->fair_key - se->fair_key; | 680 | s64 __delta = curr->fair_key - se->fair_key; |
681 | unsigned long ideal_runtime, delta_exec; | ||
682 | |||
683 | /* | ||
684 | * ideal_runtime is compared against sum_exec_runtime, which is | ||
685 | * walltime, hence do not scale. | ||
686 | */ | ||
687 | ideal_runtime = max(sysctl_sched_latency / cfs_rq->nr_running, | ||
688 | (unsigned long)sysctl_sched_min_granularity); | ||
689 | |||
690 | /* | ||
691 | * If we executed more than what the latency constraint suggests, | ||
692 | * reduce the rescheduling granularity. This way the total latency | ||
693 | * of how much a task is not scheduled converges to | ||
694 | * sysctl_sched_latency: | ||
695 | */ | ||
696 | delta_exec = curr->sum_exec_runtime - curr->prev_sum_exec_runtime; | ||
697 | if (delta_exec > ideal_runtime) | ||
698 | granularity = 0; | ||
679 | 699 | ||
680 | /* | 700 | /* |
681 | * Take scheduling granularity into account - do not | 701 | * Take scheduling granularity into account - do not |
682 | * preempt the current task unless the best task has | 702 | * preempt the current task unless the best task has |
683 | * a larger than sched_granularity fairness advantage: | 703 | * a larger than sched_granularity fairness advantage: |
704 | * | ||
705 | * scale granularity as key space is in fair_clock. | ||
684 | */ | 706 | */ |
685 | if (__delta > niced_granularity(curr, granularity)) { | 707 | if (__delta > niced_granularity(curr, granularity)) |
686 | resched_task(rq_of(cfs_rq)->curr); | 708 | resched_task(rq_of(cfs_rq)->curr); |
687 | return 1; | ||
688 | } | ||
689 | return 0; | ||
690 | } | 709 | } |
691 | 710 | ||
692 | static inline void | 711 | static inline void |
@@ -702,6 +721,7 @@ set_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *se) | |||
702 | update_stats_wait_end(cfs_rq, se); | 721 | update_stats_wait_end(cfs_rq, se); |
703 | update_stats_curr_start(cfs_rq, se); | 722 | update_stats_curr_start(cfs_rq, se); |
704 | set_cfs_rq_curr(cfs_rq, se); | 723 | set_cfs_rq_curr(cfs_rq, se); |
724 | se->prev_sum_exec_runtime = se->sum_exec_runtime; | ||
705 | } | 725 | } |
706 | 726 | ||
707 | static struct sched_entity *pick_next_entity(struct cfs_rq *cfs_rq) | 727 | static struct sched_entity *pick_next_entity(struct cfs_rq *cfs_rq) |
@@ -731,7 +751,6 @@ static void put_prev_entity(struct cfs_rq *cfs_rq, struct sched_entity *prev) | |||
731 | 751 | ||
732 | static void entity_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr) | 752 | static void entity_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr) |
733 | { | 753 | { |
734 | unsigned long gran, ideal_runtime, delta_exec; | ||
735 | struct sched_entity *next; | 754 | struct sched_entity *next; |
736 | 755 | ||
737 | /* | 756 | /* |
@@ -748,22 +767,8 @@ static void entity_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr) | |||
748 | if (next == curr) | 767 | if (next == curr) |
749 | return; | 768 | return; |
750 | 769 | ||
751 | gran = sched_granularity(cfs_rq); | 770 | __check_preempt_curr_fair(cfs_rq, next, curr, |
752 | ideal_runtime = niced_granularity(curr, | 771 | sched_granularity(cfs_rq)); |
753 | max(sysctl_sched_latency / cfs_rq->nr_running, | ||
754 | (unsigned long)sysctl_sched_min_granularity)); | ||
755 | /* | ||
756 | * If we executed more than what the latency constraint suggests, | ||
757 | * reduce the rescheduling granularity. This way the total latency | ||
758 | * of how much a task is not scheduled converges to | ||
759 | * sysctl_sched_latency: | ||
760 | */ | ||
761 | delta_exec = curr->sum_exec_runtime - curr->prev_sum_exec_runtime; | ||
762 | if (delta_exec > ideal_runtime) | ||
763 | gran = 0; | ||
764 | |||
765 | if (__check_preempt_curr_fair(cfs_rq, next, curr, gran)) | ||
766 | curr->prev_sum_exec_runtime = curr->sum_exec_runtime; | ||
767 | } | 772 | } |
768 | 773 | ||
769 | /************************************************** | 774 | /************************************************** |
@@ -1121,10 +1126,8 @@ static void task_new_fair(struct rq *rq, struct task_struct *p) | |||
1121 | * The statistical average of wait_runtime is about | 1126 | * The statistical average of wait_runtime is about |
1122 | * -granularity/2, so initialize the task with that: | 1127 | * -granularity/2, so initialize the task with that: |
1123 | */ | 1128 | */ |
1124 | if (sysctl_sched_features & SCHED_FEAT_START_DEBIT) { | 1129 | if (sysctl_sched_features & SCHED_FEAT_START_DEBIT) |
1125 | se->wait_runtime = -(sched_granularity(cfs_rq) / 2); | 1130 | se->wait_runtime = -(sched_granularity(cfs_rq) / 2); |
1126 | schedstat_add(cfs_rq, wait_runtime, se->wait_runtime); | ||
1127 | } | ||
1128 | 1131 | ||
1129 | __enqueue_entity(cfs_rq, se); | 1132 | __enqueue_entity(cfs_rq, se); |
1130 | } | 1133 | } |