Skip to contentSkip to conversation

2.6.21-rc4 nicksched v32

PATCH New Nick Piggin 1 participant 1 message Mar 22, 2007

Subsystems (5)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 2.6.21-rc4 nicksched v32

Hi,

Considering the recent attention on CPU schedulers, so here is an updated version of my scheduler against 2.6.21-rc4. I often run it on my own desktop here here and it works well for me, no guarantees! I would be happy if anyone was interested in testing it :)

Thanks,
Nick

Signature · 1 line
SUSE Labs, Novell Inc.

Forward port of nicksched to 2.6.21-rc4. Can't find my old design/description document for it, but it is yet another scheduler. Focus is on simplicity and fairness.

This one tends to require X to be reniced to -10 or so for best results (renice -10 pidof X).

Timeslices get scaled by /proc/sys/kernel/base_timeslice. If you have bad interactivity you could try lowering this and see if it helps.

 fs/proc/array.c           |   12
 include/linux/init_task.h |    7
 include/linux/sched.h     |   34 -
 include/linux/sysctl.h    |    1
 kernel/sched.c            | 1122 +++++++++++++++++-----------------------------
 kernel/sysctl.c           |   16
 mm/oom_kill.c             |    7
 7 files changed, 476 insertions(+), 723 deletions(-)
