延遲 IO¶
延遲 IO 是一種延遲和重新利用 IO 的方法。 它使用主機記憶體作為緩衝區,並將 MMU 缺頁作為何時執行裝置 IO 的預觸發器。 以下示例可能有助於解釋一種這樣的設定是如何工作的
使用者空間應用程式(如 Xfbdev)mmap 幀緩衝
延遲 IO 和驅動程式設定故障和 page_mkwrite 處理程式
使用者空間應用程式嘗試寫入 mmapped 的虛擬地址
我們得到缺頁,併到達故障處理程式
故障處理程式找到並返回物理頁面
我們得到 page_mkwrite,在這裡我們將此頁面新增到列表
排程一個工作佇列任務,以便在延遲後執行
應用程式繼續寫入該頁面,沒有額外的成本。這是關鍵好處。
工作佇列任務進入並 mkcleans 列表上的頁面,然後完成與更新幀緩衝相關的任務。 這是與裝置通訊的真正工作。
應用程式嘗試寫入地址(現在已被 mkcleaned)
獲取缺頁,並且再次發生上述序列
從上面可以看出,一個好處是允許突發幀緩衝寫入以最低成本發生。 然後,經過一段時間,當希望一切都平靜下來時,我們去真正更新幀緩衝,這將是一個相對更昂貴的操作。
對於某些型別的非易失性高延遲顯示器,所需的影像是最終影像,而不是中間階段,這就是為什麼不更新每次寫入是可以接受的。
這種情況在其他場景中也可能有用。 Paul Mundt 提到了一種情況,即使用頁面計數來決定是合併和發出 SG DMA 還是進行記憶體突發是有益的。
另一種情況可能是,如果有一個裝置幀緩衝採用不尋常的格式,比如對角線移動 RGB,那麼這可能是一種機制,允許應用程式假裝擁有一個正常的幀緩衝,但根據觸控的頁面列表,在垂直同步時重新整理裝置幀緩衝。
如何使用它:(對於應用程式)¶
不需要更改。 像往常一樣 mmap 幀緩衝並使用它即可。
如何使用它:(對於 fbdev 驅動程式)¶
以下示例可能有所幫助。
設定您的結構。例如
static struct fb_deferred_io hecubafb_defio = { .delay = HZ, .deferred_io = hecubafb_dpy_deferred_io, };
延遲是 page_mkwrite 觸發器發生的時間與呼叫 deferred_io 回撥的時間之間的最小延遲。 deferred_io 回撥如下所述。
設定您的延遲 IO 回撥。例如
static void hecubafb_dpy_deferred_io(struct fb_info *info, struct list_head *pagelist)
deferred_io 回撥是您執行所有 IO 到顯示裝置的地方。 您收到 pagelist,它是延遲期間寫入的頁面列表。 您不得修改此列表。 此回撥是從工作佇列中呼叫的。
呼叫 init
info->fbdefio = &hecubafb_defio; fb_deferred_io_init(info);
呼叫 cleanup
fb_deferred_io_cleanup(info);