免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: cskyrain
打印 上一主题 下一主题

中断处理程序为什么不能阻塞休眠???以前真没认真思考过! [复制链接]

论坛徽章:
0
11 [报告]
发表于 2009-11-24 22:43 |只看该作者

回复 #8 snail_314 的帖子

“在设计上的原因,而非实现上。”
我感觉也是可以休眠,被切换出去的,而且也可以再切换回来,但ulk上的理由貌似说不行(好像意思是切换不回来了,我的理解)。有点晕啊。

论坛徽章:
0
12 [报告]
发表于 2009-11-24 22:45 |只看该作者

回复 #10 mik 的帖子

这个中断函数调用sleep,sleep里面会调用schedule啊?

论坛徽章:
0
13 [报告]
发表于 2009-11-24 22:57 |只看该作者

re

中断不是不能睡眠;

中断如果睡眠;
比如,运行中的进程,来个中断,而该中断睡眠,
因为你这个中断不返回,那么被中断的进程也无法继续运行,
就如同该进程睡眠了一样,而进程睡眠不是我们想要的结果;

我的进程和你的中断可能毫无瓜葛,可是因为你中断了我然后睡眠,而我无法再运行一直到你返回;

多次中断睡眠嵌套,内核态堆栈也许就溢出了;

论坛徽章:
0
14 [报告]
发表于 2009-11-24 23:01 |只看该作者

回复 #11 cskyrain 的帖子

在linux-newbies上有人讨论这个话题,这个兄弟的意思和我的想法差不多:

Re: Why can't we sleep in an ISR?
I agree that the reason an interrupt can not sleep is because an
interrupt is not associated with any context. But I do not agree that
it is specifically because the scheduler can not *resume* the context.

In early version, the ISR always borrow the stack of the currently
running process, so if the kernel design had allowed ISR sleep, it
would automatically be able to implement the context switch naturally.
But ISR sleep has been forbidden from the very beginning.

The reason why kernel design does not allow ISR sleep is because a
process should not be forced to wait for a event that irrelative to
itself. When an exception handler sleep, the event it sleeps on is
always in some sense related to the process incurring that exception.
But if an ISR was allowed to sleep, the event it sleeps on would have
nothing to do with the process being interrupted.

So my understanding is, the forbidden of ISR sleep is not because of
the difficulty to resume context, but because a process should not
wait for irrelative event.


2007/5/14, Bahadir Balban <[EMAIL PROTECTED]>:

    On 5/14/07, Learning Linux <[EMAIL PROTECTED]> wrote:
    > Ok, but how about an ISR, that does not take any locks? Why can't we
    > sleep in SUCH an ISR?
    > LL
    > -

    The killer reason why you can't sleep in an interrupt is because an
    interrupt is not associated with any context in the first place. What
    is a context, then? It is the state information for a process. This
    includes the kernel and userspace stack pointers, the register set,
    and the page tables for that process. The scheduler has access to all
    this information, to preempt one process and run another. Contrary to
    this, an interrupt, depending on the version of your kernel and arch,
    uses a separate irq stack or the kernel stack of the interrupted
    process. An irq is not a context but merely a temporary execution to
    be concluded asap.

    Hope this helps,
    Bahadir

    --
    To unsubscribe from this list: send an email with
    "unsubscribe kernelnewbies" to [EMAIL PROTECTED]
    Please read the FAQ at http://kernelnewbies.org/FAQ

论坛徽章:
0
15 [报告]
发表于 2009-11-24 23:17 |只看该作者
原帖由 snail_314 于 2009-11-24 22:45 发表
这个中断函数调用sleep,sleep里面会调用schedule啊?


sleep() 里会调用 schedule() 吗?

你能不能找一找 sleep() 实现来看一看,我 kernel 不了解。

论坛徽章:
0
16 [报告]
发表于 2009-11-24 23:17 |只看该作者

回复 #14 snail_314 的帖子

Contrary to
    this, an interrupt, depending on the version of your kernel and arch,
    uses a separate irq stack or the kernel stack of the interrupted
    process. An irq is not a context but merely a temporary execution to
    be concluded asap.

呵呵,上面和下面的那个是回复啊,下面的解释中 a separate irq stack,到有可能成为切换不会来的一种原因。

论坛徽章:
0
17 [报告]
发表于 2009-11-25 01:27 |只看该作者
从ULK3的原话来说,他说了KERNEL STACK IS TIGHTLY BOUND WITH CURRENT PROCESS. 也就是说,如果你进行了调度,CURRENT变了的话,KERNEL STACK也就会变了.
其实最彻底的方法是把调度那部分(SHCEDULE()函数)找出来看看,看它如何处理Kernel STACK就知道了. 或者用个简单的方法,自己写个DRIVER, 在ISR里SLEEP或者调用下SCHEDULE一下,看看会如何.

我觉得如果抛开LINUX, 仅从CPU 的角度来说,你是可以在ISR里再调用SCHEDULE的. 也就是说你可以自己写个OS, 自己维护KERNEL STACK. CPU应该可以支持. 不过LINUX也许没有这么做就是了.

论坛徽章:
0
18 [报告]
发表于 2009-11-25 01:28 |只看该作者

回复 #15 mik 的帖子

应该会调用的.即使没调用,你也可以在ISR里自己调用SCHEDULE函数.

论坛徽章:
0
19 [报告]
发表于 2009-11-25 09:15 |只看该作者

回复 #17 accessory 的帖子

你和snail_314的观点应该是一致的,呵呵,我比较支持这种看法,不是不能休眠,是linux 不让他休眠。
不过现在这可能是错的了,ulk中说的这个内核栈属于当前进程可能是过时的了,lkd中提到一种中断栈,这种栈由所有中断处理程序共享,不属于任何进程,所以这种情况应该是切换不回来了。

按照这种说法,新内核的改进,使中断成为了真正的不可休眠了。老内核还是有可能实现中断休眠,而新内核根本没这种可能了。

论坛徽章:
0
20 [报告]
发表于 2009-11-25 10:54 |只看该作者
原帖由 mik 于 2009-11-24 21:38 发表
中断不能被阻塞,要看什么情形之下:


1、大部分情况下,中断里不允许再发生中断,中断发生后 processor 会屏蔽“可屏蔽中断”,拒绝响向其它“可屏蔽中断”。

2、在中断发生另一个异常,是不能被屏蔽的 ...


要看代码,不要光看书

/*
* Have got an event to handle:
*/
fastcall int handle_IRQ_event(unsigned int irq, struct pt_regs *regs,
                                struct irqaction *action)
{
        int ret, retval = 0, status = 0;

    /*
     * The SA_INTERRUPT flag of the main IRQ descriptor determines whether
     * interrupts must be enabled or disabled when the do_IRQ( ) function
     * invokes an ISR
     */
        if (!(action->flags & SA_INTERRUPT))
                local_irq_enable();

        do {
                ret = action->handler(irq, action->dev_id, regs);
                if (ret == IRQ_HANDLED)
                        status |= action->flags;
                retval |= ret;
                action = action->next;
        } while (action);

        if (status & SA_SAMPLE_RANDOM)
                add_interrupt_randomness(irq);

    /*
     * be careful, this may pop the last saved context in kernel stack, that
     * may make tragedy, by chenj
     */
        local_irq_disable();
        return retval;
}

at kernel/irq/handle.c
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP