Instruction Restart

Concept

Page fault 可能在任何一個步驟發生,可能在 instruction 執行前、執行中、執行後,所以 OS 處理完 page fault 後要從哪裡開始繼續執行?

我們會從頭執行那條指令(restart the instruction),而不是從中間繼續

假設我們要 add A,B -> C,他的步驟是:fetch 指令 → fetch A → fetch B → 相加 → 將結果存到 C,如果在「存到 C」這步才 page fault,OS 還是會將整條指令都重跑一遍

Overlapping

我們考慮MOVS,它會把一大塊資料從記憶體搬到另一個位置,問題在於如果 source 和 destination 有 overlapped 該怎麼辦?

像是我們要把 page 100~103 的資料搬到 102~105,如果在將 102 搬到 104 時 104 發生 page fault,等我們 handle 完整個 instruction 重新執行 source 的舊資料可能已經在剛剛 page fault 前的搬移被污染了

對於 page 100 已經搬到 page 102 等下 page 102 就沒有舊資料搬到 page 104 這個問題在 compile time 就會被編譯器處理了(像是改變搬移順序),所以這裡我們需要處理的只是避免在搬移過程的 page fault 造成 restart instruction 的問題

Solution

1. 不用讓問題在執行時才爆發

microcode 會在 instruction 執行前嘗試存取每一個 instruction 涉及的 page,如果該 page 會 page fault,我們就在這個時候先處理好

如此可以保證之後真實執行 instruction 時不會 page fault

2. 事後還原(在 register 備份)

在開始搬移前先將即將被搬移的舊值備份到 register 或其他安全的地方。如果搬移圖中產生 page fault,在 trap in kernel 前,OS 會先將這些備份重新寫回原地址,就可以避免 restart instruction 可能造成的問題