Commit 3d8b56d7 authored by Yanteng Si's avatar Yanteng Si Committed by Jonathan Corbet
Browse files

docs/zh_CN: Update the translation of io_ordering to 6.0-rc2



Update to commit d1ce3500 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: default avatarYanteng Si <siyanteng@loongson.cn>
Reviewed-by: default avatarWu XiangCheng <bobwxc@email.cn>
Link: https://lore.kernel.org/r/c66f6d17c509c2c93f2afd30223c4bcf734f8317.1661431365.git.siyanteng@loongson.cn


Signed-off-by: default avatarJonathan Corbet <corbet@lwn.net>
parent 6cf3116d
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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
+60 −0
Original line number Diff line number Diff line
.. 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芯片清刷未处理的写操作,
再处理后面的读操作,防止引发数据不一致问题。
+0 −67
Original line number Diff line number Diff line
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芯片清刷未处理的写操作,
再处理后面的读操作,防止引发数据不一致问题。