免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 7332 | 回复: 18
打印 上一主题 下一主题

[内核同步] 抢占+SMP+中断上下文->临界区资源保护方式 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-12-21 11:39 |只看该作者 |倒序浏览
第一帖。
假如我现在有一个临界区,它可能处于中断下文之中,当前的CPU支持抢占,且系统为SMP。

我看书上有讲到,使用下面的方式在单CPU中,如下方式是安全的。
spin_lock_irqsave(&lock,flags);
//...Critical Section
spin_unlock_irqrestore(&lock,flags);

但是对于SMP,由于spin_lock_irqsave()函数只禁止了本CPU中断,所以对于SMP,上述保护机制是不安全的,
这种说法对吗?
如果是不安全的,请问在此情况下,如何保护我的临界区资源最为安全呢?

论坛徽章:
10
戌狗
日期:2013-10-17 09:43:0215-16赛季CBA联赛之广东
日期:2018-02-05 11:22:1215-16赛季CBA联赛之八一
日期:2016-07-04 12:26:1815-16赛季CBA联赛之青岛
日期:2016-06-08 11:15:4115-16赛季CBA联赛之辽宁
日期:2016-04-05 10:10:1415-16赛季CBA联赛之辽宁
日期:2016-03-11 11:11:48酉鸡
日期:2014-12-18 14:35:48狮子座
日期:2014-02-20 10:14:07寅虎
日期:2013-12-02 13:48:2915-16赛季CBA联赛之广夏
日期:2018-03-21 08:51:10
2 [报告]
发表于 2012-12-21 13:05 |只看该作者
回复 1# xinshirn
spinlock是为SMP设计的,单核都不需要。。。


   

论坛徽章:
0
3 [报告]
发表于 2012-12-21 14:26 |只看该作者
本帖最后由 xinshirn 于 2012-12-21 14:44 编辑
daniel_11 发表于 2012-12-21 13:05
回复 1# xinshirn
spinlock是为SMP设计的,单核都不需要。。。


准确来说,单核CPU,如果系统支持任务抢占,是可以使用spin_lock_irq()的,它是自旋锁的一个变体。

论坛徽章:
4
天秤座
日期:2013-10-18 13:58:33金牛座
日期:2013-11-28 16:17:01辰龙
日期:2014-01-14 09:54:32戌狗
日期:2014-01-24 09:23:27
4 [报告]
发表于 2012-12-21 14:52 |只看该作者
为什么说“spin_lock_irqsave()”是SMP不安全的?哪里获得的信息?

论坛徽章:
10
戌狗
日期:2013-10-17 09:43:0215-16赛季CBA联赛之广东
日期:2018-02-05 11:22:1215-16赛季CBA联赛之八一
日期:2016-07-04 12:26:1815-16赛季CBA联赛之青岛
日期:2016-06-08 11:15:4115-16赛季CBA联赛之辽宁
日期:2016-04-05 10:10:1415-16赛季CBA联赛之辽宁
日期:2016-03-11 11:11:48酉鸡
日期:2014-12-18 14:35:48狮子座
日期:2014-02-20 10:14:07寅虎
日期:2013-12-02 13:48:2915-16赛季CBA联赛之广夏
日期:2018-03-21 08:51:10
5 [报告]
发表于 2012-12-21 14:52 |只看该作者
回复 3# xinshirn
单CPU的spinlock只是禁止内核抢占。


   

论坛徽章:
0
6 [报告]
发表于 2012-12-21 15:35 |只看该作者
多CPU时,spinlock是采用CPU提供的专门的操作指令来实现。下面是ARM CORTEX A9的实现
  1. static inline void arch_spin_lock(arch_spinlock_t *lock)
  2. {
  3.         unsigned long tmp;

  4.         __asm__ __volatile__(
  5. "1:        ldrex        %0, [%1]\n"
  6. "        teq        %0, #0\n"
  7.         WFE("ne")
  8. "        strexeq        %0, %2, [%1]\n"
  9. "        teqeq        %0, #0\n"
  10. "        bne        1b"
  11.         : "=&r" (tmp)
  12.         : "r" (&lock->lock), "r" (1)
  13.         : "cc");

  14.         smp_mb();
  15. }
复制代码
通过ldrex        及  strexeq两条汇编指令来实现原子加锁操作。这种操作指令的原子性是由硬件来保证的。

论坛徽章:
0
7 [报告]
发表于 2012-12-21 16:10 |只看该作者
内核代码可嫩在中断上下文中,最安全的保护措施就是spin_lock_irqsave()/spin_unlock_irqrestore(&lock,flags);

对于单核CPU来说,若内核配置为PREEMPT,则调用spin_lock_irqsave()时既关闭本地中断又关闭当前CPU的抢占。若内核没有配置PREEMPT,则只关闭本地中断就可以了;

对于SMP来说,除了关闭本地中断和关闭当前CPU内核抢占外,对于其他CPU的进程访问临界资源时,该进程会在那个CPU上spin一会儿,等当前进程退出临界区后,那个CPU上的进程可以正常进入临界区。

spinlock保护的临界区代码不易过大,否则会影响性能。有条件的话可以考虑per_cpu变量、atomic等。

论坛徽章:
0
8 [报告]
发表于 2012-12-23 01:39 |只看该作者
liuiang 发表于 2012-12-21 14:52
为什么说“spin_lock_irqsave()”是SMP不安全的?哪里获得的信息?


我说了前提,是SMP,且中断上下文,spin_lock_irqsave()不能禁止其他CPU的中断。临界区仍可能被其他CPU的中断进入,不是吗?

论坛徽章:
4
天秤座
日期:2013-10-18 13:58:33金牛座
日期:2013-11-28 16:17:01辰龙
日期:2014-01-14 09:54:32戌狗
日期:2014-01-24 09:23:27
9 [报告]
发表于 2012-12-23 14:21 |只看该作者
其他cpu中断有能怎样,要进入临界区,仍然会spin在外面,除非临界区被unlock。

如果仅因为不能禁止其他cpu的中断,那么spin__irq_跟irq_disable这些还有什么区别?

论坛徽章:
0
10 [报告]
发表于 2012-12-23 19:38 |只看该作者
回复 9# liuiang

所以,如你所说,下面的使用是保证安全的?
spin_lock_irqsave(&lock,flags);
//...Critical Section
spin_unlock_irqrestore(&lock,flags);


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP