Chinaunix首页 | 论坛 | 博客
  • 博客访问: 438787
  • 博文数量: 99
  • 博客积分: 65
  • 博客等级: 民兵
  • 技术积分: 1012
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-20 16:30
个人简介

linux kernel 工程师

文章分类

全部博文(99)

文章存档

2018年(5)

2017年(12)

2016年(27)

2015年(10)

2014年(43)

2012年(2)

我的朋友

分类: LINUX

2014-02-05 17:51:28

__local_bh_disable(SOFTIRQ_OFFSET)/__local_bh_enable(SOFTIRQ_OFFSET)
仅仅是增加/减少抢占计数, 这两个函数被__do_softirq()调用,应当不会被kernel线程来调用

static void __local_bh_enable(unsigned int cnt)
{
 WARN_ON_ONCE(in_irq());
 WARN_ON_ONCE(!irqs_disabled());

 if (softirq_count() == cnt)
  trace_softirqs_on((unsigned long)__builtin_return_address(0));
 sub_preempt_count(cnt); /* 减少抢占计数 */
}

static inline void __local_bh_disable(unsigned long ip, unsigned int cnt)
{
 add_preempt_count(cnt); /* 增加抢占计数 */ 
 barrier();
}
--------------------------------------------------------------------
在线程环境下调用local_bh_enable时,需要执行被耽误的softirq
static inline void _local_bh_enable_ip(unsigned long ip)
{
 WARN_ON_ONCE(in_irq() || irqs_disabled());
#ifdef CONFIG_TRACE_IRQFLAGS
 local_irq_disable();
#endif
 /*
  * Are softirqs going to be turned on now:
  */
 if (softirq_count() == SOFTIRQ_DISABLE_OFFSET)
  trace_softirqs_on(ip);
 /*
  * Keep preemption disabled until we are done with
  * softirq processing:
   */
 sub_preempt_count(SOFTIRQ_DISABLE_OFFSET - 1);  /* 此时抢占计数为1,还不能被抢占 */
 /* 但在执行softirq的callback函数时, 可以被中断和softirq打断 */

 if (unlikely(!in_interrupt() && local_softirq_pending()))
  do_softirq(); /*  这里是线程上下文,不是中断上下文,所以需要调用do_softirq(这个函数里面有先关闭中断的操作) */
    /* 因为线程里面禁止softirq,会导致softirq的推迟,所以在使能softirq后,主动执行已经被推迟的softirq */

 dec_preempt_count(); /* 抢占计数再减1,此时应当变为0,开启抢占 */
#ifdef CONFIG_TRACE_IRQFLAGS
 local_irq_enable();
#endif
 preempt_check_resched();
}

阅读(6092) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~