Commit | Line | Data |
---|---|---|
76f1fc26 HH |
1 | Chinese translated version of Documentation/driver-api/io_ordering.rst |
2 | ||
3 | If you have any comment or update to the content, please contact the | |
4 | original document maintainer directly. However, if you have a problem | |
5 | communicating in English you can also ask the Chinese maintainer for | |
6 | help. Contact the Chinese maintainer if this translation is outdated | |
7 | or if there is a problem with the translation. | |
8 | ||
335bbdf0 | 9 | Traditional Chinese maintainer: Hu Haowen <2023002089@link.tyut.edu.cn> |
76f1fc26 HH |
10 | --------------------------------------------------------------------- |
11 | Documentation/driver-api/io_ordering.rst 的繁體中文翻譯 | |
12 | ||
13 | 如果想評論或更新本文的內容,請直接聯繫原文檔的維護者。如果你使用英文 | |
14 | 交流有困難的話,也可以向繁體中文版維護者求助。如果本翻譯更新不及時或 | |
15 | 者翻譯存在問題,請聯繫繁體中文版維護者。 | |
16 | ||
335bbdf0 HH |
17 | 繁體中文版維護者: 胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn> |
18 | 繁體中文版翻譯者: 胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn> | |
19 | 繁體中文版校譯者: 胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn> | |
76f1fc26 HH |
20 | |
21 | ||
22 | 以下爲正文 | |
23 | --------------------------------------------------------------------- | |
24 | ||
25 | 在某些平台上,所謂的內存映射I/O是弱順序。在這些平台上,驅動開發者有責任 | |
26 | 保證I/O內存映射地址的寫操作按程序圖意的順序達到設備。通常讀取一個「安全」 | |
27 | 設備寄存器或橋寄存器,觸發IO晶片清刷未處理的寫操作到達設備後才處理讀操作, | |
28 | 而達到保證目的。驅動程序通常在spinlock保護的臨界區退出之前使用這種技術。 | |
29 | 這也可以保證後面的寫操作只在前面的寫操作之後到達設備(這非常類似於內存 | |
30 | 屏障操作,mb(),不過僅適用於I/O)。 | |
31 | ||
32 | 假設一個設備驅動程的具體例子: | |
33 | ||
34 | ... | |
35 | CPU A: spin_lock_irqsave(&dev_lock, flags) | |
36 | CPU A: val = readl(my_status); | |
37 | CPU A: ... | |
38 | CPU A: writel(newval, ring_ptr); | |
39 | CPU A: spin_unlock_irqrestore(&dev_lock, flags) | |
40 | ... | |
41 | CPU B: spin_lock_irqsave(&dev_lock, flags) | |
42 | CPU B: val = readl(my_status); | |
43 | CPU B: ... | |
44 | CPU B: writel(newval2, ring_ptr); | |
45 | CPU B: spin_unlock_irqrestore(&dev_lock, flags) | |
46 | ... | |
47 | ||
48 | 上述例子中,設備可能會先接收到newval2的值,然後接收到newval的值,問題就 | |
49 | 發生了。不過很容易通過下面方法來修復: | |
50 | ||
51 | ... | |
52 | CPU A: spin_lock_irqsave(&dev_lock, flags) | |
53 | CPU A: val = readl(my_status); | |
54 | CPU A: ... | |
55 | CPU A: writel(newval, ring_ptr); | |
56 | CPU A: (void)readl(safe_register); /* 配置寄存器?*/ | |
57 | CPU A: spin_unlock_irqrestore(&dev_lock, flags) | |
58 | ... | |
59 | CPU B: spin_lock_irqsave(&dev_lock, flags) | |
60 | CPU B: val = readl(my_status); | |
61 | CPU B: ... | |
62 | CPU B: writel(newval2, ring_ptr); | |
63 | CPU B: (void)readl(safe_register); /* 配置寄存器?*/ | |
64 | CPU B: spin_unlock_irqrestore(&dev_lock, flags) | |
65 | ||
66 | 在解決方案中,讀取safe_register寄存器,觸發IO晶片清刷未處理的寫操作, | |
67 | 再處理後面的讀操作,防止引發數據不一致問題。 | |
68 |