Chinaunix首页 | 论坛 | 博客
  • 博客访问: 974714
  • 博文数量: 109
  • 博客积分: 1751
  • 博客等级: 上尉
  • 技术积分: 1817
  • 用 户 组: 普通用户
  • 注册时间: 2011-05-31 22:37
文章分类

全部博文(109)

文章存档

2014年(9)

2013年(21)

2012年(48)

2011年(31)

分类: LINUX

2011-09-20 17:02:29

摘抄memory-barrier.txt中关于mmiowb的一部分,以解答mmiowb的用法。
----------

在某些情况下(特别是涉及到NUMA的情况), 两个CPU上发起的属于两个spinlock临界区的IO
访问可能被PCI桥看成是交错发生的, 因为PCI桥并不一定参与cache一致性协议, 以至于无
法响应读内存屏障.

例如:

        CPU 1                                CPU 2
        ===============================      ===============================
        spin_lock(Q)
        writel(0, ADDR)
        writel(1, DATA);
        spin_unlock(Q);
                                             spin_lock(Q);
                                             writel(4, ADDR);
                                             writel(5, DATA);
                                             spin_unlock(Q);

PCI桥可能看到的是:

        STORE *ADDR = 0, STORE *ADDR = 4, STORE *DATA = 1, STORE *DATA = 5

这可能会引起硬件操作的错误.

这里所需要的是, 在释放spinlock之前, 使用mmiowb()作为干预, 例如:

        CPU 1                                CPU 2
        ===============================      ===============================
        spin_lock(Q)
        writel(0, ADDR)
        writel(1, DATA);
        mmiowb();
        spin_unlock(Q);
                                             spin_lock(Q);
                                             writel(4, ADDR);
                                             writel(5, DATA);
                                             mmiowb();
                                             spin_unlock(Q);

这样就能确保CPU 1的两次STORE操作先于CPU 2的STORE操作被PCI桥所看到.

此外, 对于同一硬件设备在进行STORE操作之后再进行LOAD操作, 可以省去mmiowb(), 因为
LOAD操作将强制STORE操作在开始LOAD之前就完成:

        CPU 1                                CPU 2
        ===============================      ===============================
        spin_lock(Q)
        writel(0, ADDR)
        a = readl(DATA);
        spin_unlock(Q);
                                             spin_lock(Q);
                                             writel(4, ADDR);
                                             b = readl(DATA);
                                             spin_unlock(Q);
阅读(6985) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

szhxc1112013-10-05 12:26:49

估计PCI桥想去做些优化,对于ADDR 的两次操作可能会被优化成一次,这样就会有问题