2007-05-14 06:37:29

by Learning Linux

[permalink] [raw]
Subject: Why can't we sleep in an ISR?

I have a very basic doubt here ... what makes it impossible to sleep
in an ISR? I mean, I know that the kernel preemption is disabled and
the kernel will panic, but I could not understand why?

TIA,

LL


2007-05-14 07:16:40

by Learning Linux

[permalink] [raw]
Subject: Re: Why can't we sleep in an ISR?

> > I have a very basic doubt here ... what makes it impossible to sleep
> > in an ISR? I mean, I know that the kernel preemption is disabled and
> > the kernel will panic, but I could not understand why?
>
> Because the interrupt which you are serving in the
> ISR has been masked to avoid preemption(
> true for maskable inetrrupts ).Any locks you are holding in ISR are now with
> you solely. So, if you try to sleep you take the locks you untill you are
> rescheduled and complete. This may lead to
> a deadlock for the lock resource.

Ok, but how about an ISR, that does not take any locks? Why can't we
sleep in SUCH an ISR?

AFAIK, taking a lock disables kernel preemption, and hence it is not
allowed to sleep. So I think my question would boil down to why is
sleeping not allowed when the kernel preemption is disabled.

LL

2007-05-14 12:34:25

by Helge Hafting

[permalink] [raw]
Subject: Re: Why can't we sleep in an ISR?

Learning Linux wrote:
> I have a very basic doubt here ... what makes it impossible to sleep
> in an ISR? I mean, I know that the kernel preemption is disabled and
> the kernel will panic, but I could not understand why?
First: an ISR is meant to be very quick. It is supposed to do only a
minimum of work needed to service the interrupt, then exit.
This is important, as other interrupts might be blocked during your ISR.
Sleeping is out of question, even a long-running loop in no-no.

Second: You don't ever need to sleep in an ISR anyway.
Complicated work that might take time or might need to sleep
is not supposed to be in an ISR. If you think you have a need,
tell us what you're up to and hopefully someone will explain
how do do things properly.

When an interrupt happens that needs complicated servicing, the
ISR don't do the whole job. It just acknowledges the interrupt,
perhaps does a few things with the device in question, then it
exits. It leaves the rest of the work for a bottom half or kernel
thread or something like that. Kernel threads may sleep . . .

Helge Hafting

2007-05-14 13:36:37

by Dong Feng

[permalink] [raw]
Subject: Re: Why can't we sleep in an ISR?

My understanding is as follows.

Whenever the kernel code sleeps, it means the latest process running
in user space will have to wait for the event on which the kernel code
sleeps.

It makes sense for an exception handler to sleep because an exception
handler always serves the latest process running in user space. So a
process can complain nothing for it having to wait for the event on
which the exception handler in its own context sleeps.

It makes no sense for an ISR to sleep because an ISR does not
necessarily serve the latest process (that is, the interrupted
process). It makes no sense having a process wait for the event having
nothing to do with it.

I could be wrong, so please correct me if the understanding is not right.


2007/5/14, pradeep singh <[email protected]>:
>
>
> On 5/14/07, Helge Hafting <[email protected]> wrote:
> > Learning Linux wrote:
> > > I have a very basic doubt here ... what makes it impossible to sleep
> > > in an ISR? I mean, I know that the kernel preemption is disabled and
> > > the kernel will panic, but I could not understand why?
> > First: an ISR is meant to be very quick. It is supposed to do only a
> > minimum of work needed to service the interrupt, then exit.
> > This is important, as other interrupts might be blocked during your ISR.
> > Sleeping is out of question, even a long-running loop in no-no.
> >
> > Second: You don't ever need to sleep in an ISR anyway.
> > Complicated work that might take time or might need to sleep
> > is not supposed to be in an ISR. If you think you have a need,
> > tell us what you're up to and hopefully someone will explain
> > how do do things properly.
> >
> > When an interrupt happens that needs complicated servicing, the
> > ISR don't do the whole job. It just acknowledges the interrupt,
> > perhaps does a few things with the device in question, then it
> > exits. It leaves the rest of the work for a bottom half or kernel
> > thread or something like that. Kernel threads may sleep . . .
>
> Helge, i think the Original poster wants to know why
> *exactly* cannot you sleep? What prevents me from
> sleeping?
>
> What is this complicated processing which force an ISR not to sleep?
>
> Thanks
>
> > Helge Hafting
> >
> > --
> > To unsubscribe from this list: send an email with
> > "unsubscribe kernelnewbies" to [email protected]
> > Please read the FAQ at http://kernelnewbies.org/FAQ
> >
> >
>
>
>
> --
> play the game

