免费注册 查看新帖 |

Chinaunix

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

[内核同步] spin_lock_irq 不明白 望指导 [复制链接]

论坛徽章:
16
CU十二周年纪念徽章
日期:2013-10-24 15:41:3415-16赛季CBA联赛之广东
日期:2015-12-23 21:21:55青铜圣斗士
日期:2015-12-05 10:35:30黄金圣斗士
日期:2015-11-26 20:42:16神斗士
日期:2015-11-19 12:47:50每日论坛发贴之星
日期:2015-11-18 06:20:00程序设计版块每日发帖之星
日期:2015-11-18 06:20:002015亚冠之城南
日期:2015-11-10 19:10:492015亚冠之萨济拖拉机
日期:2015-10-28 18:47:282015亚冠之柏太阳神
日期:2015-08-30 17:21:492015亚冠之山东鲁能
日期:2015-07-07 18:48:39摩羯座
日期:2014-08-29 23:01:42
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-06-16 14:10 |只看该作者 |倒序浏览
本帖最后由 tc1989tc 于 2015-06-17 12:12 编辑

自旋锁的代码调用流程大致如下,
但是只看见其中local_irq_disable()将本地中断关闭,
但是下面的preempt_disable();
        spin_acquire(&lock->dep_map, 0, 0, _RET_IP_);
        LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock);
        代码看不懂。个人理解既然关闭啦中断。那么为啥还要执行下面的do_raw_spin_lock
        函数啊?

函数调用流程如下:
spin_lock_irq -> raw_spin_lock_irq->__raw_spin_lock_irq

static inline void spin_lock_irq(spinlock_t *lock)
{
        raw_spin_lock_irq(&lock->rlock);
}

#define raw_spin_lock_irq(lock)                _raw_spin_lock_irq(lock)

void __lockfunc _raw_spin_lock_irq(raw_spinlock_t *lock)
{
        __raw_spin_lock_irq(lock);
}

static inline void __raw_spin_lock_irq(raw_spinlock_t *lock)
{
        local_irq_disable();
        preempt_disable();
        spin_acquire(&lock->dep_map, 0, 0, _RET_IP_);
        LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock);
}


请问忙等待那段代码在哪个函数呢 我没有找到。谁知道啊

论坛徽章:
16
CU十二周年纪念徽章
日期:2013-10-24 15:41:3415-16赛季CBA联赛之广东
日期:2015-12-23 21:21:55青铜圣斗士
日期:2015-12-05 10:35:30黄金圣斗士
日期:2015-11-26 20:42:16神斗士
日期:2015-11-19 12:47:50每日论坛发贴之星
日期:2015-11-18 06:20:00程序设计版块每日发帖之星
日期:2015-11-18 06:20:002015亚冠之城南
日期:2015-11-10 19:10:492015亚冠之萨济拖拉机
日期:2015-10-28 18:47:282015亚冠之柏太阳神
日期:2015-08-30 17:21:492015亚冠之山东鲁能
日期:2015-07-07 18:48:39摩羯座
日期:2014-08-29 23:01:42
2 [报告]
发表于 2015-06-17 11:47 |只看该作者
有理解的吗

论坛徽章:
16
CU十二周年纪念徽章
日期:2013-10-24 15:41:3415-16赛季CBA联赛之广东
日期:2015-12-23 21:21:55青铜圣斗士
日期:2015-12-05 10:35:30黄金圣斗士
日期:2015-11-26 20:42:16神斗士
日期:2015-11-19 12:47:50每日论坛发贴之星
日期:2015-11-18 06:20:00程序设计版块每日发帖之星
日期:2015-11-18 06:20:002015亚冠之城南
日期:2015-11-10 19:10:492015亚冠之萨济拖拉机
日期:2015-10-28 18:47:282015亚冠之柏太阳神
日期:2015-08-30 17:21:492015亚冠之山东鲁能
日期:2015-07-07 18:48:39摩羯座
日期:2014-08-29 23:01:42
3 [报告]
发表于 2015-06-17 14:37 |只看该作者
x86下面是这样的:
static __always_inline void arch_spin_lock(arch_spinlock_t *lock)
{
        register struct __raw_tickets inc = { .tail = TICKET_LOCK_INC };

        inc = xadd(&lock->tickets, inc);
        if (likely(inc.head == inc.tail))
                goto out;

        inc.tail &= ~TICKET_SLOWPATH_FLAG;
        for (; {
                unsigned count = SPIN_THRESHOLD;

                do {
                        if (ACCESS_ONCE(lock->tickets.head) == inc.tail)
                                goto out;
                        cpu_relax();
                } while (--count);
                __ticket_lock_spinning(lock, inc.tail);
        }
out:        barrier();        /* make sure nothing creeps before the lock is taken */
}

论坛徽章:
16
CU十二周年纪念徽章
日期:2013-10-24 15:41:3415-16赛季CBA联赛之广东
日期:2015-12-23 21:21:55青铜圣斗士
日期:2015-12-05 10:35:30黄金圣斗士
日期:2015-11-26 20:42:16神斗士
日期:2015-11-19 12:47:50每日论坛发贴之星
日期:2015-11-18 06:20:00程序设计版块每日发帖之星
日期:2015-11-18 06:20:002015亚冠之城南
日期:2015-11-10 19:10:492015亚冠之萨济拖拉机
日期:2015-10-28 18:47:282015亚冠之柏太阳神
日期:2015-08-30 17:21:492015亚冠之山东鲁能
日期:2015-07-07 18:48:39摩羯座
日期:2014-08-29 23:01:42
4 [报告]
发表于 2015-06-17 14:37 |只看该作者
  1. static __always_inline void arch_spin_lock(arch_spinlock_t *lock)
  2. {
  3.         register struct __raw_tickets inc = { .tail = TICKET_LOCK_INC };

  4.         inc = xadd(&lock->tickets, inc);
  5.         if (likely(inc.head == inc.tail))
  6.                 goto out;

  7.         inc.tail &= ~TICKET_SLOWPATH_FLAG;
  8.         for (;;) {
  9.                 unsigned count = SPIN_THRESHOLD;

  10.                 do {
  11.                         if (ACCESS_ONCE(lock->tickets.head) == inc.tail)
  12.                                 goto out;
  13.                         cpu_relax();
  14.                 } while (--count);
  15.                 __ticket_lock_spinning(lock, inc.tail);
  16.         }
  17. out:        barrier();        /* make sure nothing creeps before the lock is taken */
  18. }
复制代码

论坛徽章:
20
程序设计版块每日发帖之星
日期:2015-08-17 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00每日论坛发贴之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:5615-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之青岛
日期:2017-09-04 17:32:0515-16赛季CBA联赛之吉林
日期:2018-03-26 10:02:16程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:512015亚冠之萨济拖拉机
日期:2015-08-17 12:21:08
5 [报告]
发表于 2015-06-17 20:31 |只看该作者
TICKET_SLOWPATH_FLAG这个标记做什么用的?

论坛徽章:
8
羊年新春福章
日期:2015-03-19 02:03:312015亚冠之北京国安
日期:2015-06-16 22:04:45程序设计版块每日发帖之星
日期:2015-06-23 22:20:00每日论坛发贴之星
日期:2015-06-23 22:20:002015亚冠之首尔
日期:2015-06-24 19:18:072015亚冠之广州恒大
日期:2015-08-06 10:29:442015亚冠之柏太阳神
日期:2015-11-02 11:21:0515-16赛季CBA联赛之辽宁
日期:2015-12-09 15:05:02
6 [报告]
发表于 2015-06-22 13:01 |只看该作者
从代码结构上看, 是为了虚拟化加的一个优化.
个人理解可能是虚拟化的是spin lock可能比较频繁.

下面是不完整的commit信息. 完整信息 自己git show一下吧.
commit 96f853eaa889c7a22718d275b0df7bebdbd6780e
Author: Jeremy Fitzhardinge <jeremy@goop.org>
Date:   Fri Aug 9 19:51:58 2013 +0530

    x86, ticketlock: Add slowpath logic
   
    Maintain a flag in the LSB of the ticket lock tail which indicates
    whether anyone is in the lock slowpath and may need kicking when
    the current holder unlocks.  The flags are set when the first locker
    enters the slowpath, and cleared when unlocking to an empty queue (ie,
    no contention).
   
    In the specific implementation of lock_spinning(), make sure to set
    the slowpath flags on the lock just before blocking.  We must do
    this before the last-chance pickup test to prevent a deadlock
    with the unlocker:
   
    Unlocker                    Locker
                                test for lock pickup
                                        -> fail
    unlock
    test slowpath
        -> false
                                set slowpath flags
                                block
   
    Whereas this works in any ordering:
   
    Unlocker                    Locker
                                set slowpath flags
                                test for lock pickup
                                        -> fail
                                block
    unlock
    test slowpath



回复 5# nswcfd


   

论坛徽章:
20
程序设计版块每日发帖之星
日期:2015-08-17 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00每日论坛发贴之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:5615-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之青岛
日期:2017-09-04 17:32:0515-16赛季CBA联赛之吉林
日期:2018-03-26 10:02:16程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:512015亚冠之萨济拖拉机
日期:2015-08-17 12:21:08
7 [报告]
发表于 2015-06-24 20:04 |只看该作者
本帖最后由 nswcfd 于 2015-06-24 20:05 编辑

好的,多谢提供信息。

不过还是没太看明白

论坛徽章:
0
8 [报告]
发表于 2015-08-26 19:15 |只看该作者
回复 1# tc1989tc

static inline void __raw_spin_lock_irq(raw_spinlock_t *lock)
{
        local_irq_disable();
        preempt_disable();
        spin_acquire(&lock->dep_map, 0, 0, _RET_IP_);
        LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock);
}

    为什么你觉得一个自旋锁关了中断后就可以了,而不用去拿锁? 那这个为什么叫自旋锁?

