RFC-0237:使用 ZX_CLOCK_UPDATED 更新 Signalling Clock

RFC-0237:使用 ZX_CLOCK_UPDATED 傳送時鐘更新信號
狀態已接受
區域
  • 核心
說明

新增一種信號類型,在 Zircon 時鐘更新時傳送

Gerrit 變更
作者
審查人員
提交日期 (年-月-日)2023-09-26
審查日期 (年-月-日)2024-01-03

摘要

這份 RFC 建議在 Zircon 時鐘中導入新的時鐘訊號 ZX_CLOCK_UPDATED,每次時鐘更新時都會閃爍。

提振精神

時鐘時鐘單調性參考時間軸的一維仿射變換,定義如何將「參考」時間 (即裝置的單調性時鐘) 轉換為時鐘輸出的「合成」時間。因此,UTC 時鐘是不斷調整的轉換函式,當套用至裝置單調時鐘的目前值時,會產生目前世界標準時間。

Zircon 中 UTC 時鐘的仿射變換,僅會由 Timekeeper 使用 syscall zx_clock_update 更新,且可供任何使用者使用 syscall zx_clock_get_details 讀取。

為了讓在 Starnix 上執行的 Linux 程式能夠使用 vDSO 函式 clock_gettimegettimeofday 計算世界標準時間,Starnix vDSO 必須能夠存取從單調時間到世界標準時間的最新時鐘轉換。目前,Starnix 核心可以使用 zx_clock_get_details 定期對 Zircon UTC 時鐘進行時鐘轉換的輪詢,然後將此轉換載入 Starnix 核心和 Starnix 上執行的 Linux 程式的使用者空間共用記憶體中的網頁,以提供這項存取權。

閃爍是指對訊號進行無限快速的斷言和取消斷言。這表示等待時鐘訊號變更的觀察器可以偵測到閃爍,但不會有任何觀察器讀取要斷言的時鐘訊號值。透過引入 ZX_CLOCK_UPDATED (在時鐘更新時會閃爍的時鐘訊號),Starnix 核心可以改為收到世界標準時間時鐘的更新通知,並從 Zircon 取得最新的轉換,然後在收到這些通知後立即更新 Linux 程式使用的時鐘轉換。這麼做可減少在 Linux 程式計算世界標準時間時,Zircon 中時鐘轉換變更與使用這項新轉換之間的潛在延遲時間。

相關人員

誰會受到這項 RFC 是否通過的影響?(此為選用部分,但建議您填寫)。

協助人員:

  • cpu@google.com

審查者:

  • abarth@google.com
  • maniscalco@google.com
  • johngro@google.com

諮詢:

  • mariagl@google.com
  • fdurso@google.com
  • qsr@google.com

社會化:

與上述所有審查人員和顧問進行討論。這份文件之前有設計文件,並收到所有利益相關者提供的非正式意見回饋。

這份文件中的資訊已納入本 RFC,並在相關部分加以整合。

設計

Zircon 時鐘包含一個信號:ZX_CLOCK_STARTED,會在時鐘啟動時提出。設計中新增了 ZX_CLOCK_UPDATED 時鐘信號,每次更新時鐘時,系統都會發送這項信號。

為了能夠閃爍信號,設計也涉及修改 Dispatcher::UpdateState,目前用於更新 Zircon 信號。目前,該函式會採用兩個輸入內容:set_maskclear_mask,用於指定要設定 (斷言) 和清除 (取消斷言) 的信號。除了更新 set_maskclear_mask 指定的信號,這個函式還會使用 NotifyObservers 函式,通知所有觀察器任何從非活動狀態轉為活動狀態的信號。

修改內容是將第三個輸入值新增至 UpdateState,並命名為 strobe_mask,預設值為零。這會指定要閃爍的所有信號。指定為閃爍的訊號不會變更值,但 NotifyObservers 呼叫會經過修改,以便通知所有觀察者 strobe_mask 指定的任何訊號,讓觀察者得知訊號已更新。

為了使用這個訊號,以便在不會讓使用者錯過更新的情況下,通知他們時鐘轉換的更新,使用者不應使用 zx_object_wait_onezx_object_wait_many 等待信號閃爍。如果使用者讀取目前的時鐘詳細資料,然後呼叫 zx_object_wait_one 以等待時鐘更新,在讀取目前時鐘詳細資料和呼叫等待之間,Zircon 可能已更新時鐘,因此系統不會註冊這項更新。

請改用 zx_object_wait_async。在讀取目前轉換作業之前,使用者應針對時鐘發布非同步等待作業。然後,在讀取時鐘詳細資料後,使用者就可以在發布非同步等待的端口上等待。這樣就能避免錯過時鐘詳細資料的更新。

這個機制的結果是,如果在建立非同步等待作業與讀取時鐘詳細資料之間更新時鐘,會導致在等待連接埠時立即喚醒,即使讀取的時鐘轉換為最新狀態也一樣。日後的作業可能會改進這項信號,以免發生這些誤喚醒的可能性。

實作

這項設計可在一個小型 CL 中實作。CL 會定義新的訊號,並修改 UpdateState 以納入新的 strobe_mask 輸入內容。

成效

Starnix 核心會使用這個新信號,減少在 Starnix 上執行的 Linux 程式世界標準時間時鐘的潛在錯誤。

目前,Starnix 是唯一建議使用這項信號的使用者,但日後可能會有其他使用者使用這項信號 (例如,為了支援 C++ 標準程式庫在 UTC 期限前封鎖執行緒的能力,而實作 C++ 執行階段)。使用 UpdateState 閃爍訊號的時間複雜度,與訊號觀察者的數量成線性關係。也就是說,當 ZX_CLOCK_UPDATED 的觀察員數量變多時,就會發生效能問題。

回溯相容性

任何現有信號的行為都不會改變,因此預期不會有向下相容性的問題。

安全性考量

這項提案不會造成任何安全性影響。

隱私權注意事項

這項提案不會對隱私權造成任何影響。

測試

我們會新增測試,驗證設計中指定的行為。這些測試會確保沒有任何使用者可以手動變更時鐘信號,且任何在時鐘 ZX_CLOCK_UPDATED 信號上等待閃光燈的觀察者,都會在時鐘更新時收到通知,且在沒有時鐘更新時不會收到信號觀察者的通知 (也就是說,在沒有時鐘更新時,系統不會斷言 ZX_CLOCK_UPDATED)。

說明文件

我們會更新下列說明文件,以說明 ZX_CLOCK_UPDATED,以及使用者應遵循的方法時鐘,以免在使用此信號時錯過更新。

缺點和替代方案

缺點

本文件的「效能」一節說明瞭隨著信號觀察員數量增加,效能會降低的問題。如果時鐘訊號的觀察者數量增加到大量,可能需要進一步處理,以減輕這些效能問題。

替代方案

針對動機所提出的問題,另一個解決方案是將 Zircon UTC 時鐘的時鐘詳細資料直接對應至 Starnix 核心。接著,Starnix 核心就能將這段記憶體直接對應至 Linux 程序的空間。也就是說,Zircon 中的時鐘物件會立即更新至 Starnix 和 Linux 程序。這樣一來,就不需要引入新的訊號,而且不必降低傳播至 Starnix 的時鐘更新延遲時間,而是完全移除這項延遲時間。不過,這需要對 Zircon 核心進行大幅變更。