2007-05-14 15:22:30

by George Spelvin

[permalink] [raw]
Subject: Re: Why can't we sleep in an ISR?

Sleeping in an ISR is not fundamentally impossible - I could design
a multitasker that permitted it - but has significant problems, and
most multitaskers, including Linux, forbid it.

The first problem is the scheduler. "Sleeping" is actually a call
into the scheduler to choose another process to run. There are times -
so-called critical sections - when the scheduler can't be called.

If an interrupt can call the scheduler, then every criticial section
has to disable interrupts. Otherwise, an interrupt might arrive and
end up calling the scheduler. This increases interrupt latency.

If interrupts are forbidden to sleep, then there's no need to
disable interrupts in critical sections, so interrupts can be responded
to faster. Most multitaskers find this worth the price.

The second problem is shared interrupts. You want to sleep until something
happens. The processor hears about that event via an interrupt. Inside
an ISR, interrupts are disabled.

You have to somehow enable the interrupt that will wake up the sleeping
ISR without enabling the interrupt that the ISR is in the middle of handling
(or the handler will start a second time and make a mess).

This is complicated and prone to error. And, in the case of shared interrupts
(as allowed by PCI), it's possible that the the interrupt you need
to wait for is exactly the same interrupt as what you're in the middle
of handling. So it might be impossible!

The third problem is that you're obviously increasing the latency of the
interrupt whose handler you're sleeping in.

Finally, if you're even *thinking* of wanting to sleep in an ISR,
you probably have a deadlock waiting to happen.

2007-05-14 15:24:41

by Bahadir Balban

[permalink] [raw]
Subject: Re: Why can't we sleep in an ISR?

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

2007-05-14 15:55:27

by Rik van Riel

[permalink] [raw]
Subject: Re: Why can't we sleep in an ISR?

[email protected] wrote:
> Sleeping in an ISR is not fundamentally impossible - I could design
> a multitasker that permitted it - but has significant problems, and
> most multitaskers, including Linux, forbid it.

You could design a system in which most ISRs can sleep,
but even then you'll probably need to make exceptions.

For example, the timer interrupt tends to drive the
scheduler. This means the timer interrupt cannot go
to sleep and expect the scheduler to wake it up at
some point in the future - since there will be no new
timer interrupts to drive the scheduler.

This precludes the timer interrupt from taking certain
sleeping locks, even on a system where interrupts can
sleep (not Linux).

Interrupts will always have some limitations, under
any OS design.

--
All Rights Reversed

2007-05-14 15:56:28

by Dong Feng

[permalink] [raw]
Subject: 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
>
>

2007-05-15 06:45:53

by Dong Feng

[permalink] [raw]
Subject: Re: Why can't we sleep in an ISR?

>
> good enough, but i have a query regarding this then.
> On a 8K kernel stack system, doesn't interrupts share the stack associated
> with the current process which was interrupted?

Yes, I think so.

> Doesn't interrupt steals the CPU slice time allocated to the running process
> to run?

I don't think so but I am not sure.

> Doesn't it run in current process's context ?
>

No. I think the concept of process context is a higher-level logical
concept. Though the interrupt share stack with the interrupted
process, in my opinion it logically does not share the context with
the process.

> What am i missing here?
>
> Thanks
> ~psr
>


But I do not see the exact relationship between your specific queries
and the original question. Could you elaborate?

2007-05-15 07:28:19

by Dong Feng

[permalink] [raw]
Subject: Re: Why can't we sleep in an ISR?

> >
> > I don't think so but I am not sure.
>
> Aliter, i think so.How can an interrupt's execution time go
> unaccounted then?
> I guess it does not, only the current processes running
> time is accounted for.
> Thoughts?
>

