docs/zh_CN: Update the translation of io_ordering to 6.0-rc2
Update to commit d1ce350015
Documentation: ("Add
io_ordering.rst to driver-api manual").
Move ../zh_CN/io_ordering.txt to ../zh_CN/driver-api/io_ordering.rst.
Signed-off-by: Yanteng Si <siyanteng@loongson.cn>
Reviewed-by: Wu XiangCheng <bobwxc@email.cn>
Link: https://lore.kernel.org/r/c66f6d17c509c2c93f2afd30223c4bcf734f8317.1661431365.git.siyanteng@loongson.cn
Signed-off-by: Jonathan Corbet <corbet@lwn.net>
This commit is contained in:
parent
6cf3116d5e
commit
3d8b56d7b1
|
@ -25,6 +25,7 @@ Linux驱动实现者的API指南
|
|||
:maxdepth: 2
|
||||
|
||||
gpio/index
|
||||
io_ordering
|
||||
|
||||
Todolist:
|
||||
|
||||
|
@ -97,7 +98,6 @@ Todolist:
|
|||
* isa
|
||||
* isapnp
|
||||
* io-mapping
|
||||
* io_ordering
|
||||
* generic-counter
|
||||
* memory-devices/index
|
||||
* men-chameleon-bus
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
.. include:: ../disclaimer-zh_CN.rst
|
||||
|
||||
:Original: Documentation/driver-api/io_ordering.rst
|
||||
|
||||
:翻译:
|
||||
|
||||
林永听 Lin Yongting <linyongting@gmail.com>
|
||||
司延腾 Yanteng Si <siyanteng@loongson.cn>
|
||||
|
||||
:校译:
|
||||
|
||||
===========================
|
||||
对内存映射地址的I/O写入排序
|
||||
===========================
|
||||
|
||||
在某些平台上,所谓的内存映射I/O是弱顺序。在这些平台上,驱动开发者有责任
|
||||
保证I/O内存映射地址的写操作按程序图意的顺序达到设备。通常读取一个“安全”
|
||||
设备寄存器或桥寄存器,触发IO芯片清刷未处理的写操作到达设备后才处理读操作,
|
||||
而达到保证目的。驱动程序通常在spinlock保护的临界区退出之前使用这种技术。
|
||||
这也可以保证后面的写操作只在前面的写操作之后到达设备(这非常类似于内存
|
||||
屏障操作,mb(),不过仅适用于I/O)。
|
||||
|
||||
假设一个设备驱动程的具体例子::
|
||||
|
||||
...
|
||||
CPU A: spin_lock_irqsave(&dev_lock, flags)
|
||||
CPU A: val = readl(my_status);
|
||||
CPU A: ...
|
||||
CPU A: writel(newval, ring_ptr);
|
||||
CPU A: spin_unlock_irqrestore(&dev_lock, flags)
|
||||
...
|
||||
CPU B: spin_lock_irqsave(&dev_lock, flags)
|
||||
CPU B: val = readl(my_status);
|
||||
CPU B: ...
|
||||
CPU B: writel(newval2, ring_ptr);
|
||||
CPU B: spin_unlock_irqrestore(&dev_lock, flags)
|
||||
...
|
||||
|
||||
上述例子中,设备可能会先接收到newval2的值,然后接收到newval的值,问题就
|
||||
发生了。不过很容易通过下面方法来修复::
|
||||
|
||||
...
|
||||
CPU A: spin_lock_irqsave(&dev_lock, flags)
|
||||
CPU A: val = readl(my_status);
|
||||
CPU A: ...
|
||||
CPU A: writel(newval, ring_ptr);
|
||||
CPU A: (void)readl(safe_register); /* 配置寄存器?*/
|
||||
CPU A: spin_unlock_irqrestore(&dev_lock, flags)
|
||||
...
|
||||
CPU B: spin_lock_irqsave(&dev_lock, flags)
|
||||
CPU B: val = readl(my_status);
|
||||
CPU B: ...
|
||||
CPU B: writel(newval2, ring_ptr);
|
||||
CPU B: (void)readl(safe_register); /* 配置寄存器?*/
|
||||
CPU B: spin_unlock_irqrestore(&dev_lock, flags)
|
||||
|
||||
在解决方案中,读取safe_register寄存器,触发IO芯片清刷未处理的写操作,
|
||||
再处理后面的读操作,防止引发数据不一致问题。
|
|
@ -1,67 +0,0 @@
|
|||
Chinese translated version of Documentation/driver-api/io_ordering.rst
|
||||
|
||||
If you have any comment or update to the content, please contact the
|
||||
original document maintainer directly. However, if you have a problem
|
||||
communicating in English you can also ask the Chinese maintainer for
|
||||
help. Contact the Chinese maintainer if this translation is outdated
|
||||
or if there is a problem with the translation.
|
||||
|
||||
Chinese maintainer: Lin Yongting <linyongting@gmail.com>
|
||||
---------------------------------------------------------------------
|
||||
Documentation/driver-api/io_ordering.rst 的中文翻译
|
||||
|
||||
如果想评论或更新本文的内容,请直接联系原文档的维护者。如果你使用英文
|
||||
交流有困难的话,也可以向中文版维护者求助。如果本翻译更新不及时或者翻
|
||||
译存在问题,请联系中文版维护者。
|
||||
|
||||
中文版维护者: 林永听 Lin Yongting <linyongting@gmail.com>
|
||||
中文版翻译者: 林永听 Lin Yongting <linyongting@gmail.com>
|
||||
中文版校译者: 林永听 Lin Yongting <linyongting@gmail.com>
|
||||
|
||||
|
||||
以下为正文
|
||||
---------------------------------------------------------------------
|
||||
|
||||
在某些平台上,所谓的内存映射I/O是弱顺序。在这些平台上,驱动开发者有责任
|
||||
保证I/O内存映射地址的写操作按程序图意的顺序达到设备。通常读取一个“安全”
|
||||
设备寄存器或桥寄存器,触发IO芯片清刷未处理的写操作到达设备后才处理读操作,
|
||||
而达到保证目的。驱动程序通常在spinlock保护的临界区退出之前使用这种技术。
|
||||
这也可以保证后面的写操作只在前面的写操作之后到达设备(这非常类似于内存
|
||||
屏障操作,mb(),不过仅适用于I/O)。
|
||||
|
||||
假设一个设备驱动程的具体例子:
|
||||
|
||||
...
|
||||
CPU A: spin_lock_irqsave(&dev_lock, flags)
|
||||
CPU A: val = readl(my_status);
|
||||
CPU A: ...
|
||||
CPU A: writel(newval, ring_ptr);
|
||||
CPU A: spin_unlock_irqrestore(&dev_lock, flags)
|
||||
...
|
||||
CPU B: spin_lock_irqsave(&dev_lock, flags)
|
||||
CPU B: val = readl(my_status);
|
||||
CPU B: ...
|
||||
CPU B: writel(newval2, ring_ptr);
|
||||
CPU B: spin_unlock_irqrestore(&dev_lock, flags)
|
||||
...
|
||||
|
||||
上述例子中,设备可能会先接收到newval2的值,然后接收到newval的值,问题就
|
||||
发生了。不过很容易通过下面方法来修复:
|
||||
|
||||
...
|
||||
CPU A: spin_lock_irqsave(&dev_lock, flags)
|
||||
CPU A: val = readl(my_status);
|
||||
CPU A: ...
|
||||
CPU A: writel(newval, ring_ptr);
|
||||
CPU A: (void)readl(safe_register); /* 配置寄存器?*/
|
||||
CPU A: spin_unlock_irqrestore(&dev_lock, flags)
|
||||
...
|
||||
CPU B: spin_lock_irqsave(&dev_lock, flags)
|
||||
CPU B: val = readl(my_status);
|
||||
CPU B: ...
|
||||
CPU B: writel(newval2, ring_ptr);
|
||||
CPU B: (void)readl(safe_register); /* 配置寄存器?*/
|
||||
CPU B: spin_unlock_irqrestore(&dev_lock, flags)
|
||||
|
||||
在解决方案中,读取safe_register寄存器,触发IO芯片清刷未处理的写操作,
|
||||
再处理后面的读操作,防止引发数据不一致问题。
|
Loading…
Reference in New Issue