2008年5月6日火曜日

古いパソコン、FreeBSD 7.0Rにしたら、topのCPU states行が、全部「0.0%」 ~ (2) とりあえず解決

前回の話。





CPUがAMD Athlon 800MHzという古い自作パソコンにFreeBSD 7.0-RELEASEをインストールしたら、なぜか、topのCPU statesという行の値が、全部0.0%になっていて、vmstatのCPU使用率も0、というおかしなことが起きました。



まず、カーネルのバグを疑って、試行錯誤してみました。



  • 4月のsnapshot版のカーネルを使っても、0.0%のまま。vmstat -iでみたとき、rtcのrateは0。


  • cvsup (csup)で、最新の7-STABLEのカーネルソースコードを取得して、カーネル再構築してみたけど、0.0%のまま。vmstat -iでみたとき、rtcのrateは0。


  • 6-STABLEのカーネルで起動すると、正しそうな値が表示された。vmstat -iでみたとき、rtcのrateは127。


というわけで、6系と7系の間に入った変更で、0.0%になる原因が入っているはず。



rtcはソースコードでどのあたりかな?とラフにgrepしてみると、/sys/i386/isa/clock.cが主に該当しそう。



6-STABLEと7-STABLEとで、clock.cの差分を眺めていて、rtcin()とwritertc()が、なんとなくあやしいと思い、6-STABLE相当のコードに戻して、カーネル再構築。



/*
* RTC support routines
*/



int
rtcin(reg)
        int reg;
{
#if 1
  /*6-STABLE*/
        u_char val;



        RTC_LOCK;
        outb(IO_RTC, reg);
        rtc_reg = reg; /* +++ */
        inb(0x84);
        val = inb(IO_RTC + 1);
        inb(0x84);
        RTC_UNLOCK;
        return (val);
#else
  /*7-STABLE*/
        u_char val;



        RTC_LOCK;
        if (rtc_reg != reg) {
                inb(0x84);
                outb(IO_RTC, reg);
                rtc_reg = reg;
                inb(0x84);
        }
        val = inb(IO_RTC + 1);
        RTC_UNLOCK;
        return (val);
#endif
}



void
writertc(int reg, u_char val)
{
#if 1
        RTC_LOCK;
        inb(0x84);
        outb(IO_RTC, reg);
                rtc_reg = reg;
        inb(0x84);
        outb(IO_RTC + 1, val);
        inb(0x84);              /* XXX work around wrong order in rtcin() */
        RTC_UNLOCK;
#else
        RTC_LOCK;
        if (rtc_reg != reg) {
                inb(0x84);
                outb(IO_RTC, reg);
                rtc_reg = reg;
               inb(0x84);
        }
        outb(IO_RTC + 1, val);
        inb(0x84);
        RTC_UNLOCK;
#endif
}



これで起動してみると・・・直りました。



% vmstat -i
interrupt                          total       rate
irq0: clk                          79523         99
irq1: atkbd0                         218          0
irq6: fdc0                             2          0
irq7: ppbus0 ppc0                      1          0
irq8: rtc                         101780        127
irq9: fxp0 acpi0                     334          0
irq12: uhci0 uhci1                     2          0
irq14: ata0                         3598          4
Total                             185458        232



top -S -Hは、こんな感じ。



last pid:   834;  load averages:  0.00,  0.02,  0.03              up 0+00:14:28  16:31:50
74 processes:  2 running, 57 sleeping, 15 waiting
CPU states:  1.5% user,  0.0% nice,  0.0% system,  0.0% interrupt,  100% idle
Mem: 10M Active, 11M Inact, 21M Wired, 44K Cache, 28M Buf, 137M Free
Swap: 512M Total, 512M Free



  PID USERNAME   PRI NICE   SIZE    RES STATE    TIME   WCPU COMMAND
   11 root       171 ki31     0K     8K RUN     13:52 100.00% idle
   12 root       -32    -     0K     8K WAIT     0:01  0.00% swi4: clock sio
    4 root        -8    -     0K     8K -        0:00  0.00% g_down
  564 root        96    0  3104K  1208K select   0:00  0.00% nfsd
  783 root         5    0  4468K  2584K ttyin    0:00  0.00% csh
  800 root         4    0  8384K  3776K sbwait   0:00  0.00% sshd
    3 root        -8    -     0K     8K -        0:00  0.00% g_up



う~ん、どういうことなんでしょうね。
この症状がでるのって、うちのこのパソコンくらいなんでしょうか。





P.S.



最初、writertc()の方を見落としていて、7-STABLEのときのままでやったら、vmstat -iでrtcが出てこなくなり、何が起きたんだ?と思ってソースコードを見直して、さもありなん、と納得。変数rtc_regのあたりですね。



writertc()を修正して、再起動したら、BIOSの初期化で、CMOSの内容がおかしいよ、と言われてしまう。



う~ん、そういうこともありそうな気がする、と再び納得しつつ、BIOSメニューでパラメータを再設定して再起動したら・・・起動しなくなりました。どこか、指定を間違えたみたいです(DRAM関係を間違えたらしい)。



しょうがないから、CMOSの内容をリセットしようと思って、マザーボード上のジャンパピンを探したら、見つからない。



マニュアルを見て、ジャンパピンの場所を調べてみたけど、やはり見つからない。



おかしいな、と思いつつ、ボード上に印刷している文字をじっくりと眺めていたら・・・、ジャンパピンがあるべき場所に、パターンだけがあって、ピンがはんだ付けされてませんでした。不良品じゃん・・・約8年目にして気がついた・・・





P.S. 2



関係あるかどうかわかりませんが(関係ありそうですが)、portupgradeを実行中など、裏で重たいプロセスが走っているとき、キー入力などの反応がものすごく鈍くなる、っていうのも改善されました。



おかしかったときは、CPUの統計情報が取得できなくなってたので、プロセスのスケジューリングも、メロメロな状態になっていたのではないかと?




■ 過去記事













0 件のコメント:

コメントを投稿