livaの雑記帳(2016/10)

10/31

  • git初心者なので、これまでSHAから過去のコミットへ巻き戻すと、マージされたコミットが混在したカオスなソースコードを取得してしまっていた
    • つまり、以下のようなコミット履歴で、マージをしていない(*)のコミットが欲しいのだけど、resetすると(♯)の変更が混ざっている
      • マージによって他のブランチからやってきたコミット(♯)→巻き戻したいコミット(*)→マージコミット→最新のコミット
  •  結論としては、reset時に–hardの代わりに、–mergeを使えば良い、という事を知った
  • クラスの値返し時はコピーコンストラクタが呼ばれない
    • 検証コード
      • 継承子クラスを親クラスの型で返す場合は、コピーコンストラクタが呼ばれてしまうので、注意
    • 一瞬、無視されてしまうError型の実装に使えそうって思ったけど、んな事なかった
      • 呼び出し元の関数がreturnする時にErrorを処理したかどうか判定するわけだけど、それまでにいっぱい処理してしまってたら意味ない
      • つまり、Error型が戻った直後にErrorを処理したか検証する必要があるわけだけど、それはc++では無理
      • Rustならデフォルトで無視すると怒られるError型があるのになぁ
  • 実機でキーボード入力を受け付けない問題を解析中
    • 昔は受け付けていた
    • ACPICAの初期化を無効化したらなぜか動いた。なんで????

10/27

  • KNLでSRATのMemory Affinityエントリを出力してみる
    • こんな感じ
      • p_20161027_110258
    • 型番忘れたけど、たぶんXeon Phi 7210で、メインメモリは96GB積んでる
    • 最初のメモリ空間がベースアドレス0から96GBで、これがDDR4
    • 次の空間がベースアドレスが96GBから16GBで、これがMCDRAM
    • MCDRAMってIntelのアーキテクチャ図だと複数個あるんだけど…おかしいなぁ?
    • 残りのゴミカスはEnabled flagのチェックをサボってるため
      • きちんとチェックしたら消えた

10/26

  • I/O APIC multi controllerの対応
    • いろいろ調べた割には対応はとても簡単だった
    • コントローラーごとにint baseとint maxが取れるから、irqを元にどのコントローラーに振れば良いか考えるだけで良い
  • ACPIのSRATを読むコードを書いた

10/25

  • 読んだ
    • I/O APIC周りの初期化におけるACPIからの情報取得について大変よくまとまっている

The ACPI MADT table has a flag (similar to the mp table imcr one) which indicates if legacy PIC needs to be disabled.

たぶんPCAT_COMPATの事

  • (17/3/13追記) PCAT_COMPATが立っているからといって、IMCRをいじってはいけない。
    • という事が上のリンクの後半に書かれている
    • ACPIが存在する場合はIMCRは存在しない・・・らしい

 

10/24

  • ここ数日取り組んでいた、スピンロックで落ちるバグが解決したので、メモ
    • キーボードを沢山叩いたり、ネットワークのテストを行うと発生する
    • 既にロックが掛かっている状況下でロックを掛けたCPUが更に同じロックを取得しようとしたため、カーネルがデッドロックと見なして自動停止している
      • コード設計でデッドロックを埋め込んだわけではないので、誤作動?
    • qemuでのみ起きる。実機では再現しない
    • スタックトレースを調べると、割り込みハンドラ内で落ちる模様
    • 最初にロックを掛けたコンテキストから、ロック関数呼び出し元の追跡した結果、どうやらTaskCtrl内の特定のコードで起きている
      • このコードの実行中に割り込みハンドラが呼び出され、同じロックを取得している
      • このコードはSpinLockでガードされている=割り込み禁止中のはず。それなのに割り込みハンドラが呼ばれているのはおかしい
      • しかも、ここのコードはものすごく単純な上、割り込みフラグやロックフラグはコード内で正常に動作している模様
    • 原因は至極簡単で、SpinLockクラスの実装のバグ
      • ロックを解除する前に割り込みが解除されていた

10/23

  • addr2lineのオプションを調べた
    • addr2line -Cife objname address がよさ気
  • pull requestをマージするときは、作成者にどんなテストをしたかを聞くべきだな
    • 本当ならCIでテストを回すのが良いのだけども

