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
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)
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
20 /* 360 */ CALL(sys_inotify_init1)
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, \
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 {
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
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);
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;
68 int sched_iso_cpu __read_mostly = 70;
70 +int sched_interactive __read_mostly = 2;
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.
79 -static inline u64 prio_deadline_diff(int user_prio)
80 +static inline u64 prio_deadline_diff(int user_prio, int latnice)
82 - return (prio_ratios[user_prio] * rr_interval * (MS_TO_NS(1) / 128));
83 + u64 pdd = prio_ratios[user_prio] * rr_interval;
85 + pdd *= MS_TO_NS(1) / 128;
88 + else if (latnice > 1)
89 + pdd >>= latnice - 1;
94 static inline u64 __task_deadline_diff(struct task_struct *p)
96 - return prio_deadline_diff(TASK_USER_PRIO(p));
97 + return prio_deadline_diff(TASK_USER_PRIO(p), p->latnice);
100 static inline u64 task_deadline_diff(struct task_struct *p)
101 @@ -2690,12 +2700,12 @@ static inline u64 task_deadline_diff(str
103 static inline u64 static_deadline_diff(int static_prio)
105 - return prio_deadline_diff(USER_PRIO(static_prio));
106 + return prio_deadline_diff(USER_PRIO(static_prio), 1);
109 static inline int longest_deadline_diff(void)
111 - return prio_deadline_diff(39);
112 + return prio_deadline_diff(39, 0);
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)
119 u64 tdd = task_deadline_diff(p);
120 + unsigned long ts = timeslice();
121 + int latnice = p->latnice;
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);
129 - p->time_slice = timeslice();
131 + switch (sched_interactive) {
135 + else if (latnice > 1)
136 + ts >>= latnice - 1;
143 + else if (latnice > 1)
144 + ts <<= latnice - 1;
147 + p->time_slice = ts;
148 p->deadline_niffy = grq.niffies;
149 p->deadline = grq.niffies + tdd;
151 @@ -3524,6 +3553,104 @@ asmlinkage long sys_nice(int increment)
155 +static bool __check_same_owner(struct task_struct *p)
157 + uid_t euid = current_euid();
161 + match = (euid == task_euid(p) ||
162 + euid == task_uid(p));
166 +static bool check_same_owner(struct task_struct *p)
171 + match = __check_same_owner(p);
176 +SYSCALL_DEFINE1(latnice, int, latnice)
178 + struct task_struct *p = current;
179 + unsigned long flags;
187 + if (!check_same_owner(p))
190 + rq = time_task_grq_lock(p, &flags);
191 + p->latnice = latnice;
192 + task_grq_unlock(&flags);
197 +static inline struct task_struct *find_process_by_pid(pid_t pid);
199 +SYSCALL_DEFINE2(setlatnice, pid_t, pid, int, latnice)
201 + struct task_struct *p;
202 + int retval = -EINVAL;
203 + unsigned long flags;
211 + p = find_process_by_pid(pid);
214 + if (!__check_same_owner(p)) {
219 + rq = time_task_grq_lock(p, &flags);
220 + p->latnice = latnice;
221 + task_grq_unlock(&flags);
231 +SYSCALL_DEFINE1(getlatnice, pid_t, pid)
233 + struct task_struct *p;
234 + int retval = -EINVAL;
241 + p = find_process_by_pid(pid);
244 + retval = p->latnice;
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,
271 + .procname = "interactive",
272 + .data = &sched_interactive,
273 + .maxlen = sizeof(int),
275 + .proc_handler = &proc_dointvec_minmax,
280 .procname = "group_thread_accounting",
281 .data = &group_thread_accounting,
282 .maxlen = sizeof (int),