| ||
在慢速中断的过程中,允许别的中断发生 | ||
|
| ||
2.4中还有慢速中断吗? | ||
|
| ||
有,其实就是软中断. | ||
|
| ||
你好快,就成newbie了,我努力了好几个月才成newbie | ||
|
| ||
我觉得首先讲一下LINUX的内核机制: | ||
|
| ||
从他的意思来看就是软中断. | ||
|
| ||
我想你没有理解他的意思。他说的慢速中断是指没有SA_INTERRUPT标志的中断。 int handle_IRQ_event(unsigned int irq, struct pt_regs * regs, struct irqaction * action)
{
int status;
int cpu = smp_processor_id();
irq_enter(cpu, irq);
status = 1; /* Force the "do bottom halves" bit */
/*慢速中断则开中断*/ if (!(action->flags & SA_INTERRUPT)) __sti();
do {
status |= action->flags;
action->handler(irq, action->dev_id, regs);
action = action->next;
} while (action);
if (status & SA_SAMPLE_RANDOM)
add_interrupt_randomness(irq);
__cli();
irq_exit(cpu, irq);
return status;
}
| ||
|
| ||
我觉得这个好象包括在软中断的机制里面吧? | ||
|
| ||
你这里采用的就是软中断的机制之一的BH机制. | ||
|
| ||
有没搞错?handle_IRQ_event()是IRQ!是硬中断! | ||
|
| ||
wheelz说得对,我说的慢速中断就是慢速中断,不是软中断 | ||
|
| ||
>你这里采用的就是软中断的机制之一的BH机制. | ||
|
| ||
你只知道其一,不知道其二,作为优化,软中断未必就必须那么执行,在没有其他硬中断的时候,就直接执行算了,你以为DO_IRQ里面的检查是做什么的呀?首先把ACTION=NULL的那一段的代码, | ||
|
| ||
在执行硬中断的时候,如果没有检测到其他的高级中断,直接执行他的软中断算了.因此,从概念上说,他是属于软中断的,尽管他同硬中断一道执行的. | ||
|
| ||
没有搞错,你假设一在他里面发生了高级的中断,他怎么处理?假设这个中断发生在其他的低级中断中,他怎么处理?还能执行到这个 IRQ_HANLDLER_EVENT么?不能,只能作为软中断执行了.这里做为优化,在没有检测到其他高级的中断的时候,直接就在硬中断后面把软中断执行掉了算了,从实际来讲,他是在硬中断之后执行的,但从概念上,他是属于软中断的范畴. | ||
|
| ||
你仔细看一ULK2的4.6和4.7节,看看hande_IRQ_event 是不是书上所讲的deferrable function的涵义. | ||
|
| ||
我都懒得跟你争,你居然认为handle_IRQ_event()是软中断? | ||
|
| ||
书上所讲的deferrable function指的是bottom half和tasklet,它们是由do_softirq调用的,而不是hande_IRQ_event. | ||
|
| ||
好,既然有处理软中断的例程,那么我问:软中断在哪里产生的?也就是说,在什么地方,硬中断把软中断挂入队列?你只能在DO_IRQ中找. | ||
|
| ||
硬中断只产生中断请求队列,我确实不知道,硬中断还要处理中断请求.按照你的理解,第一个中断产生了一个handle_IRQ_event1中产生了一个中断2,它应该包含一个handle_IRQ_event2,只要没有被别的中断打断的话,就该执行完,那不就是event2在event1中执行了么? 你没有办法确定event2和event1是不是一个中断,假设是一个中断呢?你就必须考虑你的中断程序的可重入的问题.这无疑增加了驱动程序开发的难度. | ||
|
| ||
我想问题已经很清楚了,这只是一个概念上的问题,并没有谁对谁错,在争下去也没有什么意义,我觉得我或者freshground或者wheelz是不会被你说服的,你觉得你会被我们说服吗?:) | ||
|
| ||
呵呵,“懒得和你争”其实是我调侃的气话,我愿意向你道歉:-)。 /*
* do_IRQ handles all normal device IRQ's (the special
* SMP cross-CPU interrupts have their own specific
* handlers).
*/
asmlinkage unsigned int do_IRQ(struct pt_regs regs)
{
/*
* We ack quickly, we don't want the irq controller
* thinking we're snobs just because some other CPU has
* disabled global interrupts (we have already done the
* INT_ACK cycles, it's too late to try to pretend to the
* controller that we aren't taking the interrupt).
*
* 0 return value means that this irq is already being
* handled by some other CPU. (or is disabled)
*/
int irq = regs.orig_eax & 0xff; /* high bits used in ret_from_ code */
int cpu = smp_processor_id();
irq_desc_t *desc = irq_desc + irq;
struct irqaction * action;
unsigned int status;
#ifdef CONFIG_DEBUG_STACKOVERFLOW
long esp;
/* Debugging check for stack overflow: is there less than 1KB free? */
__asm__ __volatile__("andl %%esp,%0" : "=r" (esp) : "0" (8191));
if (unlikely(esp < (sizeof(struct task_struct) + 1024))) {
extern void show_stack(unsigned long *);
printk("do_IRQ: stack overflow: %ld\n",
esp - sizeof(struct task_struct));
__asm__ __volatile__("movl %%esp,%0" : "=r" (esp));
show_stack((void *)esp);
}
#endif
kstat.irqs[cpu][irq]++;
spin_lock(&desc->lock);
desc->handler->ack(irq);
/*
REPLAY is when Linux resends an IRQ that was dropped earlier
WAITING is used by probe to mark irqs that are being tested
*/
status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
status |= IRQ_PENDING; /* we _want_ to handle it */
/*
* If the IRQ is disabled for whatever reason, we cannot
* use the action we have.
*/
action = NULL;
if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
action = desc->action;
status &= ~IRQ_PENDING; /* we commit to handling */
status |= IRQ_INPROGRESS; /* we are handling it */
}
desc->status = status;
/*
* If there is no IRQ handler or it was disabled, exit early.
Since we set PENDING, if another processor is handling
a different instance of this same irq, the other processor
will take care of it.
*/
if (!action)
goto out;
/*
* Edge triggered interrupts need to remember
* pending events.
* This applies to any hw interrupts that allow a second
* instance of the same irq to arrive while we are in do_IRQ
* or in the handler. But the code here _disibledevent="darktable" valign="top" width="2%" rowspan="2"> |
| |
"呵呵,“懒得和你争”其实是我调侃的气话,我愿意向你道歉:-)。" | ||
|
| ||
我觉得还是你们的有道理,在我仔细对照了ULK2和LDD2等资料之后,只是碰巧我找到了别人的学习笔记,理解的同我差不多,哈哈,也犯了和我一样的错误,转贴如下(太长了,只搞连接): |
内核线程、软中断和定时器有何区别
最新推荐文章于 2024-08-13 22:16:23 发布
本文讨论了内核线程、软中断和定时器的区别,重点解释了软中断的概念及其与慢速中断的关系。通过分析Linux内核源代码,明确了软中断的工作原理和应用场景。
2301

被折叠的 条评论
为什么被折叠?



