마술같은 성능 향상 패치 :)

sandy의 이미지

요 며칠간 마술같은 성능향상을 보여주는 리눅스 커널 패치(200자 정도)가
화제인데요.

https://patchwork.kernel.org/patch/326472/

2.6.38 커널에 포함이 예정되어 있습니다.

과연 성능향상이 있을까 ? 호기심에 방금 git 최신 커널 소스에
이 패치 적용하고 들어와보니 펜티엄 4 2,0 기가 제 구닥다리 데스크탑이
씽씽 날아 다니고 그간 안돌던 고화질 동영상 마저 이제 돌아가는군요.

이거 진짜 물건이네요. 커널패치 아닌 편법으로 같은 효과를 보게하는 팁이 나올정도 ㅋㅋ

^_^[/media/sdc6]$ uname -a
Linux s4ndy 2.6.37-rc2-s4ndy-r4+ #1 Sun Nov 21 01:35:21 KST 2010 i686 GNU/Linux
^_^[/media/sdc6]$

추가///

하 이 패치 적용 전후의 변화가 각자가 가진 하드웨어 성능에 따라
그다지 별로 변화가 없다고 느끼실 수도 있지만 뭐 제 펜티엄 4 2 기가의 경우는
비약적인 성능 향상 임에 분명합니다.

직접 커널 패치를 해보실분을 위해 팁을 알려드리자면

일단 소스를 받고

git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git linux-2.6

문제의 그 패치도 받습니다.

wget -O RFC-RFT-v3-sched-automated-per-tty-task-groups.patch https://patchwork.kernel.org/patch/326472/raw/

이제 패치를 적용해주면 되는데
다른 부분은 문제 없지만 kernel/sched.c는 최신 git소스가 이 패치 만든분의 커널과 달라진게 있어
적용이 안될테니 직접 손으로 적용하세요.

그리고 에러가 안나도록 커널 컴파일 전에 이 두 부분을 더 고쳐 주시고

--- drivers/eisa/pci_eisa.c
+++ drivers/eisa/pci_eisa.c
@@ -51,7 +51,7 @@ static struct pci_device_id pci_eisa_pci_tbl[] = {
 	{ 0, }
 };
 
