diff options
Diffstat (limited to 'kernel/sched_fair.c')
-rw-r--r-- | kernel/sched_fair.c | 73 |
1 files changed, 67 insertions, 6 deletions
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 892616bf2c77..67c67a87146e 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c | |||
@@ -43,6 +43,14 @@ unsigned int sysctl_sched_latency __read_mostly = 20000000ULL; | |||
43 | unsigned int sysctl_sched_min_granularity __read_mostly = 2000000ULL; | 43 | unsigned int sysctl_sched_min_granularity __read_mostly = 2000000ULL; |
44 | 44 | ||
45 | /* | 45 | /* |
46 | * sys_sched_yield() compat mode | ||
47 | * | ||
48 | * This option switches the agressive yield implementation of the | ||
49 | * old scheduler back on. | ||
50 | */ | ||
51 | unsigned int __read_mostly sysctl_sched_compat_yield; | ||
52 | |||
53 | /* | ||
46 | * SCHED_BATCH wake-up granularity. | 54 | * SCHED_BATCH wake-up granularity. |
47 | * (default: 25 msec, units: nanoseconds) | 55 | * (default: 25 msec, units: nanoseconds) |
48 | * | 56 | * |
@@ -631,6 +639,16 @@ static void enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se) | |||
631 | 639 | ||
632 | se->block_start = 0; | 640 | se->block_start = 0; |
633 | se->sum_sleep_runtime += delta; | 641 | se->sum_sleep_runtime += delta; |
642 | |||
643 | /* | ||
644 | * Blocking time is in units of nanosecs, so shift by 20 to | ||
645 | * get a milliseconds-range estimation of the amount of | ||
646 | * time that the task spent sleeping: | ||
647 | */ | ||
648 | if (unlikely(prof_on == SLEEP_PROFILING)) { | ||
649 | profile_hits(SLEEP_PROFILING, (void *)get_wchan(tsk), | ||
650 | delta >> 20); | ||
651 | } | ||
634 | } | 652 | } |
635 | #endif | 653 | #endif |
636 | } | 654 | } |
@@ -897,19 +915,62 @@ static void dequeue_task_fair(struct rq *rq, struct task_struct *p, int sleep) | |||
897 | } | 915 | } |
898 | 916 | ||
899 | /* | 917 | /* |
900 | * sched_yield() support is very simple - we dequeue and enqueue | 918 | * sched_yield() support is very simple - we dequeue and enqueue. |
919 | * | ||
920 | * If compat_yield is turned on then we requeue to the end of the tree. | ||
901 | */ | 921 | */ |
902 | static void yield_task_fair(struct rq *rq, struct task_struct *p) | 922 | static void yield_task_fair(struct rq *rq, struct task_struct *p) |
903 | { | 923 | { |
904 | struct cfs_rq *cfs_rq = task_cfs_rq(p); | 924 | struct cfs_rq *cfs_rq = task_cfs_rq(p); |
925 | struct rb_node **link = &cfs_rq->tasks_timeline.rb_node; | ||
926 | struct sched_entity *rightmost, *se = &p->se; | ||
927 | struct rb_node *parent; | ||
905 | 928 | ||
906 | __update_rq_clock(rq); | ||
907 | /* | 929 | /* |
908 | * Dequeue and enqueue the task to update its | 930 | * Are we the only task in the tree? |
909 | * position within the tree: | 931 | */ |
932 | if (unlikely(cfs_rq->nr_running == 1)) | ||
933 | return; | ||
934 | |||
935 | if (likely(!sysctl_sched_compat_yield)) { | ||
936 | __update_rq_clock(rq); | ||
937 | /* | ||
938 | * Dequeue and enqueue the task to update its | ||
939 | * position within the tree: | ||
940 | */ | ||
941 | dequeue_entity(cfs_rq, &p->se, 0); | ||
942 | enqueue_entity(cfs_rq, &p->se, 0); | ||
943 | |||
944 | return; | ||
945 | } | ||
946 | /* | ||
947 | * Find the rightmost entry in the rbtree: | ||
948 | */ | ||
949 | do { | ||
950 | parent = *link; | ||
951 | link = &parent->rb_right; | ||
952 | } while (*link); | ||
953 | |||
954 | rightmost = rb_entry(parent, struct sched_entity, run_node); | ||
955 | /* | ||
956 | * Already in the rightmost position? | ||
910 | */ | 957 | */ |
911 | dequeue_entity(cfs_rq, &p->se, 0); | 958 | if (unlikely(rightmost == se)) |
912 | enqueue_entity(cfs_rq, &p->se, 0); | 959 | return; |
960 | |||
961 | /* | ||
962 | * Minimally necessary key value to be last in the tree: | ||
963 | */ | ||
964 | se->fair_key = rightmost->fair_key + 1; | ||
965 | |||
966 | if (cfs_rq->rb_leftmost == &se->run_node) | ||
967 | cfs_rq->rb_leftmost = rb_next(&se->run_node); | ||
968 | /* | ||
969 | * Relink the task to the rightmost position: | ||
970 | */ | ||
971 | rb_erase(&se->run_node, &cfs_rq->tasks_timeline); | ||
972 | rb_link_node(&se->run_node, parent, link); | ||
973 | rb_insert_color(&se->run_node, &cfs_rq->tasks_timeline); | ||
913 | } | 974 | } |
914 | 975 | ||
915 | /* | 976 | /* |