Chinaunix首页 | 论坛 | 博客
  • 博客访问: 335502
  • 博文数量: 102
  • 博客积分: 2510
  • 博客等级: 少校
  • 技术积分: 1146
  • 用 户 组: 普通用户
  • 注册时间: 2010-01-21 22:33
文章分类

全部博文(102)

文章存档

2011年(8)

2010年(94)

我的朋友

分类: LINUX

2010-03-16 13:40:00

 | | | | | | |

 
   >> 
此话题阅读次数: 161

  加到“个人收藏夹”   |    打印

(stranger)
10-03-11 13:09
 请教一个hrtimer的问题

hrtimer_enqueue_reprogram中重新设定下一次中断发生的时间以后,还会调用raise_softirq_irqoff(HRTIMER_SOFTIRQ);设置相应的软中断,并唤醒softirqd。 
为什么要这样设置呢?此时对应的hrtimer并没有发生。 

为什么不在时钟中断的处理函数中,设置raise_softirq_irqoff(HRTIMER_SOFTIRQ)呢?

文章选项: 打印   将这篇文章放置于备忘录中,待有空时回覆   好友分享   通知版主


(addict)
10-03-11 13:40
 Re: 请教一个hrtimer的问题 []

这个是由hrtimer的执行环境决定的。 
hrtimer expired后的执行在hrtimer_interrupt or softirq 两种环境里。 
so,如果是 softirq环境的话,就得使能HRTIMER_SOFTIRQ软中断,在软中断执行点调用 run_hrtimer_softirq 
手动触发 hrtimer_interrupt. 

"为什么不在时钟中断的处理函数中,设置raise_softirq_irqoff(HRTIMER_SOFTIRQ)呢?" 
== 
你说的“时钟中断的处理函数”是指scheduler_tick()还是hrtimer_interrupt()? 
如果是前者的话,原因是粒度太大了,比不上hrtimer 的精度。 




--------------------
做kernel,求内推,长期有效 

文章选项: 打印   将这篇文章放置于备忘录中,待有空时回覆   好友分享   通知版主


(stranger)
10-03-11 15:49
 Re: 请教一个hrtimer的问题 []

也许我没问清楚: 
hrtimer_enqueue_reprogram的定义: 
static inline int hrtimer_enqueue_reprogram(struct hrtimer *timer, 
struct hrtimer_clock_base *base) 

