Commit a4ec24b48ddef1e93f7578be53270f0b95ad666c

Authored by Dmitry Adamushko
Committed by Ingo Molnar
1 parent a9957449b0

sched: tidy up SCHED_RR

- make timeslices of SCHED_RR tasks constant and not
dependent on task's static_prio [1] ;
- remove obsolete code (timeslice related bits);
- make sched_rr_get_interval() return something more
meaningful [2] for SCHED_OTHER tasks.

[1] according to the following link, it's not compliant with SUSv3
(not sure though, what is the reference for us :-)
http://lkml.org/lkml/2007/3/7/656

[2] the interval is dynamic and can be depicted as follows "should a
task be one of the runnable tasks at this particular moment, it would
expect to run for this interval of time before being re-scheduled by the
scheduler tick".
(i.e. it's more precise if a task is runnable at the moment)

yeah, this seems to require task_rq_lock/unlock() but this is not a hot
path.

results:

(SCHED_FIFO)

dimm@earth:~/storage/prog$ sudo chrt -f 10 ./rr_interval
time_slice: 0 : 0

(SCHED_RR)

dimm@earth:~/storage/prog$ sudo chrt 10 ./rr_interval
time_slice: 0 : 99984800

(SCHED_NORMAL)

dimm@earth:~/storage/prog$ ./rr_interval
time_slice: 0 : 19996960

(SCHED_NORMAL + a cpu_hog of similar 'weight' on the same CPU --- so should be a half of the previous result)

dimm@earth:~/storage/prog$ taskset 1 ./rr_interval
time_slice: 0 : 9998480

Signed-off-by: Dmitry Adamushko <dmitry.adamushko@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>

Showing 2 changed files with 18 additions and 25 deletions Side-by-side Diff

... ... @@ -96,7 +96,7 @@
96 96 /*
97 97 * Some helpers for converting nanosecond timing to jiffy resolution
98 98 */
99   -#define NS_TO_JIFFIES(TIME) ((TIME) / (1000000000 / HZ))
  99 +#define NS_TO_JIFFIES(TIME) ((unsigned long)(TIME) / (1000000000 / HZ))
100 100 #define JIFFIES_TO_NS(TIME) ((TIME) * (1000000000 / HZ))
101 101  
102 102 #define NICE_0_LOAD SCHED_LOAD_SCALE
103 103  
... ... @@ -105,11 +105,9 @@
105 105 /*
106 106 * These are the 'tuning knobs' of the scheduler:
107 107 *
108   - * Minimum timeslice is 5 msecs (or 1 jiffy, whichever is larger),
109   - * default timeslice is 100 msecs, maximum timeslice is 800 msecs.
  108 + * default timeslice is 100 msecs (used only for SCHED_RR tasks).
110 109 * Timeslices get refilled after they expire.
111 110 */
112   -#define MIN_TIMESLICE max(5 * HZ / 1000, 1)
113 111 #define DEF_TIMESLICE (100 * HZ / 1000)
114 112  
115 113 #ifdef CONFIG_SMP
... ... @@ -133,24 +131,6 @@
133 131 }
134 132 #endif
135 133  
136   -#define SCALE_PRIO(x, prio) \
137   - max(x * (MAX_PRIO - prio) / (MAX_USER_PRIO / 2), MIN_TIMESLICE)
138   -
139   -/*
140   - * static_prio_timeslice() scales user-nice values [ -20 ... 0 ... 19 ]
141   - * to time slice values: [800ms ... 100ms ... 5ms]
142   - */
143   -static unsigned int static_prio_timeslice(int static_prio)
144   -{
145   - if (static_prio == NICE_TO_PRIO(19))
146   - return 1;
147   -
148   - if (static_prio < NICE_TO_PRIO(0))
149   - return SCALE_PRIO(DEF_TIMESLICE * 4, static_prio);
150   - else
151   - return SCALE_PRIO(DEF_TIMESLICE, static_prio);
152   -}
153   -
154 134 static inline int rt_policy(int policy)
155 135 {
156 136 if (unlikely(policy == SCHED_FIFO) || unlikely(policy == SCHED_RR))
... ... @@ -4746,6 +4726,7 @@
4746 4726 long sys_sched_rr_get_interval(pid_t pid, struct timespec __user *interval)
4747 4727 {
4748 4728 struct task_struct *p;
  4729 + unsigned int time_slice;
4749 4730 int retval = -EINVAL;
4750 4731 struct timespec t;
4751 4732  
4752 4733  
... ... @@ -4762,9 +4743,21 @@
4762 4743 if (retval)
4763 4744 goto out_unlock;
4764 4745  
4765   - jiffies_to_timespec(p->policy == SCHED_FIFO ?
4766   - 0 : static_prio_timeslice(p->static_prio), &t);
  4746 + if (p->policy == SCHED_FIFO)
  4747 + time_slice = 0;
  4748 + else if (p->policy == SCHED_RR)
  4749 + time_slice = DEF_TIMESLICE;
  4750 + else {
  4751 + struct sched_entity *se = &p->se;
  4752 + unsigned long flags;
  4753 + struct rq *rq;
  4754 +
  4755 + rq = task_rq_lock(p, &flags);
  4756 + time_slice = NS_TO_JIFFIES(sched_slice(cfs_rq_of(se), se));
  4757 + task_rq_unlock(rq, &flags);
  4758 + }
4767 4759 read_unlock(&tasklist_lock);
  4760 + jiffies_to_timespec(time_slice, &t);
4768 4761 retval = copy_to_user(interval, &t, sizeof(t)) ? -EFAULT : 0;
4769 4762 out_nounlock:
4770 4763 return retval;
... ... @@ -206,7 +206,7 @@
206 206 if (--p->time_slice)
207 207 return;
208 208  
209   - p->time_slice = static_prio_timeslice(p->static_prio);
  209 + p->time_slice = DEF_TIMESLICE;
210 210  
211 211 /*
212 212 * Requeue to the end of queue if we are not the only element