fs/proc/array.c +10 -2
Index: linux-2.6/fs/proc/array.c
===================================================================
@@ -165,7 +165,13 @@ static inline char * task_state(struct t
 	rcu_read_lock();
 	buffer += sprintf(buffer,
 		"State:\t%s\n"
-		"SleepAVG:\t%lu%%\n"
+		"timeslice:\t%d\n"
+		"usedslice:\t%d\n"
+		"arrayseq:\t%lu\n"
+		"staticprio:\t%u\n"
+		"prio:\t%u\n"
+		"sleep_time:\t%lu\n"
+		"total_time:\t%lu\n"
 		"Tgid:\t%d\n"
 		"Pid:\t%d\n"
 		"PPid:\t%d\n"
@@ -173,7 +179,9 @@ static inline char * task_state(struct t
 		"Uid:\t%d\t%d\t%d\t%d\n"
 		"Gid:\t%d\t%d\t%d\t%d\n",
 		get_task_state(p),
-		(p->sleep_avg/1024)*100/(1020000000/1024),
+		get_task_timeslice(p), p->used_slice, p->array_sequence,
+		p->static_prio, p->prio,
+		p->sleep_time, p->total_time,
 	       	p->tgid, p->pid,
 	       	pid_alive(p) ? rcu_dereference(p->real_parent)->tgid : 0,
 		pid_alive(p) && p->ptrace ? rcu_dereference(p->parent)->pid : 0,
include/linux/sched.h +14 -20
Index: linux-2.6/include/linux/sched.h
===================================================================
@@ -523,7 +523,7 @@ struct signal_struct {
 #define MAX_USER_RT_PRIO	100
 #define MAX_RT_PRIO		MAX_USER_RT_PRIO
 
-#define MAX_PRIO		(MAX_RT_PRIO + 40)
+#define MAX_PRIO		(MAX_RT_PRIO + 59)
 
 #define rt_prio(prio)		unlikely((prio) < MAX_RT_PRIO)
 #define rt_task(p)		rt_prio((p)->prio)
@@ -788,24 +788,16 @@ struct mempolicy;
 struct pipe_inode_info;
 struct uts_namespace;
 
-enum sleep_type {
-	SLEEP_NORMAL,
-	SLEEP_NONINTERACTIVE,
-	SLEEP_INTERACTIVE,
-	SLEEP_INTERRUPTED,
-};
-
 struct prio_array;
 
 struct task_struct {
 	volatile long state;	/* -1 unrunnable, 0 runnable, >0 stopped */
 	struct thread_info *thread_info;
 	atomic_t usage;
+	int lock_depth;		/* BKL lock depth */
 	unsigned long flags;	/* per process flags, defined below */
 	unsigned long ptrace;
 
-	int lock_depth;		/* BKL lock depth */
-
 #ifdef CONFIG_SMP
 #ifdef __ARCH_WANT_UNLOCKED_CTXSW
 	int oncpu;
@@ -813,27 +805,29 @@ struct task_struct {
 #endif
 	int load_weight;	/* for niceness load balancing purposes */
 	int prio, static_prio, normal_prio;
+	int used_slice, over_slice;
 	struct list_head run_list;
 	struct prio_array *array;
+	unsigned long array_sequence;
 
-	unsigned short ioprio;
-#ifdef CONFIG_BLK_DEV_IO_TRACE
-	unsigned int btrace_seq;
-#endif
-	unsigned long sleep_avg;
 	unsigned long long timestamp, last_ran;
 	unsigned long long sched_time; /* sched_clock time spent running */
-	enum sleep_type sleep_type;
+	unsigned long total_time, sleep_time;
+
+	struct list_head tasks;
+	struct mm_struct *mm, *active_mm;
 
 	unsigned long policy;
 	cpumask_t cpus_allowed;
-	unsigned int time_slice, first_time_slice;
 
 #if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT)
 	struct sched_info sched_info;
 #endif
 
-	struct list_head tasks;
+	unsigned short ioprio;
+#ifdef CONFIG_BLK_DEV_IO_TRACE
+	unsigned int btrace_seq;
+#endif
 	/*
 	 * ptrace_list/ptrace_children forms the list of my children
 	 * that were stolen by a ptracer.
@@ -841,8 +835,6 @@ struct task_struct {
 	struct list_head ptrace_children;
 	struct list_head ptrace_list;
 
-	struct mm_struct *mm, *active_mm;
-
 /* task state */
 	struct linux_binfmt *binfmt;
 	long exit_state;
@@ -1199,6 +1191,8 @@ extern unsigned long long sched_clock(vo
 extern unsigned long long
 current_sched_time(const struct task_struct *current_task);
 
+extern int get_task_timeslice(struct task_struct *t);
+
 /* sched_exec is called by processes performing an exec */
 #ifdef CONFIG_SMP
 extern void sched_exec(void);
kernel/sched.c +430 -692

1,636 lines not on this page · raw message

mm/oom_kill.c +3 -4
Index: linux-2.6/mm/oom_kill.c
===================================================================
@@ -287,11 +287,10 @@ static void __oom_kill_task(struct task_
 		printk(KERN_ERR "Killed process %d (%s)\n", p->pid, p->comm);
 
 	/*
-	 * We give our sacrificial lamb high priority and access to
-	 * all the memory it needs. That way it should be able to
-	 * exit() and clear out its resources quickly...
+	 * We give our sacrificial lamb access to all the memory it needs.
+	 * That way it should be able to exit() and clear out its resources
+	 * quickly...
 	 */
-	p->time_slice = HZ;
 	set_tsk_thread_flag(p, TIF_MEMDIE);
 
 	force_sig(SIGKILL, p);
kernel/sysctl.c +15 -1
Index: linux-2.6/kernel/sysctl.c
===================================================================
@@ -76,6 +76,9 @@ extern int pid_max_min, pid_max_max;
 extern int sysctl_drop_caches;
 extern int percpu_pagelist_fraction;
 extern int compat_log;
+extern int sched_base_timeslice;
+extern int sched_min_base;
+extern int sched_max_base;
 
 /* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */
 static int maxolduid = 65535;
@@ -603,7 +606,17 @@ static ctl_table kern_table[] = {
 		.proc_handler	= &proc_dointvec,
 	},
 #endif
-
+	{
+		.ctl_name	= KERN_SCHED_TIMESLICE,
+		.procname	= "base_timeslice",
+		.data		= &sched_base_timeslice,
+		.maxlen		= sizeof (sched_base_timeslice),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_minmax,
+		.strategy	= &sysctl_intvec,
+		.extra1		= &sched_min_base,
+		.extra2		= &sched_max_base,
+	},
 	{ .ctl_name = 0 }
 };
 
@@ -859,6 +872,7 @@ static ctl_table vm_table[] = {
 		.extra1		= &zero,
 	},
 #endif
+
 	{ .ctl_name = 0 }
 };
 
include/linux/init_task.h +3 -4
Index: linux-2.6/include/linux/init_task.h
===================================================================
@@ -99,16 +99,15 @@ extern struct group_info init_groups;
 	.usage		= ATOMIC_INIT(2),				\
 	.flags		= 0,						\
 	.lock_depth	= -1,						\
-	.prio		= MAX_PRIO-20,					\
-	.static_prio	= MAX_PRIO-20,					\
-	.normal_prio	= MAX_PRIO-20,					\
+	.prio		= MAX_PRIO-29,					\
+	.static_prio	= MAX_PRIO-29,					\
+	.normal_prio	= MAX_PRIO-29,					\
 	.policy		= SCHED_NORMAL,					\
 	.cpus_allowed	= CPU_MASK_ALL,					\
 	.mm		= NULL,						\
 	.active_mm	= &init_mm,					\
 	.run_list	= LIST_HEAD_INIT(tsk.run_list),			\
 	.ioprio		= 0,						\
-	.time_slice	= HZ,						\
 	.tasks		= LIST_HEAD_INIT(tsk.tasks),			\
 	.ptrace_children= LIST_HEAD_INIT(tsk.ptrace_children),		\
 	.ptrace_list	= LIST_HEAD_INIT(tsk.ptrace_list),		\
include/linux/sysctl.h +1 -0
Index: linux-2.6/include/linux/sysctl.h
===================================================================
@@ -165,6 +165,7 @@ enum
 	KERN_MAX_LOCK_DEPTH=74,
 	KERN_NMI_WATCHDOG=75, /* int: enable/disable nmi watchdog */
 	KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */
+	KERN_SCHED_TIMESLICE=77, /* int: base timeslice for scheduler */
 };