-static struct pci_driver pci_eisa_driver = {
+static struct pci_driver pci_eisa_driver __initdata = {
 	.name		= "pci_eisa",
 	.id_table	= pci_eisa_pci_tbl,
 	.probe		= pci_eisa_init,
 
 
--- include/acpi/video.h
+++ include/acpi/video.h
@@ -1,6 +1,10 @@ 
 #ifndef __ACPI_VIDEO_H
 #define __ACPI_VIDEO_H
 
+#include <linux/errno.h>
+
+struct acpi_device;
+
 #define ACPI_VIDEO_DISPLAY_CRT  1
 #define ACPI_VIDEO_DISPLAY_TV   2
 #define ACPI_VIDEO_DISPLAY_DVI  3

이 패치를 위해 제 커널의 경우 추가해줬던 커널 .config 내용입니다.

/boot/config-2.6.37-rc2-s4ndy-r4+:CONFIG_CGROUPS=y
/boot/config-2.6.37-rc2-s4ndy-r4+:CONFIG_CGROUP_DEBUG=y
/boot/config-2.6.37-rc2-s4ndy-r4+:CONFIG_CGROUP_NS=y
/boot/config-2.6.37-rc2-s4ndy-r4+:CONFIG_CGROUP_FREEZER=y
/boot/config-2.6.37-rc2-s4ndy-r4+:CONFIG_CGROUP_DEVICE=y
/boot/config-2.6.37-rc2-s4ndy-r4+:CONFIG_CGROUP_CPUACCT=y
/boot/config-2.6.37-rc2-s4ndy-r4+:CONFIG_CGROUP_MEM_RES_CTLR=y
/boot/config-2.6.37-rc2-s4ndy-r4+:CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y
/boot/config-2.6.37-rc2-s4ndy-r4+:CONFIG_CGROUP_SCHED=y
/boot/config-2.6.37-rc2-s4ndy-r4+:CONFIG_BLK_CGROUP=y
/boot/config-2.6.37-rc2-s4ndy-r4+:CONFIG_SCHED_AUTOGROUP=y

맨마지막 옵션(CONFIG_SCHED_AUTOGROUP)이 핵심입니다.

자 이제 커널 컴파일 해주고

재부팅하면 완료.물론 부팅시 이 패치 적용할건가 말건가 옵션(noautogroup)을 줄수도 있고
부팅후 조절할수도 있습니다.

$ ls -al /proc/sys/kernel/sched_autogroup_enabled
-rw-r--r-- 1 root root 0 2010-11-21 19:50 /proc/sys/kernel/sched_autogroup_enabled
$ more /proc/sys/kernel/sched_autogroup_enabled
1

1로나오면 적용이 된겁니다.적용을 끌려면

$ echo 0 > /proc/sys/kernel/sched_autogroup_enabled

뭐 심한부하가 걸리는 상황에선 효과가 있지만 일반적인 부하에는 성능저하가 생길수 있다는
논의와는 달리 패치 적용후 하루 정도 사용한(거의 부하가 없는 평범한 사용 :)결과 성능저하는 없었고
눈에 띄게 좋아진게 느껴집니다.

카二리의 이미지

영어실력이 딸려서 당장 뭔소린지 모르겠지만, 굉장히 기대 되는군요.
어떤 방식인지 궁금합니다. 이게 모바일에서도 적용 될 수 있으면 좋을꺼 같군요

새 생각 :)

MasterQ의 이미지

"커널패치 아닌 편법으로 같은 효과를 보게하는 팁이 나올정도 ㅋㅋ"

가 아니라 이것때문에 많은 논쟁이 있는것 같군요. 기본적으로 이 패치가 할수 있는것은 userspace에서도 cgroup을 이용해서 할수 있는데 왜 굳이 커널패치를 이용해야 하냐와 userspace보다 커널에 적용하는게 더 많은 유저들에게 도움이 된다고 주장하고 있는것 같습니다.

개인적으로는 kernal patch가 더 적절해 보이지만 userspace approach보다 더 낫다고 모두가 납득할 이유도 딱히 없습니다. 사실 회사에서도 이런 경우가 많이 있고 이런것으로 싸움을 걸어오기도 하지만 대부분 어느것이 다른 어느것보다 낫다라고 딱히 얘기할수 없는 경우는 목소리가 크거나 좀더 파워가 있는쪽이 이기는 경우가 많은것 같습니다. Linus도 비슷한 느낌으로 주도해 나가려고 하지만 Linus의 argument가 그렇게 강해보이지는 않는군요.

근데 이 패치는 터미널 유저에게 해당이 되는것 같아보이는데 sandy님도 터미널에서 어플리케이션을 띄우는것인가요?

stypr의 이미지

TTY 에 적용된다는 것은 터미널에서 어플리케이션을 뛰우는 유저만 해당되는 것이 아니라 TTY layer 을 사용하는 모든 어플리케이션에 해당되는 것으로 생각됩니다.

TTY layer 을 사용한다는 것은 99% desktop 유틸리티 (gnome 등등) 을 커버할 듯 합니다.

JuEUS-U의 이미지

약간 이해가 안갑니다.
각 tty마다 하나의 cgroup을 하나씩 생성하는게 패치의 내용이 아닌가요?
그 뒤로 거기서 나오는 child process는 전부 이를 상속받는걸로 이해했는데요.
혹시 desktop utility에서 내부적으로 tty를 하나씩 할당받나요? - .-)??

stypr의 이미지

TTY layer 내부에 대한 자세한 내용은 사실 저도 모릅니다. linux kernel 쪽은 특히 잼병이구요. ㅡㅡ;; 여튼 제 지극히 개인적인 상식으로는 init -> getty -> console -> X server -> gnome (KDE) -> desktop utility 로 이어지는 라인으로 봤을 때는 이미 대부분의 Desktop 유틸리티가 특정 control group (저에게는 굉장히 낯선...) 에 속해져 있을 가능성이 있다는 겁니다. (이번 패치로 인해 tty 에서 물려받든 아니든). 즉 패치 적용 후 부팅 init 단계가 넘어간 이후로는 X server 이하 모든 프로그램이 저 패치 영향 하에 있다는 것을 말하고 싶었을 뿐이구요.

당연히 일반적으로는 tty 를 desktop utility 마다 할당하지는 않을 꺼구요. (물론 개발자 구현 나름입니다만..)

JuEUS-U의 이미지