The interrupt handler's execution time will definitely defer the
execution of the process, but I think it does not steal the process's
time slice (the time_slice field not subtracted).

> > > Doesn't it run in current process's context ?
> > >
> >
> > No. I think the concept of process context is a higher-level logical
> > concept. Though the interrupt share stack with the interrupted
> > process, in my opinion it logically does not share the context with
> > the process.
>
> Yes, you are right as i can infer. thats why ISRs
> are special kernel control paths.
> But the poster asked, why can't we make ISRs to
> share context with the interrupted process
> if
> it not holding any locks? This is rather a desing issues
> IMO rather than imlementation, isnt it?
>
> I guess even if it is possible, it would over complicate the handler code.
> Better trying to keep it simple i guess. Please CMIIW

My understanding is, the ISR is in different context from the process
because of the definition of term *context*. In my opinion, to say two
code pieces running in the same context means that two pieces of code
has some logical relationship to meet a common objective. That's why I
said *context* is a higher-level logical concept. It's not a concept
defined in the level of hardware or code implementation, but instead
in the level of logical. I think, by its definition, it makes no sense
to say an ISR share context with the process interrupted by it because
an ISR just randomly interrupts a process, with no logical
relationship.

2007-05-15 08:41:09

by Learning Linux

[permalink] [raw]
Subject: Re: Why can't we sleep in an ISR?

> The interrupt handler's execution time will definitely defer the
> execution of the process, but I think it does not steal the process's
> time slice (the time_slice field not subtracted).

It will definitely be substracted from the process's time slice.
Because the timeslice is substracted in timer interrupt, and does not
differenciate if the process is executing ISR or not.

2007-05-15 08:58:21

by Dong Feng

[permalink] [raw]
Subject: Re: Why can't we sleep in an ISR?

Yes, you are right in this regard. An interrupt handler does steal the
time slice from the interrupted process.

So now I think it is considered an acceptable deviation in calculating
the process run time as well as determine process scheduling because
an ISR should take very short time to return, in part as a consequence
of the rule that ISR should not sleep.


2007/5/15, Learning Linux <[email protected]>:
> > The interrupt handler's execution time will definitely defer the
> > execution of the process, but I think it does not steal the process's
> > time slice (the time_slice field not subtracted).
>
> It will definitely be substracted from the process's time slice.
> Because the timeslice is substracted in timer interrupt, and does not
> differenciate if the process is executing ISR or not.
>

2007-05-15 16:57:39

by Phillip Susi

[permalink] [raw]
Subject: Re: Why can't we sleep in an ISR?

Dong Feng wrote:
>> Doesn't it run in current process's context ?
>>
>
> No. I think the concept of process context is a higher-level logical
> concept. Though the interrupt share stack with the interrupted
> process, in my opinion it logically does not share the context with
> the process.

No, the term context here has a specific meaning. It refers to those
things which flow from the current pointer, including the virtual memory
space, file descriptor table, current uid, and so forth. Because the
current pointer is not changed on entry to an ISR, the ISR is executing
in the context of the interrupted process, and thus uses that process'
virtual memory, etc.


2007-05-15 17:24:42

by David Schwartz

[permalink] [raw]
Subject: RE: Why can't we sleep in an ISR?


> No, the term context here has a specific meaning. It refers to those
> things which flow from the current pointer, including the virtual memory
> space, file descriptor table, current uid, and so forth.

And none of these things are used by an ISR.

> Because the
> current pointer is not changed on entry to an ISR, the ISR is executing
> in the context of the interrupted process, and thus uses that process'
> virtual memory, etc.

You mean it would be if it ever looked at the current pointer. It is not the
setting of the current pointer that determines the context but actually
*using* that pointer.

As you said, it is the "things which flow from the current pointer" that
matter, not the value of the pointer itself. An ISR uses none of those
things.

DS


2007-05-15 22:49:28

by Dong Feng

[permalink] [raw]
Subject: Re: Why can't we sleep in an ISR?

2007/5/16, Phillip Susi <[email protected]>:
> Dong Feng wrote:
> >> Doesn't it run in current process's context ?
> >>
> >
> > No. I think the concept of process context is a higher-level logical
> > concept. Though the interrupt share stack with the interrupted
> > process, in my opinion it logically does not share the context with
> > the process.
>
> No, the term context here has a specific meaning. It refers to those
> things which flow from the current pointer, including the virtual memory
> space, file descriptor table, current uid, and so forth. Because the
> current pointer is not changed on entry to an ISR, the ISR is executing
> in the context of the interrupted process, and thus uses that process'
> virtual memory, etc.
>

If what you say were true, then an ISR would be running in the same
context as the interrupted process. But please check any article or
book, it will say ISR running in different context from any process.
So ISR is considered in its own context, although it shares a lot of
things with the interrupted process. I would only say *context* is a
higher-level logical concept.

2007-05-16 15:20:52

by Phillip Susi

[permalink] [raw]
Subject: Re: Why can't we sleep in an ISR?

Dong Feng wrote:
> If what you say were true, then an ISR would be running in the same
> context as the interrupted process.

Yes, and it is, as others have said in this thread, which is a good
reason why ISRs can't sleep.

> But please check any article or
> book, it will say ISR running in different context from any process.
> So ISR is considered in its own context, although it shares a lot of
> things with the interrupted process. I would only say *context* is a
> higher-level logical concept.

Depends on which book or article you are reading I suppose. The
generally accepted and often used thought is that ISRs technically are
running in the context of the interrupted process, but because that
context is unknown and therefore should not be used, it is often said
that they run in no context, or outside of any context. Sometimes
people then assume that because they run outside of any ( particular )
process context, they must be in their own context, but this is a mistake.


2007-05-16 23:17:47

by Dong Feng

[permalink] [raw]
Subject: Re: Why can't we sleep in an ISR?

OK. I think the gap between you and me is the definition of term
*context*. If you go to Linux Kernel Development, 2nd Edition (ISBN
0-672-32720-1), Page 6, then you will read the following:

.... in Linux, ... each processor is doing one of three things at any
given moment:

1. In kernel-space, in process context, ...
2. In kernel-space, in interrupt context, not associated with a process, ...
3. In user-space ...

This list is inclusive. ...


Maybe you prefer other terminology system, but I do like the above
definition given by Robert Love. So maybe in your system *context*
mean something at hardware level and you say ISR is in process
context, but I think it is more like a logical level and agree with
Rovert's definition.

And in hardware level, Robert's *context* definition also mean
something specific, that I started to be aware of. That is, *in the
same context* means a kernel-code is triggered by a user-space code.
*in different context* means a kernel-code is triggered by an external
interrupt source other than a user-space code.

Context has nothing to do with whether an ISR borrow any data
structure of a process, instead, its something logical or related to
causality.



2007/5/16, Phillip Susi <[email protected]>:
> Dong Feng wrote:
> > If what you say were true, then an ISR would be running in the same
> > context as the interrupted process.
>
> Yes, and it is, as others have said in this thread, which is a good
> reason why ISRs can't sleep.
>
> > But please check any article or
> > book, it will say ISR running in different context from any process.
> > So ISR is considered in its own context, although it shares a lot of
> > things with the interrupted process. I would only say *context* is a
> > higher-level logical concept.
>
> Depends on which book or article you are reading I suppose. The
> generally accepted and often used thought is that ISRs technically are
> running in the context of the interrupted process, but because that
> context is unknown and therefore should not be used, it is often said
> that they run in no context, or outside of any context. Sometimes
> people then assume that because they run outside of any ( particular )
> process context, they must be in their own context, but this is a mistake.
>
>
>

2007-05-17 16:06:56

by Phillip Susi

[permalink] [raw]
Subject: Re: Why can't we sleep in an ISR?

Dong Feng wrote:
> OK. I think the gap between you and me is the definition of term
> *context*. If you go to Linux Kernel Development, 2nd Edition (ISBN
> 0-672-32720-1), Page 6, then you will read the following:
>
> .... in Linux, ... each processor is doing one of three things at any
> given moment:
>
> 1. In kernel-space, in process context, ...
> 2. In kernel-space, in interrupt context, not associated with a process,
> ...
> 3. In user-space ...
>
> This list is inclusive. ...

