WSL2-Linux-Kernel/Documentation/translations/zh_CN/io_ordering.txt

68 строки
2.9 KiB
Plaintext
Исходник Ответственный История

Этот файл содержит неоднозначные символы Юникода!

Этот файл содержит неоднозначные символы Юникода, которые могут быть перепутаны с другими в текущей локали. Если это намеренно, можете спокойно проигнорировать это предупреждение. Используйте кнопку Экранировать, чтобы подсветить эти символы.

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芯片清刷未处理的写操作
再处理后面的读操作,防止引发数据不一致问题。