if (base->cpu_base->hres_active && hrtimer_reprogram(timer, base)) { 
spin_unlock(&base->cpu_base->lock); 
raise_softirq_irqoff(HRTIMER_SOFTIRQ); 
spin_lock(&base->cpu_base->lock); 
return 1; 

return 0; 

hrtimer_reprogram已经重新设置了中断,假设是50us以后,中断产生,而在时钟中断处理函数中,本来就会在中断上下文中处理hrtimer,为什么要手动设置raise_softirq_irqoff(HRTIMER_SOFTIRQ);? 
而且,raise_softirq_irqoff中会唤醒softirqd,这是硬件时钟中断还没有到来,就已经执行这个定时器,不是提前了吗?

文章选项: 打印   将这篇文章放置于备忘录中,待有空时回覆   好友分享   通知版主


(addict)
10-03-11 19:44
 Re: 请教一个hrtimer的问题 []

不知道这么回答可不可以: 

假如这个hrtimer要在软中断环境执行且过期时Tick中断还没有到怎么办呢? 

每一次设置hrtimer的时候激活softirq,保证hardirq中断退出时给softirq一个执行hrtimer的机会。 
当然在scheduler_tick时会检测 过期的hrtimer,但有可能已经太迟了... 


--------------------
做kernel,求内推,长期有效 

文章选项: 打印   将这篇文章放置于备忘录中,待有空时回覆   好友分享   通知版主


(stranger)
10-03-12 17:06
 Re: 请教一个hrtimer的问题 []

我们还是情景分析一下吧,先明确一下前提:Kernel是2.6.29,而且make menuconfig选中tickless(也就是NO_HZ宏定义打开)。 
我谈谈我的理解: 
假设一个nanosleep(50), 
此时内核会将这个定时器加入到hrtimers中,当发现这是最近一个到期定时器的时候,将这个时间与下一个tick发生时间比较,如果比下一个tick近,则调用hrtimer_enqueue_reprogram重新设置时钟中断,要求在50ns以后产生中断。 
在50ns以后,中断发生,进入时钟处理函数tick_period。 
tick_period->update_process_times->run_local_timers->hrtimer_run_queues()中会直接处理一遍所有到期的高精度定时器。然后设置普通精度定时器的软中断。 

如果我以上的理解是正确的,那么hrtimer_enqueue_reprogram中间为什么要调用raise_softirq_irqoff(HRTIMER_SOFTIRQ)来唤醒hrtimer的软中断。 

因为50ns以后明明会有一个硬中断产生,而且会直接处理到期定时。 

文章选项: 打印   将这篇文章放置于备忘录中,待有空时回覆   好友分享   通知版主


(addict)
10-03-12 18:11
 Re: 请教一个hrtimer的问题 []

兄弟,好像不是这个样子的。。。 
我的理解是: 
50ns后进入 hrtimer_interrupt()是硬中断环境,立即退出 --> 执行软中断(这个时候离tick中断还很远)-->处理hrtimer. 


--------------------
做kernel,求内推,长期有效 

文章选项: 打印   将这篇文章放置于备忘录中,待有空时回覆   好友分享   通知版主


(stranger)
10-03-15 10:16
 Re: 请教一个hrtimer的问题 []

感谢你的回复,我又仔细看了一下代码,你说的对2.6.27是对的,但是对于2.6.29以后,就不完全对了。 
2.6.27的hrtimer_interrupt处理流程是: 
1.找出所有到期定时器,加到cb_pending 
2.raise_softirq(HRTIMER_SOFTIRQ); 
3.规划下一次的定时器 
而2.6.29以后则是 
1.找出所有到期hr定时器,直接执行 
2.规划下一次定时器 
而没有raise_softirq(HRTIMER_SOFTIRQ) 


文章选项: 打印   将这篇文章放置于备忘录中,待有空时回覆   好友分享   通知版主


(addict)
10-03-15 12:04
 Re: 请教一个hrtimer的问题 []

再回答1楼的问题把, 
刚看了下代码,我前面的回答有部分可能是错的。 
我再看看代码,咣当咣当。。。 


--------------------
做kernel,求内推,长期有效 

文章选项: 打印   将这篇文章放置于备忘录中,待有空时回覆   好友分享   通知版主


(addict)
10-03-15 12:32
 Re: 请教一个hrtimer的问题 []

hrtimer_enqueue_reprogram()这个函数在重新启用一个hrtimer且此hrtimer变成红黑树leftmost的时候被调用。 
说明这是个即将过期的hrtimer。 

重新program 硬件的register后,启用设置了softirq的pending标志,说明在任何下一个软中断的环境,都会执行HRTIMER_SOFTIRQ,他的作用是手动触发一个interrupt,即调用hrtimer_interrupt(). 

最新的代码里硬中断处理函数hrtimer_interrupt()会检测leftmost的hrtimer是否过期并执行。现在是软中断环境也尝试去做同样的事情。有一点不同的是,参数wakeup,如果设置且当前是非中断上下文,要唤醒softirqd去处理,否则只是置softirq_pending标志位。 

按说设置了硬件寄存器应该等硬中断的,现在软中断环境里做重复(补充)的事情,为什么呢? 
我不敢说是“禁timer硬中断的情况下使用"这个结论。。。 



--------------------
做kernel,求内推,长期有效 

文章选项: 打印   将这篇文章放置于备忘录中,待有空时回覆   好友分享   通知版主

  加到“个人收藏夹”   |    打印

前往讨论区  

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