Yep, I disagree with that use of the term, because it is misleading and
caused your confusion. The context that the ISR executes in is not
associated with a _known_ process is more correct.

> Maybe you prefer other terminology system, but I do like the above
> definition given by Robert Love. So maybe in your system *context*
> mean something at hardware level and you say ISR is in process
> context, but I think it is more like a logical level and agree with
> Rovert's definition.
>
> And in hardware level, Robert's *context* definition also mean
> something specific, that I started to be aware of. That is, *in the
> same context* means a kernel-code is triggered by a user-space code.
> *in different context* means a kernel-code is triggered by an external
> interrupt source other than a user-space code.

Right, and that becomes more clear when you say that the ISR's is
executing in an indeterminate process context, rather than saying it
does not have any context at all, or has its own special context.

> Context has nothing to do with whether an ISR borrow any data
> structure of a process, instead, its something logical or related to
> causality.

No, it has everything to do with the data structures of the process.
When you are executing "in the same context" as you put it, as called
from the user mode code, you know you are using the task structure of
that process and so you can make use of that structure. For example,
you can look at the current uid to decide if you should allow an
operation to proceed. When you are in an ISR, there _is_ a task
structure there, but you shouldn't use it because you don't know which
task structure it is because you don't know which task you are
interrupting. Thus if you look at the current uid in an ISR, you have
no idea what you will see there and it will change from interrupt to
interrupt, depending on which task gets interrupted.


2007-05-17 23:51:03

by Dong Feng

[permalink] [raw]
Subject: Re: Why can't we sleep in an ISR?

Hi, Phillip,

I have said the gap between you and me is the definition of context.
In Robert's definition, *context* is used in a classification method
and really something in higher-level. And I used that term to explain
why ISR can not sleep.

If you do not like the name, name it your way and substitute term
*context* in my previous mail with what you name. But I believe my
other explaination still hold, right?

And again, if anyway I am forced to use your termnology system, I
would also agree your other point regarding hardware.


2007/5/18, Phillip Susi <[email protected]>:
> Dong Feng wrote:
> > OK. I think the gap between you and me is the definition of term
> > *context*. If you go to Linux Kernel Development, 2nd Edition (ISBN
> > 0-672-32720-1), Page 6, then you will read the following:
> >
> > .... in Linux, ... each processor is doing one of three things at any
> > given moment:
> >
> > 1. In kernel-space, in process context, ...
> > 2. In kernel-space, in interrupt context, not associated with a process,
> > ...
> > 3. In user-space ...
> >
> > This list is inclusive. ...
>
> Yep, I disagree with that use of the term, because it is misleading and
> caused your confusion. The context that the ISR executes in is not
> associated with a _known_ process is more correct.
>
> > Maybe you prefer other terminology system, but I do like the above
> > definition given by Robert Love. So maybe in your system *context*
> > mean something at hardware level and you say ISR is in process
> > context, but I think it is more like a logical level and agree with
> > Rovert's definition.
> >
> > And in hardware level, Robert's *context* definition also mean
> > something specific, that I started to be aware of. That is, *in the
> > same context* means a kernel-code is triggered by a user-space code.
> > *in different context* means a kernel-code is triggered by an external
> > interrupt source other than a user-space code.
>
> Right, and that becomes more clear when you say that the ISR's is
> executing in an indeterminate process context, rather than saying it
> does not have any context at all, or has its own special context.
>
> > Context has nothing to do with whether an ISR borrow any data
> > structure of a process, instead, its something logical or related to
> > causality.
>
> No, it has everything to do with the data structures of the process.
> When you are executing "in the same context" as you put it, as called
> from the user mode code, you know you are using the task structure of
> that process and so you can make use of that structure. For example,
> you can look at the current uid to decide if you should allow an
> operation to proceed. When you are in an ISR, there _is_ a task
> structure there, but you shouldn't use it because you don't know which
> task structure it is because you don't know which task you are
> interrupting. Thus if you look at the current uid in an ISR, you have
> no idea what you will see there and it will change from interrupt to
> interrupt, depending on which task gets interrupted.
>
>
>