Changes to series and rx51_defconfig file for BFQ
[kernel-bfs] / kernel-bfs-2.6.28 / debian / patches / sched-latnice.patch
1 diff -uprN linux-2.6.28/arch/arm/include/asm/unistd.h linux-2.6.28.new/arch/arm/include/asm/unistd.h
2 --- linux-2.6.28/arch/arm/include/asm/unistd.h  2011-05-28 17:55:10.888715216 +0200
3 +++ linux-2.6.28.new/arch/arm/include/asm/unistd.h      2011-05-28 19:23:05.739661865 +0200
4 @@ -387,6 +387,9 @@
5  #define __NR_dup3                      (__NR_SYSCALL_BASE+358)
6  #define __NR_pipe2                     (__NR_SYSCALL_BASE+359)
7  #define __NR_inotify_init1             (__NR_SYSCALL_BASE+360)
8 +#define __NR_latnice                   (__NR_SYSCALL_BASE+361)
9 +#define __NR_setlatnice                (__NR_SYSCALL_BASE+362)
10 +#define __NR_getlatnice                (__NR_SYSCALL_BASE+363)
11  
12  /*
13   * The following SWIs are ARM private.
14 diff -uprN linux-2.6.28/arch/arm/kernel/calls.S linux-2.6.28.new/arch/arm/kernel/calls.S
15 --- linux-2.6.28/arch/arm/kernel/calls.S        2011-05-28 17:54:42.354377786 +0200
16 +++ linux-2.6.28.new/arch/arm/kernel/calls.S    2011-05-28 18:00:41.705628818 +0200
17 @@ -370,6 +370,9 @@
18                 CALL(sys_dup3)
19                 CALL(sys_pipe2)
20  /* 360 */      CALL(sys_inotify_init1)
21 +               CALL(sys_latnice)
22 +               CALL(sys_setlatnice)
23 +               CALL(sys_getlatnice)
24  #ifndef syscalls_counted
25  .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
26  #define syscalls_counted
27 diff -uprN linux-2.6.28/include/linux/init_task.h linux-2.6.28.new/include/linux/init_task.h
28 --- linux-2.6.28/include/linux/init_task.h      2011-05-28 18:08:36.442148441 +0200
29 +++ linux-2.6.28.new/include/linux/init_task.h  2011-05-28 18:07:40.471745225 +0200
30 @@ -133,6 +133,7 @@ extern struct group_info init_groups;
31         .prio           = NORMAL_PRIO,                                  \
32         .static_prio    = MAX_PRIO-20,                                  \
33         .normal_prio    = NORMAL_PRIO,                                  \
34 +       .latnice        = 1,                                            \
35         .deadline       = 0,                                            \
36         .policy         = SCHED_NORMAL,                                 \
37         .cpus_allowed   = CPU_MASK_ALL,                                 \
38 diff -uprN linux-2.6.28/include/linux/sched.h linux-2.6.28.new/include/linux/sched.h
39 --- linux-2.6.28/include/linux/sched.h  2011-05-28 18:09:18.241185206 +0200
40 +++ linux-2.6.28.new/include/linux/sched.h      2011-05-28 19:16:33.081566466 +0200
41 @@ -1118,7 +1118,7 @@ struct task_struct {
42         int oncpu;
43  #endif
44  
45 -       int prio, static_prio, normal_prio;
46 +       int prio, static_prio, normal_prio, latnice;
47         unsigned int rt_priority;
48  #ifdef CONFIG_SCHED_BFS
49         int time_slice;
50 diff -uprN linux-2.6.28/include/linux/syscalls.h linux-2.6.28.new/include/linux/syscalls.h
51 --- linux-2.6.28/include/linux/syscalls.h       2011-05-28 18:08:46.013191142 +0200
52 +++ linux-2.6.28.new/include/linux/syscalls.h   2011-05-28 19:16:05.936280778 +0200
53 @@ -207,6 +207,9 @@ asmlinkage long sys_clock_nanosleep(cloc
54                                 struct timespec __user *rmtp);
55  
56  asmlinkage long sys_nice(int increment);
57 +asmlinkage long sys_latnice(int latnice);
58 +asmlinkage long sys_setlatnice(pid_t pid, int latnice);
59 +asmlinkage long sys_getlatnice(pid_t pid);
60  asmlinkage long sys_sched_setscheduler(pid_t pid, int policy,
61                                         struct sched_param __user *param);
62  asmlinkage long sys_sched_setparam(pid_t pid,
63 diff -uprN linux-2.6.28/kernel/sched_bfs.c linux-2.6.28.new/kernel/sched_bfs.c
64 --- linux-2.6.28/kernel/sched_bfs.c     2011-05-28 18:10:39.803808798 +0200
65 +++ linux-2.6.28.new/kernel/sched_bfs.c 2011-05-28 20:33:37.485040832 +0200
66 @@ -153,6 +153,8 @@ int rr_interval __read_mostly = 6;
67   */
68  int sched_iso_cpu __read_mostly = 70;
69  
70 +int sched_interactive __read_mostly = 2;
71 +
72  /*
73   * group_thread_accounting - sysctl to decide whether to treat whole thread
74   * groups as a single entity for the purposes of CPU distribution.
75 @@ -2669,14 +2671,22 @@ EXPORT_SYMBOL(sub_preempt_count);
76   * proportion works out to the square of the virtual deadline difference, so
77   * this equation will give nice 19 3% CPU compared to nice 0.
78   */
79 -static inline u64 prio_deadline_diff(int user_prio)
80 +static inline u64 prio_deadline_diff(int user_prio, int latnice)
81  {
82 -       return (prio_ratios[user_prio] * rr_interval * (MS_TO_NS(1) / 128));
83 +       u64 pdd = prio_ratios[user_prio] * rr_interval;
84 +
85 +       pdd *= MS_TO_NS(1) / 128;
86 +       if (!latnice)
87 +               pdd <<= 1;
88 +       else if (latnice > 1)
89 +               pdd >>= latnice - 1;
90 +
91 +       return pdd;
92  }
93  
94  static inline u64 __task_deadline_diff(struct task_struct *p)
95  {
96 -       return prio_deadline_diff(TASK_USER_PRIO(p));
97 +       return prio_deadline_diff(TASK_USER_PRIO(p), p->latnice);
98  }
99  
100  static inline u64 task_deadline_diff(struct task_struct *p)
101 @@ -2690,12 +2700,12 @@ static inline u64 task_deadline_diff(str
102  
103  static inline u64 static_deadline_diff(int static_prio)
104  {
105 -       return prio_deadline_diff(USER_PRIO(static_prio));
106 +       return prio_deadline_diff(USER_PRIO(static_prio), 1);
107  }
108  
109  static inline int longest_deadline_diff(void)
110  {
111 -       return prio_deadline_diff(39);
112 +       return prio_deadline_diff(39, 0);
113  }
114  
115  static inline int ms_longest_deadline_diff(void)
116 @@ -2710,6 +2720,8 @@ static inline int ms_longest_deadline_di
117  static void time_slice_expired(struct task_struct *p)
118  {
119         u64 tdd = task_deadline_diff(p);
120 +       unsigned long ts = timeslice();
121 +       int latnice = p->latnice;
122  
123         /*
124          * We proportionately increase the deadline according to how many
125 @@ -2724,7 +2736,24 @@ static void time_slice_expired(struct ta
126                 if (*threads_running > 1)
127                         tdd += *threads_running * __task_deadline_diff(p);
128         }
129 -       p->time_slice = timeslice();
130 +
131 +       switch (sched_interactive) {
132 +               case 0:
133 +                       if (!latnice)
134 +                               ts <<= 1;
135 +                       else if (latnice > 1)
136 +                               ts >>= latnice - 1;
137 +                       break;
138 +               case 1:
139 +                       break;
140 +               case 2:
141 +                       if (!latnice)
142 +                               ts >>= 1;
143 +                       else if (latnice > 1)
144 +                               ts <<= latnice - 1;
145 +                       break;
146 +       }
147 +       p->time_slice = ts;
148         p->deadline_niffy = grq.niffies;
149         p->deadline = grq.niffies + tdd;
150  }
151 @@ -3524,6 +3553,104 @@ asmlinkage long sys_nice(int increment)
152  
153  #endif
154  
155 +static bool __check_same_owner(struct task_struct *p)
156 +{
157 +       uid_t euid = current_euid();
158 +       bool match;
159 +
160 +       rcu_read_lock();
161 +       match = (euid == task_euid(p) ||
162 +                euid == task_uid(p));
163 +       return match;
164 +}
165 +
166 +static bool check_same_owner(struct task_struct *p)
167 +{
168 +       bool match;
169 +
170 +       rcu_read_lock();
171 +       match = __check_same_owner(p);
172 +       rcu_read_unlock();
173 +       return match;
174 +}
175 +
176 +SYSCALL_DEFINE1(latnice, int, latnice)
177 +{
178 +       struct task_struct *p = current;
179 +       unsigned long flags;
180 +       struct rq *rq;
181 +
182 +       if (latnice < 0)
183 +               latnice = 0;
184 +       if (latnice > 3)
185 +               latnice = 3;
186 +
187 +       if (!check_same_owner(p))
188 +               return -EPERM;
189 +
190 +       rq = time_task_grq_lock(p, &flags);
191 +       p->latnice = latnice;
192 +       task_grq_unlock(&flags);
193 +
194 +       return 0;
195 +}
196 +
197 +static inline struct task_struct *find_process_by_pid(pid_t pid);
198 +
199 +SYSCALL_DEFINE2(setlatnice, pid_t, pid, int, latnice)
200 +{
201 +       struct task_struct *p;
202 +       int retval = -EINVAL;
203 +       unsigned long flags;
204 +       struct rq *rq;
205 +
206 +       if (pid < 0)
207 +               goto out_nounlock;
208 +
209 +       retval = -ESRCH;
210 +       rcu_read_lock();
211 +       p = find_process_by_pid(pid);
212 +       if (!p)
213 +               goto out_unlock;
214 +       if (!__check_same_owner(p)) {
215 +               retval = -EPERM;
216 +               goto out_unlock;
217 +       }
218 +
219 +       rq = time_task_grq_lock(p, &flags);
220 +       p->latnice = latnice;
221 +       task_grq_unlock(&flags);
222 +       retval = 0;
223 +
224 +out_unlock:
225 +       rcu_read_unlock();
226 +out_nounlock:
227 +       return retval;
228 +
229 +}
230 +
231 +SYSCALL_DEFINE1(getlatnice, pid_t, pid)
232 +{
233 +       struct task_struct *p;
234 +       int retval = -EINVAL;
235 +
236 +       if (pid < 0)
237 +               goto out_nounlock;
238 +
239 +       retval = -ESRCH;
240 +       rcu_read_lock();
241 +       p = find_process_by_pid(pid);
242 +       if (!p)
243 +               goto out_unlock;
244 +       retval = p->latnice;
245 +
246 +out_unlock:
247 +       rcu_read_unlock();
248 +out_nounlock:
249 +       return retval;
250 +
251 +}
252 +
253  /**
254   * task_prio - return the priority value of a given task.
255   * @p: the task in question.
256 diff -uprN linux-2.6.28/kernel/sysctl.c linux-2.6.28.new/kernel/sysctl.c
257 --- linux-2.6.28/kernel/sysctl.c        2011-05-28 18:10:57.710020361 +0200
258 +++ linux-2.6.28.new/kernel/sysctl.c    2011-05-28 19:15:03.708077897 +0200
259 @@ -102,6 +102,7 @@ static int __read_mostly one_hundred = 1
260  #ifdef CONFIG_SCHED_BFS
261  extern int rr_interval;
262  extern int sched_iso_cpu;
263 +extern int sched_interactive;
264  extern int group_thread_accounting;
265  extern int fork_depth_penalty;
266  static int __read_mostly one_thousand = 1000;
267 @@ -748,6 +749,15 @@ static struct ctl_table kern_table[] = {
268                 .extra2         = &one_hundred,
269         },
270         {
271 +               .procname       = "interactive",
272 +               .data           = &sched_interactive,
273 +               .maxlen         = sizeof(int),
274 +               .mode           = 0644,
275 +               .proc_handler   = &proc_dointvec_minmax,
276 +               .extra1         = &zero,
277 +               .extra2         = &two,
278 +       },
279 +       {
280                 .procname       = "group_thread_accounting",
281                 .data           = &group_thread_accounting,
282                 .maxlen         = sizeof (int),