How would I apply the Phoronix patch?

http://www.phoronix.com/scan.php?page=article&item=linux_2637_video

How would I apply this patch? And is it really as good as they (and Linus Torvalds) seem to think?

So you have a quad quad setup? I’d be happy with make -j4 (well maybe
-j8).

Grab the git code, apply the patch and rebuild the kernel…

Larry Finger has an easy way to do it, search on the forum for
lwfinger+kernel.


Cheers Malcolm °¿° (Linux Counter #276890)
SUSE Linux Enterprise Desktop 11 (x86_64) Kernel 2.6.32.24-0.2-default
up 4 days 1:20, 3 users, load average: 0.27, 0.14, 0.08
GPU GeForce 8600 GTS Silent - Driver Version: 260.19.21

Wait, did I misunderstand this? From what I read, it also works well on Atom netbooks:

This patch has been working out extremely great on all of the test systems I tried it out on so far from quad-core AMD Phenom CPUs systems **to Intel Atom netbooks. **

So it doesn’t need to be quad-core’d, right?

Alternative To The “200 Lines Kernel Patch That Does Wonders” Which You Can Use Right Away ~ Web Upd8: Ubuntu / Linux blog

Is there any mileage in this idea?

For sure it will, will the average desktop user notice it on an atom, I
hope so as I’m one…

Not at all, just messin with you… :wink: Unless your recompiling the
kernel every few minutes…?


Cheers Malcolm °¿° (Linux Counter #276890)
SUSE Linux Enterprise Desktop 11 (x86_64) Kernel 2.6.32.24-0.2-default
up 6 days 4:49, 2 users, load average: 0.13, 0.11, 0.10
GPU GeForce 8600 GTS Silent - Driver Version: 260.19.21

I gave the Alternative To The “200 Lines Kernel Patch That Does Wonders” Which You Can Use Right Away ~ Web Upd8: Ubuntu / Linux blog instructions a try, but I’m getting stuck:
Changing my ~/.bashrc was no problem

I installed libcgroup1, found ‘cgconfig’ and ‘cgred’ in the runlevel editor. Now cgconfig won’t start, thus cgred doesn’t start. So no control groups…
Found the example files in /usr/share/doc/packages/libcgroup1 but I cannot see quickly how to effect the commands with good result.

Anybody willing to sort it out?

Hi
Didn’t have to do a thing on 11.4 M3 although I’m running systemd so the cgroups stuff was already there.

On Thu, 18 Nov 2010 21:06:02 +0000, KJ44 wrote:

> ‘Alternative To The “200 Lines Kernel Patch That Does Wonders” Which
> You Can Use Right Away ~ Web Upd8: Ubuntu / Linux blog’
> (http://tinyurl.com/2afhkja)
>
> Is there any mileage in this idea?

There’s a request in openFATE; I’d suggest voting for it. A few people
who have tried it said it really made a big difference.

Jim


Jim Henderson
openSUSE Forums Administrator
Forum Use Terms & Conditions at http://tinyurl.com/openSUSE-T-C

On Thu, 18 Nov 2010 23:32:36 +0000, Jim Henderson wrote:

> There’s a request in openFATE; I’d suggest voting for it. A few people
> who have tried it said it really made a big difference.

My bad, I meant to reply to a different post - the openFATE entry is for
the 200 line patch.

Jim


Jim Henderson
openSUSE Forums Administrator
Forum Use Terms & Conditions at http://tinyurl.com/openSUSE-T-C

download the 2.37-rc2 of 16. November 2011

http://www.kernel.org/pub/linux/kernel/v2.6/testing/linux-2.6.37-rc2.tar.bz2

extract it to a folder named “linux-2.6”.

save this as “patch-cfs”


Index: linux-2.6/include/linux/sched.h
===================================================================
--- linux-2.6/include/linux/sched.h
+++ linux-2.6/include/linux/sched.h
@@ -509,6 +509,8 @@ struct thread_group_cputimer {
 	spinlock_t lock;
 };
 
+struct autogroup;
+
 /*
  * NOTE! "signal_struct" does not have it's own
  * locking, because a shared signal_struct always
@@ -576,6 +578,9 @@ struct signal_struct {
 
 	struct tty_struct *tty; /* NULL if no tty */
 
+#ifdef CONFIG_SCHED_AUTOGROUP
+	struct autogroup *autogroup;
+#endif
 	/*
 	 * Cumulative resource counters for dead threads in the group,
 	 * and for reaped dead child processes forked by this group.
@@ -1931,6 +1936,20 @@ int sched_rt_handler(struct ctl_table *t
 
 extern unsigned int sysctl_sched_compat_yield;
 
+#ifdef CONFIG_SCHED_AUTOGROUP
+extern unsigned int sysctl_sched_autogroup_enabled;
+
+extern void sched_autogroup_create_attach(struct task_struct *p);
+extern void sched_autogroup_detach(struct task_struct *p);
+extern void sched_autogroup_fork(struct signal_struct *sig);
+extern void sched_autogroup_exit(struct signal_struct *sig);
+#else
+static inline void sched_autogroup_create_attach(struct task_struct *p) { }
+static inline void sched_autogroup_detach(struct task_struct *p) { }
+static inline void sched_autogroup_fork(struct signal_struct *sig) { }
+static inline void sched_autogroup_exit(struct signal_struct *sig) { }
+#endif
+
 #ifdef CONFIG_RT_MUTEXES
 extern int rt_mutex_getprio(struct task_struct *p);
 extern void rt_mutex_setprio(struct task_struct *p, int prio);
Index: linux-2.6/kernel/sched.c
===================================================================
--- linux-2.6/kernel/sched.c
+++ linux-2.6/kernel/sched.c
@@ -78,6 +78,7 @@
 
 #include "sched_cpupri.h"
 #include "workqueue_sched.h"
+#include "sched_autogroup.h"
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/sched.h>
@@ -605,11 +606,14 @@ static inline int cpu_of(struct rq *rq)
  */
 static inline struct task_group *task_group(struct task_struct *p)
 {
+	struct task_group *tg;
 	struct cgroup_subsys_state *css;
 
 	css = task_subsys_state_check(p, cpu_cgroup_subsys_id,
 			lockdep_is_held(&task_rq(p)->lock));
-	return container_of(css, struct task_group, css);
+	tg = container_of(css, struct task_group, css);
+
+	return autogroup_task_group(p, tg);
 }
 
 /* Change a task's cfs_rq and parent entity if it moves across CPUs/groups */
@@ -2006,6 +2010,7 @@ static void sched_irq_time_avg_update(st
 #include "sched_idletask.c"
 #include "sched_fair.c"
 #include "sched_rt.c"
+#include "sched_autogroup.c"
 #include "sched_stoptask.c"
 #ifdef CONFIG_SCHED_DEBUG
 # include "sched_debug.c"
@@ -7979,7 +7984,7 @@ void __init sched_init(void)
 #ifdef CONFIG_CGROUP_SCHED
 	list_add(&init_task_group.list, &task_groups);
 	INIT_LIST_HEAD(&init_task_group.children);
-
+	autogroup_init(&init_task);
 #endif /* CONFIG_CGROUP_SCHED */
 
 #if defined CONFIG_FAIR_GROUP_SCHED && defined CONFIG_SMP
@@ -8509,15 +8514,11 @@ void sched_destroy_group(struct task_gro
 /* change task's runqueue when it moves between groups.
  *	The caller of this function should have put the task in its new group
  *	by now. This function just updates tsk->se.cfs_rq and tsk->se.parent to
- *	reflect its new group.
+ *	reflect its new group.  Called with the runqueue lock held.
  */
-void sched_move_task(struct task_struct *tsk)
+void __sched_move_task(struct task_struct *tsk, struct rq *rq)
 {
 	int on_rq, running;
-	unsigned long flags;
-	struct rq *rq;
-
-	rq = task_rq_lock(tsk, &flags);
 
 	running = task_current(rq, tsk);
 	on_rq = tsk->se.on_rq;
@@ -8538,7 +8539,15 @@ void sched_move_task(struct task_struct
 		tsk->sched_class->set_curr_task(rq);
 	if (on_rq)
 		enqueue_task(rq, tsk, 0);
+}
 
+void sched_move_task(struct task_struct *tsk)
+{
+	struct rq *rq;
+	unsigned long flags;
+
+	rq = task_rq_lock(tsk, &flags);
+	__sched_move_task(tsk, rq);
 	task_rq_unlock(rq, &flags);
 }
 #endif /* CONFIG_CGROUP_SCHED */
Index: linux-2.6/kernel/fork.c
===================================================================
--- linux-2.6/kernel/fork.c
+++ linux-2.6/kernel/fork.c
@@ -174,8 +174,10 @@ static inline void free_signal_struct(st
 
 static inline void put_signal_struct(struct signal_struct *sig)
 {
-	if (atomic_dec_and_test(&sig->sigcnt))
+	if (atomic_dec_and_test(&sig->sigcnt)) {
+		sched_autogroup_exit(sig);
 		free_signal_struct(sig);
+	}
 }
 
 void __put_task_struct(struct task_struct *tsk)
@@ -904,6 +906,7 @@ static int copy_signal(unsigned long clo
 	posix_cpu_timers_init_group(sig);
 
 	tty_audit_fork(sig);
+	sched_autogroup_fork(sig);
 
 	sig->oom_adj = current->signal->oom_adj;
 	sig->oom_score_adj = current->signal->oom_score_adj;
Index: linux-2.6/drivers/tty/tty_io.c
===================================================================
--- linux-2.6/drivers/tty/tty_io.c
+++ linux-2.6/drivers/tty/tty_io.c
@@ -3160,6 +3160,7 @@ static void __proc_set_tty(struct task_s
 	put_pid(tsk->signal->tty_old_pgrp);
 	tsk->signal->tty = tty_kref_get(tty);
 	tsk->signal->tty_old_pgrp = NULL;
+	sched_autogroup_create_attach(tsk);
 }
 
 static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
Index: linux-2.6/kernel/sched_autogroup.h
===================================================================
--- /dev/null
+++ linux-2.6/kernel/sched_autogroup.h
@@ -0,0 +1,18 @@
+#ifdef CONFIG_SCHED_AUTOGROUP
+
+static void __sched_move_task(struct task_struct *tsk, struct rq *rq);
+
+static inline struct task_group *
+autogroup_task_group(struct task_struct *p, struct task_group *tg);
+
+#else /* !CONFIG_SCHED_AUTOGROUP */
+
+static inline void autogroup_init(struct task_struct *init_task) {  }
+
+static inline struct task_group *
+autogroup_task_group(struct task_struct *p, struct task_group *tg)
+{
+	return tg;
+}
+
+#endif /* CONFIG_SCHED_AUTOGROUP */
Index: linux-2.6/kernel/sched_autogroup.c
===================================================================
--- /dev/null
+++ linux-2.6/kernel/sched_autogroup.c
@@ -0,0 +1,140 @@
+#ifdef CONFIG_SCHED_AUTOGROUP
+
+unsigned int __read_mostly sysctl_sched_autogroup_enabled = 1;
+
+struct autogroup {
+	struct kref		kref;
+	struct task_group	*tg;
+};
+
+static struct autogroup autogroup_default;
+
+static void autogroup_init(struct task_struct *init_task)
+{
+	autogroup_default.tg = &init_task_group;
+	kref_init(&autogroup_default.kref);
+	init_task->signal->autogroup = &autogroup_default;
+}
+
+static inline void autogroup_destroy(struct kref *kref)
+{
+	struct autogroup *ag = container_of(kref, struct autogroup, kref);
+	struct task_group *tg = ag->tg;
+
+	kfree(ag);
+	sched_destroy_group(tg);
+}
+
+static inline void autogroup_kref_put(struct autogroup *ag)
+{
+	kref_put(&ag->kref, autogroup_destroy);
+}
+
+static inline struct autogroup *autogroup_kref_get(struct autogroup *ag)
+{
+	kref_get(&ag->kref);
+	return ag;
+}
+
+static inline struct autogroup *autogroup_create(void)
+{
+	struct autogroup *ag = kmalloc(sizeof(*ag), GFP_KERNEL);
+
+	if (!ag)
+		goto out_fail;
+
+	ag->tg = sched_create_group(&init_task_group);
+	kref_init(&ag->kref);
+
+	if (!(IS_ERR(ag->tg)))
+		return ag;
+
+out_fail:
+	if (ag) {
+		kfree(ag);
+		WARN_ON(1);
+	} else
+		WARN_ON(1);
+
+	return autogroup_kref_get(&autogroup_default);
+}
+
+static inline struct task_group *
+autogroup_task_group(struct task_struct *p, struct task_group *tg)
+{
+	int enabled = ACCESS_ONCE(sysctl_sched_autogroup_enabled);
+
+	enabled &= (tg == &root_task_group);
+	enabled &= (p->sched_class == &fair_sched_class);
+	enabled &= (!(p->flags & PF_EXITING));
+
+	if (enabled)
+		return p->signal->autogroup->tg;
+
+	return tg;
+}
+
+static void
+autogroup_move_group(struct task_struct *p, struct autogroup *ag)
+{
+	struct autogroup *prev;
+	struct task_struct *t;
+	struct rq *rq;
+	unsigned long flags;
+
+	rq = task_rq_lock(p, &flags);
+	prev = p->signal->autogroup;
+	if (prev == ag) {
+		task_rq_unlock(rq, &flags);
+		return;
+	}
+
+	p->signal->autogroup = autogroup_kref_get(ag);
+	__sched_move_task(p, rq);
+	task_rq_unlock(rq, &flags);
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(t, &p->thread_group, thread_group) {
+		sched_move_task(t);
+	}
+	rcu_read_unlock();
+
+	autogroup_kref_put(prev);
+}
+
+void sched_autogroup_create_attach(struct task_struct *p)
+{
+	struct autogroup *ag = autogroup_create();
+
+	autogroup_move_group(p, ag);
+	/* drop extra refrence added by autogroup_create() */
+	autogroup_kref_put(ag);
+}
+EXPORT_SYMBOL(sched_autogroup_create_attach);
+
+/* currently has no users */
+void sched_autogroup_detach(struct task_struct *p)
+{
+	autogroup_move_group(p, &autogroup_default);
+}
+EXPORT_SYMBOL(sched_autogroup_detach);
+
+void sched_autogroup_fork(struct signal_struct *sig)
+{
+	sig->autogroup = autogroup_kref_get(current->signal->autogroup);
+}
+
+void sched_autogroup_exit(struct signal_struct *sig)
+{
+	autogroup_kref_put(sig->autogroup);
+}
+
+static int __init setup_autogroup(char *str)
+{
+	sysctl_sched_autogroup_enabled = 0;
+
+	return 1;
+}
+
+__setup("noautogroup", setup_autogroup);
+#endif
Index: linux-2.6/kernel/sysctl.c
===================================================================
--- linux-2.6/kernel/sysctl.c
+++ linux-2.6/kernel/sysctl.c
@@ -382,6 +382,17 @@ static struct ctl_table kern_table] = {
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec,
 	},
+#ifdef CONFIG_SCHED_AUTOGROUP
+	{
+		.procname	= "sched_autogroup_enabled",
+		.data		= &sysctl_sched_autogroup_enabled,
+		.maxlen		= sizeof(unsigned int),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec,
+		.extra1		= &zero,
+		.extra2		= &one,
+	},
+#endif
 #ifdef CONFIG_PROVE_LOCKING
 	{
 		.procname	= "prove_locking",
Index: linux-2.6/init/Kconfig
===================================================================
--- linux-2.6/init/Kconfig
+++ linux-2.6/init/Kconfig
@@ -728,6 +728,18 @@ config NET_NS
 
 endif # NAMESPACES
 
+config SCHED_AUTOGROUP
+	bool "Automatic process group scheduling"
+	select CGROUPS
+	select CGROUP_SCHED
+	select FAIR_GROUP_SCHED
+	help
+	  This option optimizes the scheduler for common desktop workloads by
+	  automatically creating and populating task groups.  This separation
+	  of workloads isolates aggressive CPU burners (like build jobs) from
+	  desktop applications.  Task group autogeneration is currently based
+	  upon task tty association.
+
 config MM_OWNER
 	bool
 
Index: linux-2.6/Documentation/kernel-parameters.txt
===================================================================
--- linux-2.6/Documentation/kernel-parameters.txt
+++ linux-2.6/Documentation/kernel-parameters.txt
@@ -1622,6 +1622,8 @@ and is between 256 and 4096 characters.
 	noapic		[SMP,APIC] Tells the kernel to not make use of any
 			IOAPICs that may be present in the system.
 
+	noautogroup	Disable scheduler automatic task group creation.
+
 	nobats		[PPC] Do not use BATs for mapping kernel lowmem
 			on "Classic" PPC cores

apply this patch with:

patch -p0 < patch-cfq

in menuconfig check the option “enable automatic process scheduling” under “general options”. compile.

when booted, don’t forget you’ll have to enable aps in /proc/sys/kernel/sched_autogroup

is it really that good?

i enjoy it, espeally on my stone-old laptop. works well while copying (from truecrypt to truecrypt device) as suggested.

Do you have a link to this? I can’t find it on openfate.

On Mon, 22 Nov 2010 18:36:03 +0000, 6tr6tr wrote:

> Do you have a link to this? I can’t find it on openfate.

https://features.opensuse.org/310843

Looks like the work is completed for 11.4 already.

Jim


Jim Henderson
openSUSE Forums Administrator
Forum Use Terms & Conditions at http://tinyurl.com/openSUSE-T-C

My concerns is actually how much of the users will be able to take something out of it… If you don’t know how to apply a kernel patch, I doubt you use your terminal a lot to take benefit of the patch… It’s doesn’t make any difference for GUI stuff…

Maybe understanding what it really does actually would help more than following why it sorts out other people’s needs… I sense a lot of people having broken expectations because they don’t understand the very own basics of the patch and how it helps.

Knurpht and I came up with a way to try this on openSUSE-11.3 with the kernel-default installed. I posted the method that we applied here: oldcpu/knurpht implementation of the alternative to the 200 lines (on openSUSE-11.3) and then jdmcdaniel3 wrote a script to automate the installation of this hack here: jdmcdaniel3 script to simply applying the ‘hack’ for the alternative to the 200 line kernel patch

I have this “alternative” method running now on 4 openSUSE-11.3 PCs.

Note any kernel update will likely impact the /boot/grub/menu.lst file and remove the “cgroup_enable=memory” boot code.

I recommend this only be used by those wanting to “test” who are happy doing the appropriate configuration file edits, and who are not using their PCs “operationally”.

i wonder, if this doesn’t just apply to programs started by bash?

For the “alternative to the 200 line kernel patch” that may be the case. It is not the case (from what I have read) for the 200 line kernel patch.

But unless one applies a different (non-standard) kernel then for openSUSE-11.3 an easy alternative, to obtain an assessment for the sort of improvements that can be seen for some applications, is via this alternative.

Reading this more, even the 200-line kernel patch does not apply to all process. From what I have read, its for process started by TTY or bash.

I think I am wrong in this quoted statement … ie even the 200-line kernel patch does not apply to all process. From what I have read, its for process started by TTY or bash.

no, thats not the case since the kernel does not know and does not care what type of program is running:

It’s an improvement for things like smooth scrolling around, but what I found more interesting was how it seems to really make web pages load a lot faster. Maybe it shouldn’t have been surprising, but I always associated that with network performance. But there’s clearly enough of a CPU load when loading a new web page that if you have a load average of 50+ at the same time, you will be starved for CPU in the loading process, and probably won’t get all the http requests out quickly enough.

So I think this is firmly one of those “real improvement” patches. Good job. Group scheduling goes from “useful for some specific server loads” to “that’s a killer feature”.

Linus

Did you read that mailing list thread? If you did you would have read that Linus started the browser from a command line (tty).

The thread also makes it clear that they are talking about TTY improvements. There was a bit of a flame war going on about that.

I recommend you read the entire thread about the kernel patch … for the more I read it, the more I see cautions being raised about the universality of the patch (ie it is not universal). For example this post: ‘Re: [RFC/RFT PATCH v3] sched: automated per tty task groups’ - MARC](http://marc.info/?l=linux-kernel&m=128986481501325&w=2) which notes:

Yes, all tasks never having had a tty association are relegated to the
root task group, and no, there is no provision for the root task group
getting more than it’s fair share of CPU.