.. 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芯片清刷未处ç†çš„写æ“作, å†å¤„ç†åŽé¢çš„读æ“作,防æ¢å¼•å‘æ•°æ®ä¸ä¸€è‡´é—®é¢˜ã€‚