제가 이해한 바로는
기본적으로 tty1~N (콘솔)마다 그룹 하나씩, desktop environment에 하나, 가상 터미널마다 하나씩,
이렇게 cgroup이 배정되어서 CFS의 fair group scheduling을 활용하겠다는 이야기인 것 같습니다.
따라서 무턱대고 프로그램을 켠다고 효과를 보는게 아니라
phoronix에서 실험한 것처럼 터미널을 띄워서 작업을 할 때에 효과가 있다는게 제가 이해한 모습입니다.
아무리 터미널에서 커널을 컴파일해도
gdm cgroup하고 terminal cgroup 사이에서 밸런싱 이뤄지기 때문에
궁극적으로 desktop experience에는 큰 영향을 끼치지 않는다...라고 생각합니다.

물론 내부적으로 tty를 할당한다면 이야기가 또 달라지겠죠.

stypr의 이미지

커널 내부 입장에서는 tty1 ~ N 이든, desktop environment 든 tty 에 대한 구분을 스스로 알지 못하는게 당연합니다. 굉장히 generic 하게 구현이 되고 또 그렇게 되어야 하거든요. 즉 gdm 에서 뜬 프로그램이든, getty 에서 뜬 프로그래든, gnome 에서 뜬 프로그램이든 프로세스 구조체에 tty 가 세팅되는 순간 이미 저 패치에 영향 아래에 있다는 겁니다. 일반적인 유저가 일반적인 프로그램을 실행했을 때 그 프로그램이 "효과"를 본다는 뜻이 아니라 "영향"을 받는다는게 하고 싶었던 말입니다.

제가 말하고자 하는 것은 desktop experience 에 대한 것은 아니구요.

JuEUS-U의 이미지

쩝;;; 그래서 제 말이 맞는지가 궁금하단겁니다 [...]
test님이 아니더라도 다른 분이 어떻게 속시원한 설명을 달아주시면 좋겠습니다만 ㅡ.ㅡ)

stypr의 이미지

저도 제대로 잘 알지 못하지만 JuEUS-U 님의 설명이 틀려보이지는 않습니다. 리눅스 메일링 리스트를 봤을 때는 ata (ahci) 쪽이나 serial driver 쪽에선 몇몇 한국분들을 보았지만 tty 나 scheduler 쪽은 본적이 거의 없어 보이네요.

JuEUS-U 님께서 직접 한번 maintainer 에 도전을 해 보심이. :-) 기대하고 있겠습니다. ㅋ

ifree의 이미지

이 커널 패치는 심한 로드가 걸린 경우에도 interactivity 가 저하되지 않는다는 이야기 같은데,
sandy 님의 경우, 안돌던 고화질 동영상이 돌아간다는 건 어떻게 이해해야 되나요.

rogon3의 이미지

이미 보셨겠지만, 외국 인터넷 기사들도,
리누즈 토발즈 마저도 패치를 적용시켜보고 나서 프로그램 성능과는 무관해야 정상으로 보이는 패치의 효과가 실제로는 웹페이지 로딩 속도를 크게 향상시키는 경험을 하고 놀라워 하고 있다는, 패치 제작자에게 보낸 이메일 응답을 인용하더군요

어찌됐든 조금 과장해서 mmx 급 노트북에서 mp3를 들으며 firefox 탭 열댓개 띄우고도 음악감상이나 웹서핑에 버벅임이 없게 된다면...

*******************************
데비안과 세벌식 사용자입니다

*************************************

Scarecrow의 이미지

phoronix 기사에서 패치 적용 전후의 비교를 볼 수 있군요.

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

ifree의 이미지

오늘자 젠투 커널 2.6.36-r2 에 tty 별로 태스크 그룹을 만들어 주는 패치가 들어갔네요,

http://packages.gentoo.org/package/sys-kernel/gentoo-sources

ifree의 이미지

2.6.36-r2 는 망한 버전.

새로 나온 2.6.36-r3 는 대박.

3D 툴인 후디니를 돌려 보니,
렌더링 중에도 뷰포트가 자유롭게 전혀 버벅임없이 움직입니다.
윈도우즈보다도 훨씬 부드러운 듯.

rogon3의 이미지

펜4 2.0에서 1080p 가 돌아간다는 말씀인가요?

그렇다면, 펜3 700 노트북에서 720p 가 가능할지도 ...

편법은 어디서 찾을 수 있나요

*******************************
데비안과 세벌식 사용자입니다

*************************************

rogon3의 이미지

고맙습니다.

커널 제한이 있는지, 데비안 2.6.26-2 에서는 안됩니다

첫번째방법도, 두번째 우분투 방법도 오류가 발생하는군요

스펠링이 틀렸는지 지나친게 있는지, 복기해보는 중 입니다

