免费注册 查看新帖 |

Chinaunix

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

softirq&timer中还用得着bh版本spin_lock_bh吗? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-12-11 21:57 |只看该作者 |倒序浏览
10可用积分
spin_lock_bh通常用在进程中,用来禁止抢断和禁止软中断。
而软中断本身不可嵌套,所以,在软中断中就不需要bh版本的spin_lock_bh。
Linux的timer是通过软中断TIMER_SOFTIRQ实现的,所以timer的超时处理函数应该也不需要bh版本的spin_lock_bh。

但kernel中br_fdb.c中的br_fdb_cleanup()为什么用spin_lock_bh?

void br_fdb_cleanup(unsigned long _data)
{
struct net_bridge *br = (struct net_bridge *)_data;
unsigned long delay = hold_time(br);
int i;

spin_lock_bh(&br->hash_lock);
for (i = 0; i < BR_HASH_SIZE; i++) {
struct net_bridge_fdb_entry *f;
struct hlist_node *h, *n;

hlist_for_each_entry_safe(f, h, n, &br->hash, hlist) {
if (!f->is_static &&
    time_before_eq(f->ageing_timer + delay, jiffies))
fdb_delete(f);
}
}
spin_unlock_bh(&br->hash_lock);

mod_timer(&br->gc_timer, jiffies + HZ/10);
}

恳请大家来讨论下。

论坛徽章:
0
2 [报告]
发表于 2008-12-11 22:16 |只看该作者
相同的软中断不会嵌套, 但是, 不同的软中断可以嵌套啊, 而且相同的软中断也可以运行在不同的CPU上

论坛徽章:
0
3 [报告]
发表于 2008-12-11 22:34 |只看该作者

回复 #2 scutan 的帖子

第一: 同一个cpu上所有的软中断是不会嵌套的,参见do_softirq()
asmlinkage void do_softirq(void)
{
        __u32 pending;
        unsigned long flags;

        if (in_interrupt())  //这里决定了,软中断在一个cpu上不会嵌套
                return;

        local_irq_save(flags);

        pending = local_softirq_pending();

        if (pending)
                __do_softirq();

        local_irq_restore(flags);
}

第二: 禁止软中断只能禁止本地的,即本cpu的软中断。

论坛徽章:
0
4 [报告]
发表于 2008-12-11 23:53 |只看该作者

回复 #3 allenlu1212 的帖子

谢谢指正,我搞错了,软中断在一个CPU上是串行的。

论坛徽章:
0
5 [报告]
发表于 2008-12-12 00:00 |只看该作者
原帖由 allenlu1212 于 2008-12-11 22:34 发表
第二: 禁止软中断只能禁止本地的,即本cpu的软中断。


这句话能给一下出处吗?
我没有找到。
LKD上面说的是:
The function spin_lock_bh() obtains the given lock and disables all bottom halves.
没有提到是本CPU的。

thanks.

论坛徽章:
0
6 [报告]
发表于 2008-12-12 10:21 |只看该作者

回复 #5 scutan 的帖子

1.  参看内核:
    spin_lock_bh()->
        local_bh_disable()->....
              add_preempt_count(SOFTIRQ_OFFSET)->
                           preempt_count() += val;

   而preempt_count()定义为:
   #define preempt_count()        (current_thread_info()->preempt_count) //注意这里

2. spin_lock_bh中的"spin"是全局的,"bh"是本地的。

3. 禁止软中断和禁止硬中断都是指本地。

论坛徽章:
0
7 [报告]
发表于 2008-12-12 11:33 |只看该作者
不需要

论坛徽章:
0
8 [报告]
发表于 2008-12-12 11:44 |只看该作者

回复 #7 baohuaihuai 的帖子

但为什么br_fdb_cleanup()用spin_lock_bh,相信linux的code不是随便写的。

论坛徽章:
0
9 [报告]
发表于 2008-12-12 13:25 |只看该作者
lz什么版本的kernel?bh2.6已经没有了吧

论坛徽章:
0
10 [报告]
发表于 2008-12-12 13:27 |只看该作者
2.6.26
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP