[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: CASSIOPEIA report



鈴木(康)です。

わけわからないことばかり書いて申し訳ないんですが...

  | こちらについてですが、実験とは関係ないレベルで問題あるんじゃないかと
  | いう気がしてきました。
  | 
  | software interrupt が、割り込み実行レベルを無視して実行されてしまうので
  | はないでしょうか?
  | 
  | たとえば、こんなことが起きるように思います。
  | 
  |    o INTR0 での割り込み処理(たとえば KIU の処理)が実行されているときに、
  |      INTR1 の割り込みが起きて hardclock() が実行される。
  |      ( このこと自体は  hardclock() の方が 優先度が高く問題ない。)
  | 
  |    o hardclock() の後 続いて softclock() も実行されてしまう。
  |      ( この場合、INTR0 で low level の spl制御をしていても
  |        無視されて 最も低いレベルのはずの割り込み処理が動いてしまう。)
  | 
  | 
  | このようなことが起きそうなら、softclock() 等の処理をしない というロジック
  | が cpu_intr() の処理に入っていないといけないと思うのですが、
  | どうも入っていなさそうです。

上のような心配はないことが分かりました。
software interrupt は hardware interrupt と同じように実装されていて
マスクできるんですね。

ですが... machdep.c を読むと どうも気になるところが、2 つあります。

1) vr の root に
 
vr_intr_establish(VR_INTR1, vrrtc_intr, sc);
vr_intr_establish(VR_INTR0, vrip_intr, self);

の2 つのベクタが登録されているわけですが、

1回の割り込みで、どちらかしか1回しか実行されないように見えます。
2つの割り込みが pending されたとき lost するんじゃないでしょうか?

2つの割り込みが pending されるのは、たとえば splhi() で動いている
ときに たまたま 2つ来るとき ですから、確率は低いとは思います。

2) 割り込み処理ルーチンを動かすときに 割り込みレベル(IPL)をそもそも設定
していないように見えます。

たとえば、
	_spllower(MIPS_SOFT_INT_MASK_0);
	softclock();

とか
         _spllower(MIPS_SOFT_INT_MASK_0|MIPS_SOFT_INT_MASK_1);
         DO_SIR(SIR_NET, netintr());

とかになっていないと他の割り込み(正確には INTR0?)が入らず、
割り込み処理は走り切ることになると思います。

ちなみに vr_intr() はこんな処理かな

        if (ipending & MIPS_INT_MASK_1) {
                _spllower(MIPS_SPL_0_1);
                (*intr_handler[1])(intr_arg[1], pc, status);
        }
        if (ipending & MIPS_INT_MASK_0) {
                _spllower(MIPS_SPL0);
                (*intr_handler[0])(intr_arg[0], pc, status);

        }
--- ここまで

2) の方は、spl を細かく制御する メリットが得られないだけで、
バグとまでは言えないですね。

しかも spl を細かく制御すると なにが嬉しいか と問われれば 
答えにつまってしまう。

.... というわけで、このロジックを入れてみました。

software interrupt の中で スタンバイ命令を発行しても POWER ボタンで
復帰できるようにはなりました。

しかし...調子が悪いです。しばらく使うと フリーズするみたい。
なにか考慮不足のところを見つけたら教えてください。


P.S. その2

コプロセッサの割り込みマスクレジスタの値って
_splget で取れる値のことでしょうか?

# すいません全く理解していませんでした。

software interrupt の上で動かしたときの値ですが、

0xf801 だったり 0x7801 だったりしました。

_spllower() 入れると当然ながら 0xfc01 になります。

--
					鈴木 康司 @NECソリューションズ
					suz@hpc.bs1.fc.nec.co.jp
					TEL 042-333-6465