*******************************
데비안과 세벌식 사용자입니다

*************************************

feanor의 이미지

커널 config를 확인해 보세요.

$ grep CGROUP /boot/config-*

rogon3의 이미지

고맙습니다.

CONFIG_CGROUPS=y
# CONFIG_CGROUP_DEBUG is not set
CONFIG_CGROUP_NS=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_SCHED=y
CONFIG_CGROUP_CPUACCT=y

우분투 방식이 데비안과 좀 다른 듯 해서 약간 수정해서 적용했습니다.

720p 샘플 동영상이 앞에서 싱크가 약간 어긋나고 뒤에서는 정상재생 됩니다.

위에서 제 경우 둘째 줄이 문제인건가요?

p.s. 이리저리 바꿔봐도 적용된게 아닌 듯 변화가 없음.

커널 업그레이드 하느니, 이번 기회에 젠투로 바꿀까 싶네요

*******************************
데비안과 세벌식 사용자입니다

*************************************

bluesky.big의 이미지

지금 현재는 편법(?)이 커널 패치보다 성능이 더 좋다고 되어있네요.
일단 저는 편법(?)으로 패치했습니다.
괜찮은데요. ^^;;

rogon3의 이미지

데비안 유저 포럼은 패치에 대해 상당히 비판적이네요

*******************************
데비안과 세벌식 사용자입니다

*************************************

drinkme의 이미지

딴 얘기지만,
팬티엄4 2.0기가에서 고화질 동영상이 안돌아가나요?

제 펜티엄3(셀러론) XP 머신에서는 고화질 동영상이 잘 나오던데....

danskesb의 이미지

단순히 고화질이라고만 하면 비트레이트가 높아서 고화질인지, 해상도가 높아서 고화질인지 알 수 없습니다. 지금까지의 댓글을 보니 720p/1080p를 이야기하는 것 같네요. 1080p는 코어 2 듀오로도 버벅일 때가 있습니다.

rogon3의 이미지

720p의 사전적의미는 검색하시면 많이 나옵니다.

위에서 제가 적은 720p는 확장자가 mkv이며 동영상 하나의 크기가 최소 4.3GB 이상인 동영상입니다

요즘은 쿼드코어가 난무하는 무서운 세상이라 동영상 코덱 소스가 xvid 나 divx인 것들에 대해서는 고화질 동영상이라고 하지 않습니다.

그나저나 편법이 기존 커널을 수정하는 것도 아닌듯 한데 2.6.26 에서 왜 적용이 안되는지 모르겠네요

혹시 커널 2.6.36 아래 버전, 특히 2.6.32 아래 커널에서 효과를 보신 분 있나요?

*******************************
데비안과 세벌식 사용자입니다

*************************************

danskesb의 이미지

데비안 커널 2.6.32에서 userspace로 적용시켜 본 결과, 적용 전에는 '하드웨어 가속을 켜도 에러를 내뱉으며 끊기는 5번에 1번 겨우 성공하는' 1080p 동영상이 재생되는 확률이 조금 높아졌습니다.

rogon3의 이미지

위에 링크된 “편법” 에 반나절 만에 댓글이 엄청나게 달렸더군요

이리저리 읽어보니 역시 커널버전이 낮아도 가능할 듯 해서 다시 시도했습니다.

데비안유저포럼에는, 워낙 고사양을 쓰는지라 몰랐는데 하루 지나니 그 전과 달리 반응속도가 빨라졌음을 체감했다는 글과 동영상도 있고해서 저도 하루는 묵혀보려고 합니다 ㅡ.ㅡ

xp에서 팟플레이어로 문제없이 재생되는 720p 영상이 리눅스에서 초반에 10초 정도씩이나 버벅거리는건 이상하다고 생각하기에 꼭 적용이 되기를 바라고 있습니다.

사실 버벅일때도 cpu나 램이 남는 상황인걸 보면, mplayer 보다 팟플레이어가 잘 만들어진 재생기여서인지, 리눅스 탓을 해야할지 여전히 궁금하기도 합니다.

*******************************
데비안과 세벌식 사용자입니다

*************************************

dorado2의 이미지


LWN 구독자분들은 다 보셨겠지만, http://lwn.net/Articles/415740/ 내용을 보시는게 이해에 더 도움이 되실 것 같습니다.
구독 안 하신 분들은 며칠 더 기다리셨다 보셔야...

