fairsched-A4 for 2.5.66
Subsystems (4)
After some more work, I'm releasing the fourth version of the fairsched patch for O(1) enabled kernels.
The patch has been tested _not_ to work, but I hope that by relasing it some more experienced hackers could help on debugging it.
I've put up a page explaining the background and the intended design of the patch at this link:
http://www.cocodriloo.com/~wind/fairsched/
Right now, I've managed to boot it and get running on a plain system, by using this shell script as init:
#!/bin/sh
mount /proc
mount -n -o remount,rw /
#nice su user1 -c "/cpuhog.sh 1"
#nice su user2 -c "/cpuhog.sh 2"
#nice su user3 -c "/cpuhog.sh 3"
( sleep 2 && echo 1 > fairsched ) &/bin/bash --login
EOF
cpuhog.sh: this launches $1 parallel gzips
#!/bin/sh
N=$1
while [ $N -ne 0 ]; do
gzip -c </dev/zero >/dev/null &
N=$(($N - 1))
done
EOF
If I uncomment any of the "su" commands, I get two possible outcomes:
(states identified by the printk codes for the patch)
a. It enters state Dn and sends the task to the per-user list.
Then, state Cn (the kernel thread), notices it and activates it.
b. It enters state Dn and then locks up solid.
c. It goes kaboom and gives a "scheduling with no mm" message
I don't really know how to continue this debugging, any ideas?
Greets, Antonio
ps. The page explains some ideas for futher design, mostly whishful thinking, but perhaps useful.
---
This patch is a forward port of the fairsched-2.4.19 patch by Rik van Riel, which ensures all competing users get an equal share of cpu time.
Since the earlier patch applied to the classic O(n) process scheduler, and this one applies to the standard 2.5 O(1) one, the mapping isn't one-to-one but rather more complex.
Original 2.4.19 version: Rik van Riel, [email protected] Forward ported 2.5.66 version: Antonio Vargas, [email protected]
A0: initial layout for code and data
A1: introduce runqueue handling related to per-user cpu share
A2: add proper locking and O(1) behaviour
A3: perform all work with a kernel thread
A4: introduced a new priority array to park pending tasks,
somewhat works when running in debug mode using printk
include/linux/init_task.h | 2 include/linux/sched.h | 14 ++ include/linux/sysctl.h | 1 kernel/fork.c | 1 kernel/sched.c | 89 ++++++++++++++++-- kernel/sysctl.c | 3 kernel/user.c | 225 +++++++++++++++++++++++++++++++++++++++++++++- 7 files changed, 327 insertions(+), 8 deletions(-)
include/linux/init_task.h renamed from include/linux/init_task.h~fairsched-A4 +2 -0
@@ -73,6 +73,8 @@ .active_mm = &init_mm, \ .run_list = LIST_HEAD_INIT(tsk.run_list), \ .time_slice = HZ, \ + .reserved_time_slice = HZ, \ + .user_tasks = LIST_HEAD_INIT(tsk.user_tasks), \ .tasks = LIST_HEAD_INIT(tsk.tasks), \ .ptrace_children= LIST_HEAD_INIT(tsk.ptrace_children), \ .ptrace_list = LIST_HEAD_INIT(tsk.ptrace_list), \
include/linux/sched.h renamed from include/linux/sched.h~fairsched-A4 +14 -0
@@ -280,6 +280,16 @@ struct user_struct {/* Hash table maintenance information */ struct list_head uidhash_list;uid_t uid; + +/* User list */ +struct list_head user_list; + +/* Task list for this user, and protecting spinlock */ +struct list_head task_list; +spinlock_t task_list_lock; + +/* Per-user timeslice management */ +unsigned int time_slice; };#define get_current_user () ({ \
@@ -333,7 +343,11 @@ struct task_struct {unsigned long policy;unsigned long cpus_allowed;unsigned int time_slice, first_time_slice; +unsigned int reserved_time_slice; + +struct work_struct work_to_user; +struct list_head user_tasks;struct list_head tasks;struct list_head ptrace_children;struct list_head ptrace_list;
include/linux/sysctl.h renamed from include/linux/sysctl.h~fairsched-A4 +1 -0
@@ -129,6 +129,7 @@ enumKERN_CADPID =54 ,/* int: PID of the process to notify on CAD */ KERN_PIDMAX =55 ,/* int: PID # limit */ KERN_CORE_PATTERN =56 ,/* string: pattern for core-file names */ + KERN_FAIRSCHED=57, /* switch per-user fair cpu scheduler*/ };
kernel/fork.c renamed from kernel/fork.c~fairsched-A4 +1 -0
@@ -917,6 +917,7 @@ static struct task_struct *copy_process(* the parent if the child exits early enough. */ p->first_time_slice =1 ; + p->reserved_time_slice =0 ; current->time_slice >>=1 ; p->last_run = jiffies;if (!current->time_slice) {
kernel/sched.c renamed from kernel/sched.c~fairsched-A4 +82 -7
153 lines not on this page · raw message
kernel/sysctl.c renamed from kernel/sysctl.c~fairsched-A4 +3 -0
@@ -57,6 +57,7 @@ extern char core_pattern[];extern int cad_pid;extern int pid_max;extern int sysctl_lower_zone_protection; +extern int fairsched;/* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */ static int maxolduid =65535 ;
@@ -263,6 +264,8 @@ static ctl_table kern_table[] = {#endif {KERN_PIDMAX ,"pid_max" , &pid_max,sizeof (int ), 0600, NULL, &proc_dointvec}, + {KERN_FAIRSCHED, "fairsched", &fairsched, sizeof (int), + 0644, NULL, &proc_dointvec}, {0} };
kernel/user.c renamed from kernel/user.c~fairsched-A4 +224 -1
273 lines not on this page · raw message
_