January 2008

あやしげなメッセージとともにダンマリしてしまう。
ショボーン(´・ω・`)

sc420 login: SysRq : Trigger a crashdump
Memory for crash kernel (0x0 to 0x0) notwithin permissible range
PCI: BIOS Bug: MCFG area at e0000000 is not E820-reserved
PCI: Not using MMCONFIG.
ACPI: Getting cpuindex for acpiid 0x2
Mounting proc filesystem
Mounting sysfs filesys


ブートパラメタに書いたcrashkernel=128M@16M オプションが正しく認識されていることは
/proc/iomemにて確認済みだし。
おなじく、/proc/iomemにてe0000000 がreservedであることは確認できてるんだけど・・・

むむむ・・・

LKMLの [RFC] Parallelize IO for e2fsck なるスレッドでmem_notify に言及されてたらしいんだけど、ccされてなかったので、まったく気づかなかったよ。

mel にたのまれたtestをするために、近くのパソコンショップでシリアルのクロスケーブルを買ってきた。こんなん買うの10年ぶりかもしれん。
Linuxで起動時にパニックしちゃう場合シリアルケーブルつなげておかないとデバッグがほぼ不可能なのだよ。
で、帰ってみると衝撃の事実が!!
ぼくちんのWindowsマシンにはなんとシリアルポートがなかった。イマドキのWindowsってそうなのねwwww
しょうがないから、取って返してUSB - シリアル変換機も買ってきた。バカス。
てゆーか、ちょっとした善意で6千円も飛んでいくのは若干納得行かないような。むむ。

で、Linux側の設定なのだが/boot/grub/grub.confの以下の箇所を変更すればOK


default=3
timeout=5
#splashimage=(hd0,0)/grub/splash.xpm.gz
serial --unit=0 --speed=9600 --word=8 --parity=no --stop=1
terminal --timeout=10 serial console

hiddenmenu
title CentOS (2.6.18-53.1.4.el5PAE)
root (hd0,0)
kernel /vmlinuz-2.6.18-53.1.4.el5PAE ro root=/dev/VolGroup00/LogVol00 rhgb quiet
initrd /initrd-2.6.18-53.1.4.el5PAE.img

title kosatest
root (hd0,0)
kernel /vmlinuz-kosatest ro root=/dev/VolGroup00/LogVol00 rhgb quiet console=tty0 console=ttyS0,9600n8r
initrd /initrd-kosatest.img



参考URL
JF文書 :http://www.linux.or.jp/JF/JFdocs/Remote-Serial-Console-HOWTO/index.html
ITメディア: http://www.itmedia.co.jp/help/tips/linux/l0617.html
第3のペンギン: http://blog.miraclelinux.com/thethird/2007/02/linux_fb95.html
USBをシリアルコンソールに: http://www.irori.org/doc/usb-console.html

どうもあまり有名ではないらしいので、ここで書いてみる。

http://mkosaki.blog46.fc2.com/blog-entry-241.html
で書いた事とほぼ同じだけれど。

Linuxにおいて、CPU負荷を測定するベンチマークでは以下の環境変数を設定すると往々にして性能があがる。

% setenv MALLOC_TRIM_THRESHOLD_ -1
% setenv MALLOC_MMAP_MAX_ 0

MALLOC_TRIM_THRESHOLD_ はOSに未使用になったメモリを返却する契機をあらわしていて、-1は決して返却しない事を表す。
MALLOC_MMAP_MAX_ は最大mmap数で0は決してmmapせず、どんなに大きなメモリでもbrkを使ってメモリを取る事を意味する。

で、性能に効くのは(たいてい)MALLOC_MMAP_MAX_のほう。
glibcはアンチフラグメンテーションの観点から一定以上(たしかデフォルト1M)の大きさのmallocは内部で直接mmap呼び出しをするように変換される。
で、これがある種の状況下では、2重の意味で悪い効果をもたらす。

1.キャッシュコンフリクト
  まあ、実装がへこいのですがmmap呼び出すときにキャッシュカラーリングのコードが
  はいってないんです。
  なので、戻り値アドレスが全部ページバウンダリにそろってしまっています。
  なので複数スレッドがmalloc復帰値を同じようなアクセスパターンでアクセスしていくと
  がんがんキャッシュコンフリクトします。

2.munmapネック
  mmapしたやつはbrkでとったやつと違い、フリーリスト管理はせずに、アプリがfree(3)を
  呼んだら、すぐさまOSにmunmapする実装になっています。
  で、特に大規模SMPにおいて、munmapはmmapと違ってlazyに処理できないので、
  非常にコストが高い操作である。と
  大抵のアーキで全CPUに割り込みとばして空間そぎ落として返事がくるのをじっと
  まっているので。
  かつ、Linuxにおいてドライバが数ミリ秒ぐらい割禁とかするのはめずらしくないので、
  一番遅いCPUに引っ張られてますます遅くなる。

もちろん、この環境変数を設定するとヒープフラグメンテーションが進みやすくなるので365日動き続ける業務アプリで設定するものは考え物であるが、ベンチマークの数字的には結構効果があるので、ベンチマーク屋さんは、オマジナイ代わりに試してみる価値はある。





こまったときのおまじない
おまじない代わり! ランキング!

Andrew Morton先生にそんなルートは絶対に通らないと言われたので、

   うるへー、いいからやってみろ

と返信してしまった。
もうちょっと言葉遣いを考えましょう。反省。

quiltの結果のdiffstatがおかしいと思っていたら .quiltrcがスペルミスってた。
おかげでLKMLで恥をかいたわい (馬゚∀゚鹿)♪

わりと小さくてmmap copyがちゃんと高速化できるパッチができたような気がする

                  2.6.24-rc6  +my patch   ratio
     -------------------------------------------------
     rw_cp          59.32      58.60     98.79%
     rw_fadv_cp       57.96      57.96     100.0%
     mm_sync_cp      69.97      61.68     88.15%
     mm_sync_madv_cp  69.41      62.54     90.10%
     mw_cp          61.69      63.11     102.30%
     mw_madv_cp      61.35      61.31     99.93%

ratioが100以下が高速化である。
勝手な理屈だが10%程度以上の高速化をsignificantと定義している。


パッチの説明だが、メモリが不足したときのページ回収論理においてaccessed bitが立っていたページを残し、それ以外を捨てる。という論理があるのだが、そこに

・周辺のページがずっと、accessed bitが立ち続けていたらmmaped copy中とみなしてaccessed bitを無視する

という論理がいれてある。
本格的にやるにはpage->flagsにフラグビットを追加しないといけないが、Linuxにおいてそれはフレームの元なので、強引に避けてある。

来週ぐらいにlinux-mmに投げてみるべ


---
mm/vmscan.c | 46 +++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 43 insertions(+), 3 deletions(-)

Index: linux-2.6.24-rc6-cp3/mm/vmscan.c
===================================================================
--- linux-2.6.24-rc6-cp3.orig/mm/vmscan.c 2008-01-13 21:58:03.000000000 +0900
+++ linux-2.6.24-rc6-cp3/mm/vmscan.c 2008-01-13 22:30:27.000000000 +0900
@@ -446,13 +446,18 @@ static unsigned long shrink_page_list(st
struct pagevec freed_pvec;
int pgactivate = 0;
unsigned long nr_reclaimed = 0;
+ unsigned long nr_scanned = 0;
+ LIST_HEAD(l_mapped_pages);
+ unsigned long nr_mapped_page_activate = 0;
+ struct page *page;
+ int reference_checked = 0;

cond_resched();

pagevec_init(&freed_pvec, 1);
+retry:
while (!list_empty(page_list)) {
struct address_space *mapping;
- struct page *page;
int may_enter_fs;
int referenced;
@@ -466,6 +471,7 @@ static unsigned long shrink_page_list(st

VM_BUG_ON(PageActive(page));

+ nr_scanned++;
sc->nr_scanned++;

if (!sc->may_swap && page_mapped(page))
@@ -493,11 +499,17 @@ static unsigned long shrink_page_list(st
goto keep_locked;
}

- referenced = page_referenced(page, 1);
- /* In active use or really unfreeable? Activate it. */
- if (sc->order <= PAGE_ALLOC_COSTLY_ORDER &&
- referenced && page_mapping_inuse(page))
- goto activate_locked;
+ if (!reference_checked) {
+ referenced = page_referenced(page, 1);
+ /* In active use or really unfreeable? Activate it. */
+ if (sc->order <= PAGE_ALLOC_COSTLY_ORDER &&
+ referenced && page_mapping_inuse(page)) {
+ nr_mapped_page_activate++;
+ unlock_page(page);
+ list_add(&page->lru, &l_mapped_pages);
+ continue;
+ }
+ }

#ifdef CONFIG_SWAP
/*
@@ -604,7 +616,31 @@ keep:
list_add(&page->lru, &ret_pages);
VM_BUG_ON(PageLRU(page));
}
+
+ if (nr_scanned == nr_mapped_page_activate) {
+ /* may be under copy by mmap.
+ ignore reference flag. */
+ reference_checked = 1;
+ list_splice(&l_mapped_pages, page_list);
+ goto retry;
+ } else {
+ /* move active list just now */
+ while (!list_empty(&l_mapped_pages)) {
+ page = lru_to_page(&l_mapped_pages);
+ list_del(&page->lru);
+ prefetchw_prev_lru_page(page, &l_mapped_pages, flags);
+
+ if (!TestSetPageLocked(page)) {
+ SetPageActive(page);
+ pgactivate++;
+ unlock_page(page);
+ }
+ list_add(&page->lru, &ret_pages);
+ }
+ }
+
list_splice(&ret_pages, page_list);
+
if (pagevec_count(&freed_pvec))
__pagevec_release_nonlru(&freed_pvec);
count_vm_events(PGACTIVATE, pgactivate);




見せてくれるの!
パッチぐらいいくらでも見せますがな

↑このページのトップヘ