10/19

  • x2 APICはBSPだけで有効化しただけではダメで、APも自分で有効化しなきゃいけない
    • ちなみに、有効化しない状態でレジスタをMSRから読むとVirtualBoxでは0が帰る。実機だと落ちる(たぶん例外が飛んでる。仕様書にその旨書かれていたような。。)
  • Windows8.1とUbuntuをデュアルブートさせたかったのだが、嵌った
    • まず、Windows8.1をUEFIでインストールできない。UEFI画面上ではインストールDVDが認識されているのだけど、インストーラが起動しない
    • 仕方なくMBRでWindows8.1をインストール
    • Ubuntuをインストールしようとすると、パーティションが見えない。これだとパーティション切り直しになって、折角入れたWindowsが消えてしまう
    • いろいろ調べた結果、ようやく解決策を見つける
      • GPT消しましょう、って話
    • デュアルブートできた
      • ブートできたけど、GRUBのエントリがWindows Recovery Environmentになってて最初分からなかった
    • Windowsやっぱクソだわー

10/18

  • 人生で一番大規模なマージ作業をした。多くは語るまい
  • 今までSpurious Interruptとかで起動しなかったマシンでようやく起動するようになった
    • これのカスタムモデル
    • 代わりにQEMUがバグるようになった

10/17

  • 一部の実機でACPIの初期化中にフリーズするバグを修正
    • ACPICA内に沢山デバッグコード入れてどんどん関数コールを掘っていった結果判明したのが、セマフォクラスの型がおかしい、というもの
    • commit diff
    • ACPIの初期化で止まる場合、ACPICA内部にバグはなく、OS specificな実装部分に問題があるのだけど、ACPICAがでかすぎてバグ特定が大変である
  • 今日のc++は楽しい!というお話

10/13

  • x2 APICのIDが8bitから32bitに拡張されたのに対し、I/O APICのdestinationが8bitしかないため、IDが8bitを超えているCPUに割り込みを送れないのではないか疑惑
    • 調べたら出てきた→LKML
    • まあでもぶっちゃけ、とりあえず動かす分には実装しなくていいんじゃないかなぁ
  • 整数を構造体に突っ込んで型チェックする(例えば、NonZeroIntみたいな構造体を用意して、格納されている整数が0でない事を保証する)という方法、O3でコンパイルすれば値渡しがレジスタになる
    • -O3凄い
    • 普通に整数を使う場合とコストが変わらない
    • ただ、ポインタとか使い出すと最適化が掛けられないので注意
    • 更に構造体に2つ整数を格納して、値渡しならぬ値戻しした場合、raxとrdxに格納されて返る
      • calling conventionには規定されてないはずだが。。。
  • OSのデバッグをしようと思って手近のPCで起動しようとしたらなぜか起動しない
    • BIOSのブート項目を見るとUEFI onlyになっていて、変更できない
      • UEFI対応するかと思ってgrub-efiをインストールするも、パーティション分割したりしなきゃいけなくて面倒なようなので、諦める
      • Windows OS Configurationの中にあるWindows 8.1/10 WHQL SupportをDisableにしたらLegacy+UEFIが選べるようになった
        • 関係なさそうな名前にするのやめてほしい
        • 心なしかブートに掛かる時間が遅くなったような・・・スキャンの手間が増えたのだから仕方ないね
  • 上述の機体でOSを起動したら15番に割り込み。どういうこっちゃ
    • Intel SDMによれば、15番という例外は存在しない
    • もしやと思って8259PICの割り込みリマッピングをしてみた所、ちゃんとズレた場所に割り込みが発生した。ゆえにIRQ15が発生している事が判明
      • 0xa1と0x21に0xffでmask掛けてるんだけど、なんでIRQ15が発生するの。。。。
      • slaveの割り込み番号offset+7になるのはoffset%8==0の時のみ。正確には、IRQn%8==7な模様。
    • どうやらSpurious Interruptな気配→Wikipedia
      • この機体でdmesgを叩くと、確かにIRQ7でSpurious Interruptが発生している旨のログが出てる
        • Raph Kernelが正常に起動するマシンではdmesgにこのエラーが出てない模様
        • 今はIRQ15なんだけど、まあ細かい事は良しとする
      • osdev.orgのスレッドにそれらしき記載
        • 8259A無効化処理を消すとIRQ8から割り込みが入るっぽい
          • つまりRTCが諸悪の根源
        • IRQ8が既に発行されている状態でPICの割り込みをマスクしたため、PIC側が已む無くSpurious Interruptを返している、と考えるのが良さそう
          • てなると、適当に握りつぶすしかないなぁ

10/12