Linus가 이 패치에 대해 꽤나 우호적이기 때문에, userspace approach보다 2.6.38 버전에 포함될 가능성이 높긴 하지만,
논쟁의 소지는 아직 많이 남아있네요.

VFS scaling patch 역시 2.6.38에서 제가 기대하고 있는 내용입니다.

rogon3의 이미지

음... 날림으로 커널 컴파일을 해놔서 기억도 없지만, config 파일을 봤더니 2.6.26 에는 CONFIG_SCHED_AUTOGROUP 은 물론 몇몇 항목이 아예 없는 듯 합니다.

sandy님의 첫번째 링크에 오늘 새로운 패치가 올라왔는데, 내용을 이해할 수 없습니다.

2.6.x 에 대한 여러버전의(또는 포괄적인) 패치인 듯 한데, 암호처럼 보이네요

Index: linux-2.6/include/linux/sched.h
===================================================================
--- linux-2.6.orig/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.orig/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
Index: linux-2.6/kernel/fork.c
===================================================================
--- linux-2.6.orig/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.orig/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,16 @@ 
+#ifdef CONFIG_SCHED_AUTOGROUP
+
+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,150 @@ 
+#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 bool
+task_wants_autogroup(struct task_struct *p, struct task_group *tg)
+{
+	if (tg != &root_task_group)
+		return false;
+
+	if (p->sched_class != &fair_sched_class)
+		return false;
+
+	if (p->flags & PF_EXITING)
+		return false;
+
+	return true;
+}
+
+static inline struct task_group *
+autogroup_task_group(struct task_struct *p, struct task_group *tg)
+{
+	int enabled = ACCESS_ONCE(sysctl_sched_autogroup_enabled);
+
+	if (enabled && task_wants_autogroup(p, tg))
+		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;
+
+	prev = p->signal->autogroup;
+	if (prev == ag)
+		return;
+
+	p->signal->autogroup = autogroup_kref_get(ag);
+	sched_move_task(p);
+
+	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);
+}
+
+/* Must be called with siglock held */
+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);
+
+/* Must be called with siglock held.  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)
+{
+	struct sighand_struct *sighand = current->sighand;
+
+	spin_lock(&sighand->siglock);
+	sig->autogroup = autogroup_kref_get(current->signal->autogroup);
+	spin_unlock(&sighand->siglock);
+}
+
+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.orig/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.orig/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.orig/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.
 

*******************************
데비안과 세벌식 사용자입니다

*************************************

pastime의 이미지

올려주신 이 패치에서 CONFIG_SCHED_AUTOGROUP 항목을 추가한 것입니다. ^^

rogon3의 이미지

주어, 보어가 불명확하지만, 제가 바라던 건 아니라는 뜻이로군요 ㅡ.ㅡ;

고맙습니다.

*******************************
데비안과 세벌식 사용자입니다

*************************************

sandy의 이미지

오해를 하신듯 . 오늘 새로 올라온게 아니고 댓글이 최근것이 아래 달리고 실제 패치는 그 맨아래 있다보니
오늘 올라온것 처럼 느끼신것 같네요. 올리신 그게 원래 그패치입니다.

..

rogon3의 이미지

네, 뭔가 이상하다고는 짐작했지만서도... ㅋ;

편법이라는 링크의 방법은 실질적으로는 2.6.36 을 위한 방법인 것 같습니다.

*******************************
데비안과 세벌식 사용자입니다

*************************************

rogon3의 이미지

데비안 유저 포럼에 liquorix 라는 이번 패치가 더해진, 멀티미디어와 게임에 최적화 되었다는 비공식인듯한 배포본이 있네요

윈도그도 아니고 데비안에 이런 버전이 다 있다니...

http://forums.debian.net/viewtopic.php?f=16&t=45151&hilit=liquorix

제 경우에는 설치했다가 부팅이 안되는 문제로 원위치.

삭제는 깔끔하고 쉽게 가능했습니다.

sudo apt-get remove '.*liquorix'

gcc-4.4 버전 이상, 기억나지 않는 라이브러리가 설치되어 있어야 의존성 문제 생기지 않습니다.

p.s. unstable 수준인 듯, 좋다는 글 보다 딴지글이 더 많습니다.

*******************************
데비안과 세벌식 사용자입니다

*************************************

galien의 이미지

오오.. 간만에 불타오를 것이 생겼네요.

hbell의 이미지

눈물이 쥬르륵 ㅠㅠ

--------------------------------
옵져빙만 하다가 이번에 가입한 hbell입니닷 x.x;;