본문 바로가기
IT 기술/리눅스 커널

kjournald 에 IPPRIO_CLASS_RT 권한 부여

by 땅뚱 2010. 5. 3.
latencytop 이라는 유틸리티를 알아보다가 찾은 메일링리스트 내용이다.

http://kerneltrap.org/mailarchive/linux-kernel/2007/10/15/343499

latecytop 과 완전히 연관된 내용은 아니지만, 간단하게 소개해보면, 인텔에 근무하는 (latencytop 이라는 유틸리티는 인텔에서 만들었다) Arjan van de Ven 이라는 친구가 latencytop 을 사용해서 검사해본 결과 커널을 build 하는데 atime update 하는데 600msec 이상의 latency 가 발생했다는 것이다. 그 외에도 ext3 journal 관련 연산이 유사하거나 더 높은 latency 를 나타냈다는 것이다.

좀 더 분석해본 결과 EXT3 와 IO scheduler 인 CFQ 사이의 interaction 때문인 것으로 보이는데, 이것은 kjournald 라는 데몬(ext3 에서 journal 을 담당하는 데몬)을 포함하여 CFQ 가 너무 fair 하게 다룬다는 것이라고 주장한다. 실제로 kjournald 는 journal을 기록하느라 많은 작업을 수행하는 "특별한" 존재이고, 이것이 "mass priority inversion" 현상을 유발시킨다는 것이다.

이에 CFQ 에서 제공하는 기능을 kjournald 에 적용해서 priority inversion 현상을 해결했다는 얘기이다. 패치는 아래와 같다.

diff -purN linux-2.6.23-rc9.org/fs/jbd/journal.c linux-2.6.23-rc9.lt/fs/jbd/journal.c
--- linux-2.6.23-rc9.org/fs/jbd/journal.c 2007-10-02 05:24:52.000000000 +0200
+++ linux-2.6.23-rc9.lt/fs/jbd/journal.c 2007-10-14 00:06:55.000000000 +0200
@@ -35,6 +35,7 @@
#include <linux/kthread.h>
#include <linux/poison.h>
#include <linux/proc_fs.h>
+#include <linux/ioprio.h>

#include <asm/uaccess.h>
#include <asm/page.h>
@@ -131,6 +132,8 @@ static int kjournald(void *arg)
printk(KERN_INFO "kjournald starting. Commit interval %ld seconds\n",
journal->j_commit_interval / HZ);

+ current->ioprio = (IOPRIO_CLASS_RT << IOPRIO_CLASS_SHIFT) | 4;
+
/*
* And now, wait forever for commit wakeup events.
*/
-

이것에 앤드류 모튼(Andrew Morton) 과 잉고 몰나르(Ingo Molnar) 라 서로 의견을 주고 받은 내용이다. 앤드류는 이러한 패치가 다른 것에 영향을 주기때문에 부정적인 반면, 잉고는 리눅스 개발이 latency 에 대한 focus 가 부족했다며 bandwidth 에 대한 내용에 집중되어있다고 얘기하고 되돌리기 어려운 패치도 아닌데 문제가 생기면 undo 해버리면 된다는 입장을 밝히면서 논쟁하다가 결국 앤드류가 개발자가 더 테스트하도록 놔두자고 결론.

아래는 latencytop 으로 측정했던 결과를 보여준다.

Here's some output of LatencyTOP, collected for a make -j4 of a kernel 
on a quad core system:

Cause Maximum Average
process fork 1097.7 msec 2.5 msec
Reading from file 1097.0 msec 0.1 msec
updating atime 850.4 msec 60.1 msec
Locking buffer head 433.1 msec 94.3 msec
Writing to file 381.8 msec 0.6 msec
Synchronous bufferhead read 318.5 msec 16.3 msec
Waiting for buffer IO 298.8 msec 7.8 msec


This shows that during the kernel build, one fork() system call had
a > 1 second latency, as did a read from a file. Updating the atime
of a file (in memory!) had 850 milliseconds, etc etc.

With a small change to the EXT3 journaling layer to fix a priority
inversion problem that was found with LatencyTOP the following results
for the exact same test were achieved [*]
( http://kerneltrap.org/mailarchive/linux-kernel/2007/10/15/343499 )

Cause Maximum Average
Writing to file 814.9 msec 0.8 msec
Reading from file 441.1 msec 0.1 msec
Waiting for buffer IO 419.0 msec 3.4 msec
Locking buffer head 360.5 msec 75.7 msec
Unlinking file 292.7 msec 5.9 msec
EXT3 (jbd) do_get_write_access 274.0 msec 36.0 msec
Filename lookup 260.0 msec 0.5 msec

이 논의가 있던 시점이 2007년 10월 이었고, 현재 커널 코드(2.6.31) 을 뒤져본 결과 해당 패치가 없는 것으로 봐서 저 문제는 없었던 것으로 된 것으로 보인다.

적용되지도 않은 이 내용을 블로그에 기록하는 이유는 latencytop 을 어떤 식으로 이용했는지에 대한 예제와 함께, 향후 io 관련 성능을 낼때, RT class 관련된 priority 로 테스트해보는 것도 괜찮을 것 같기때문이다. 리눅스 커널은 general 해야 하기 때문에 mailline 에는 포함되지 않았지만, 임베디드 환경에서는 충분히 적용해서 테스트해 볼 만한 패치라고 생각한다.

참고로 latencytop 관련 패치 코드는 이미 커널에 포함되어 있다.