10/11

  • カーネルスレッドが一通り実装できた。テストしてないけど
  • ahciのブランチ、さっさと実機テスト通してマージしないとなぁ
    • 明日のんびりやる
  •  いい加減そろそろOSを作らないとなぁ、感
    • 僕がやってるのって、OSというよりデバドラの集合体
  • 大丈夫、OSなんて1万行程度で作れるから!
    • 大丈夫なのか…?
  • x2APICがよくわからない
    • APIC IDが32bitで指定できるようになったけど、I/O APICやMSIのdestのbit幅は変わらない
      • 直接APIC IDを指定して投げる(Physical)んじゃなくて、なんか頑張る(Logical)んじゃないかと思ってるのだけど、眠くて頭が働いていないのでまた明日

10/10

  • ここ数日殆どカーネルのコードが書けてなくて辛いので、今日こそ書く
  • 全然関係ないけど、CIでスクリーンショットって扱えるのだろうかと調べた所、扱えるっぽい
  • 何時も呼び出し規約を忘れてしまってググってるので、リンクを貼っておく
  • メモ:例外もどきを実装する
    • 最近実装すべきタスクが多くて、次何やるか忘れてしまうので
    • (さっきまで忘れてた)

10/5

  • 書いた→テキスト描画
    • 簡単すぎて逆に何書けばよいか悩んだ。簡単に書けるだろうと思ったから休憩がてら書いたのだけど、あまりに簡単すぎた

10/4

  • twitterを見ていたらtupというビルドシステムが流れてきた
    • ホームページ
    • Makeの逆で依存関係から生成ファイルを辿るから早いらしいのだが、既にある程度大規模化しているプロジェクトに組み込むのはちょっと難儀そう
    • あと、cleanがないそうなのだが、mj?

10/3

  • x2APIC有効化したらMADTにも生えた
    • x2APIC実装するのダルいなー
  • gccの-fdump-tree-xxxを使った静的解析ツールを僕も作りたい
  • カーネルタスクスレッドを実装中
    • 各スレッドは個別のカーネルスタックを持つ
    • 今までは各コア毎に固有のカーネルスタックだったけど、カーネル内でもブロッキング処理をするために必要になった
    • 上手い感じに実装できそう
      • と思ってたら行き詰まった

10/2

  • なんとなく高解像度テキストをやってみたくなった
    • やるならVBEかと思って少しVBEについて調べてみる
    • どうやらVBE3.0のProtected Mode Entry Pointというのを使えば良さそう
      • でも、BIOSイメージに対してfar callしろとか書いてあって、ダルそう
      • freebsdのコード(sys/dev/fb/vesa.c)も読んでみたけど、同じ事やってる
    • やめました
  • MADTのx2APICが生えない問題
    • どうやらAPIC IDが255より小さい場合はxAPICが使われるらしい
    • というわけでXeon Phiでテストする

10/1

  • Xeon Phiについて真面目に調べている
  • 今使っているマシンがKNLの7210
    • 物理コア数は64
    • 1コア4スレッドらしいので、APICでは256コア見えるはず
    • 実際Linuxからは見えた
    • APIC IDが255を振り切る(APIC IDは飛び飛び)ので、ACPIのLocal APICエントリには振り切ったコアが載らないっぽい
    • じゃあx2APICで取得してやんよ、って思ったけど、エントリが無かった
    • SAPICっていう似たようなエントリがあって、ぐぐっても出てこなかったのだけど、これはItaniumのAPICらしい
      • 興味ない
    • Disableになってるけど、あるっぽい
      • p_20161002_001210
      • がLegacy APIC、[XX]がx2APIC
      • x2APICを有効化してあげれば、使えるようになるかな?
  • Flat/HybridモードにおけるMCDRAMについて
    • Cacheモードの時はたぶんCPUが良しなにやってくれる
    • そうでない時は明示的にMCDRAMを使ってやらなければならない
    • MCDRAMはNUMAとして見えるらしい(KNLbookより)
    • NUMAをどうやって参照するのか、Intel Developper’s Manualには掲載されていない!
    • ふとACPIを見たら、NUMAの項目があった。たぶんこれ
    • qemuにもNUMA nodeを追加する設定があるから、上手くエミュレーションできるかもしれない
  • x2APICをエミュレーションする
    • qemuは-cpu qemu64,+x2apicを使ってもcpuidのx2APIC bitが立たない
    • Virtualboxで試す
      • vboxmanageで–x2apic onをつければ良い
        • エラーで怒られたので、アップデート。意外と最近に入ったのかもしれない。ついてる
          • virtualboxをアップデートしたらvagrantのアップデートも要求されてちょっと面倒な事になった
      • ちゃんとx2APIC bitが立った。素晴らしい
      • でも、x2APICを有効化してからACPIの初期化をしても、x2APICエントリが生えない。なんでだ?
広告