这个api 存在的理由是,保护临界区被从中断上下文访问。 所以, 要关闭本地中断。为什么要关闭“本地”中断?
如果不关。你在进程上下文拿这个锁,在本 CPU 上, 来了中断, 在中断处理函数里,也想拿这个自旋锁,这时
就会自旋等锁释放。问题是,拿锁的进程被你中断打断了,你一直在自旋; 拿锁的进程没法前进,锁是不会释放了,
然后就死锁了。

上面解释了为什么要关本地中断的原因了。然后进程真正该做的,拿自旋锁。先用 do_raw_spin_trylock 尝试,如果拿到,搞定;
否则,进入慢速路径,在do_raw_spin_lock里,要自旋,以等待锁的释放。

论坛徽章:
16
CU十二周年纪念徽章
日期:2013-10-24 15:41:3415-16赛季CBA联赛之广东
日期:2015-12-23 21:21:55青铜圣斗士
日期:2015-12-05 10:35:30黄金圣斗士
日期:2015-11-26 20:42:16神斗士
日期:2015-11-19 12:47:50每日论坛发贴之星
日期:2015-11-18 06:20:00程序设计版块每日发帖之星
日期:2015-11-18 06:20:002015亚冠之城南
日期:2015-11-10 19:10:492015亚冠之萨济拖拉机
日期:2015-10-28 18:47:282015亚冠之柏太阳神
日期:2015-08-30 17:21:492015亚冠之山东鲁能
日期:2015-07-07 18:48:39摩羯座
日期:2014-08-29 23:01:42
9 [报告]
发表于 2015-08-27 19:50 |只看该作者
回复 8# l4rmbr


   嗯是的,谢谢  我开始想到单cpu的形式啦  所以锁相关的
  东东就是费脑
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP