Magellan Linux

Annotation of /trunk/kernel26-magellan/patches-2.6.20-r4/0007-2.6.20-sched-idleprio-1.1.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 132 - (hide annotations) (download)
Fri Apr 27 15:24:56 2007 UTC (17 years, 1 month ago) by niro
File size: 7317 byte(s)
files for 2.6.20-r4

1 niro 132 Add the SCHED_IDLEPRIO scheduling policy. Tasks set to this policy are only
2     given cpu time if no other tasks at all wish to have cpu time thus running
3     effectively at idle priority. If semaphores or mutexes are held, or the
4     system is going into suspend, schedule them as SCHED_NORMAL nice 19.
5    
6     Bugfixes by Sergio Cerlesi & Serge Belyshev.
7    
8     Signed-off-by: Con Kolivas <kernel@kolivas.org>
9    
10     include/linux/init_task.h | 6 ++--
11     include/linux/sched.h | 9 ++++--
12     kernel/sched.c | 68 +++++++++++++++++++++++++++++++++++++++++-----
13     3 files changed, 70 insertions(+), 13 deletions(-)
14    
15     Index: linux-2.6.20-ck1/include/linux/init_task.h
16     ===================================================================
17     --- linux-2.6.20-ck1.orig/include/linux/init_task.h 2007-02-16 19:01:31.000000000 +1100
18     +++ linux-2.6.20-ck1/include/linux/init_task.h 2007-02-16 19:01:31.000000000 +1100
19     @@ -99,9 +99,9 @@ extern struct group_info init_groups;
20     .usage = ATOMIC_INIT(2), \
21     .flags = 0, \
22     .lock_depth = -1, \
23     - .prio = MAX_PRIO-20, \
24     - .static_prio = MAX_PRIO-20, \
25     - .normal_prio = MAX_PRIO-20, \
26     + .prio = MAX_PRIO-21, \
27     + .static_prio = MAX_PRIO-21, \
28     + .normal_prio = MAX_PRIO-21, \
29     .policy = SCHED_NORMAL, \
30     .cpus_allowed = CPU_MASK_ALL, \
31     .mm = NULL, \
32     Index: linux-2.6.20-ck1/include/linux/sched.h
33     ===================================================================
34     --- linux-2.6.20-ck1.orig/include/linux/sched.h 2007-02-16 19:01:31.000000000 +1100
35     +++ linux-2.6.20-ck1/include/linux/sched.h 2007-02-16 19:01:31.000000000 +1100
36     @@ -35,10 +35,11 @@
37     #define SCHED_RR 2
38     #define SCHED_BATCH 3
39     #define SCHED_ISO 4
40     +#define SCHED_IDLEPRIO 5
41    
42     #ifdef __KERNEL__
43    
44     -#define SCHED_MAX SCHED_ISO
45     +#define SCHED_MAX SCHED_IDLEPRIO
46     #define SCHED_RANGE(policy) ((policy) <= SCHED_MAX)
47    
48     struct sched_param {
49     @@ -529,8 +530,9 @@ struct signal_struct {
50     #define MAX_RT_PRIO MAX_USER_RT_PRIO
51     #define ISO_PRIO (MAX_RT_PRIO - 1)
52    
53     -#define MAX_PRIO (MAX_RT_PRIO + 40)
54     -#define MIN_USER_PRIO (MAX_PRIO - 1)
55     +#define MAX_PRIO (MAX_RT_PRIO + 41)
56     +#define MIN_USER_PRIO (MAX_PRIO - 2)
57     +#define IDLEPRIO_PRIO (MAX_PRIO - 1)
58    
59     #define rt_prio(prio) unlikely((prio) < ISO_PRIO)
60     #define rt_task(p) rt_prio((p)->prio)
61     @@ -539,6 +541,7 @@ struct signal_struct {
62     (policy) == SCHED_RR)
63     #define has_rt_policy(p) unlikely(is_rt_policy((p)->policy))
64     #define iso_task(p) (unlikely((p)->policy == SCHED_ISO))
65     +#define idleprio_task(p) (unlikely((p)->policy == SCHED_IDLEPRIO))
66    
67     /*
68     * Some day this will be a full-fledged user tracking system..
69     Index: linux-2.6.20-ck1/kernel/sched.c
70     ===================================================================
71     --- linux-2.6.20-ck1.orig/kernel/sched.c 2007-02-16 19:01:31.000000000 +1100
72     +++ linux-2.6.20-ck1/kernel/sched.c 2007-02-16 19:01:31.000000000 +1100
73     @@ -696,6 +696,12 @@ static void set_load_weight(struct task_
74     else
75     #endif
76     p->load_weight = RTPRIO_TO_LOAD_WEIGHT(p->rt_priority);
77     + } else if (idleprio_task(p)) {
78     + /*
79     + * We want idleprio_tasks to have a presence on weighting but
80     + * as small as possible
81     + */
82     + p->load_weight = 1;
83     } else
84     p->load_weight = TASK_LOAD_WEIGHT(p);
85     }
86     @@ -872,6 +878,17 @@ static inline void recalc_task_prio(stru
87     continue_slice(p);
88     }
89    
90     +static inline int idleprio_suitable(struct task_struct *p)
91     +{
92     + return (!p->mutexes_held && !freezing(p) &&
93     + !(p->flags & (PF_NONSLEEP | PF_EXITING)));
94     +}
95     +
96     +static inline int idleprio(const struct task_struct *p)
97     +{
98     + return (p->prio == IDLEPRIO_PRIO);
99     +}
100     +
101     /*
102     * __normal_prio - dynamic priority dependent on bonus.
103     * The priority normally decreases by one each RR_INTERVAL.
104     @@ -895,6 +912,18 @@ static inline int __normal_prio(struct t
105     return ISO_PRIO;
106     }
107    
108     + if (idleprio_task(p)) {
109     + if (unlikely(!idleprio_suitable(p))) {
110     + /*
111     + * If idleprio tasks are holding a semaphore, mutex,
112     + * or being frozen, schedule at a normal priority.
113     + */
114     + p->time_slice = p->slice % RR_INTERVAL ? : RR_INTERVAL;
115     + return MIN_USER_PRIO;
116     + }
117     + return IDLEPRIO_PRIO;
118     + }
119     +
120     full_slice = slice(p);
121     if (full_slice > p->slice)
122     used_slice = full_slice - p->slice;
123     @@ -1544,6 +1573,8 @@ out_activate:
124     out_running:
125     p->state = TASK_RUNNING;
126     out:
127     + if (idleprio_task(p) && freezing(p) && idleprio(p))
128     + requeue_task(p, rq, effective_prio(p));
129     task_rq_unlock(rq, &flags);
130    
131     return success;
132     @@ -2941,7 +2972,7 @@ void account_user_time(struct task_struc
133    
134     /* Add user time to cpustat. */
135     tmp = cputime_to_cputime64(cputime);
136     - if (TASK_NICE(p) > 0)
137     + if (TASK_NICE(p) > 0 || idleprio_task(p))
138     cpustat->nice = cputime64_add(cpustat->nice, tmp);
139     else
140     cpustat->user = cputime64_add(cpustat->user, tmp);
141     @@ -3051,9 +3082,12 @@ static void task_running_tick(struct rq
142     } else
143     p->flags &= ~PF_ISOREF;
144     } else {
145     - /* SCHED_FIFO tasks never run out of timeslice. */
146     - if (unlikely(p->policy == SCHED_FIFO))
147     - goto out_unlock;
148     + if (idleprio_task(p) && !idleprio(p) && idleprio_suitable(p))
149     + set_tsk_need_resched(p);
150     + else
151     + /* SCHED_FIFO tasks never run out of timeslice. */
152     + if (unlikely(p->policy == SCHED_FIFO))
153     + goto out_unlock;
154     }
155    
156     debit = ns_diff(rq->most_recent_timestamp, p->timestamp);
157     @@ -3219,11 +3253,23 @@ dependent_sleeper(int this_cpu, struct r
158     if ((jiffies % DEF_TIMESLICE) >
159     (sd->per_cpu_gain * DEF_TIMESLICE / 100))
160     ret = 1;
161     + else if (idleprio(p))
162     + ret = 1;
163     } else {
164     if (smt_curr->static_prio < p->static_prio &&
165     !TASK_PREEMPTS_CURR(p, smt_rq) &&
166     smt_slice(smt_curr, sd) > slice(p))
167     ret = 1;
168     + else if (idleprio(p) && !idleprio_task(smt_curr) &&
169     + smt_curr->slice * sd->per_cpu_gain >
170     + slice(smt_curr)) {
171     + /*
172     + * With idleprio tasks they run just the last
173     + * per_cpu_gain percent of the smt task's
174     + * slice.
175     + */
176     + ret = 1;
177     + }
178     }
179     unlock:
180     spin_unlock(&smt_rq->lock);
181     @@ -3884,8 +3930,9 @@ void set_user_nice(struct task_struct *p
182     * If the task increased its priority or is running and
183     * lowered its priority, then reschedule its CPU:
184     */
185     - if (delta < 0 || (delta > 0 && task_running(rq, p)))
186     - resched_task(rq->curr);
187     + if (delta < 0 || ((delta > 0 || idleprio_task(p)) &&
188     + task_running(rq, p)))
189     + resched_task(rq->curr);
190     }
191     out_unlock:
192     task_rq_unlock(rq, &flags);
193     @@ -4086,6 +4133,11 @@ recheck:
194     return -EPERM;
195     }
196    
197     + if (!(p->mm) && policy == SCHED_IDLEPRIO) {
198     + /* Don't allow kernel threads to be SCHED_IDLEPRIO. */
199     + return -EINVAL;
200     + }
201     +
202     retval = security_task_setscheduler(p, policy, param);
203     if (retval)
204     return retval;
205     @@ -4407,7 +4459,7 @@ asmlinkage long sys_sched_yield(void)
206     schedstat_inc(rq, yld_cnt);
207     current->slice = slice(current);
208     current->time_slice = rr_interval(current);
209     - if (likely(!rt_task(current)))
210     + if (likely(!rt_task(current) && !idleprio(current)))
211     newprio = MIN_USER_PRIO;
212    
213     requeue_task(current, rq, newprio);
214     @@ -4564,6 +4616,7 @@ asmlinkage long sys_sched_get_priority_m
215     case SCHED_NORMAL:
216     case SCHED_BATCH:
217     case SCHED_ISO:
218     + case SCHED_IDLEPRIO:
219     ret = 0;
220     break;
221     }
222     @@ -4589,6 +4642,7 @@ asmlinkage long sys_sched_get_priority_m
223     case SCHED_NORMAL:
224     case SCHED_BATCH:
225     case SCHED_ISO:
226     + case SCHED_IDLEPRIO:
227     ret = 0;
228     }
229     return ret;