How to leave interrupt state?

Sep 04, 2006 3 Replies

Hello!



I'm busy debugging a broken harddisk driver of an embedded device and have traced down the error condition. In the irq-handler there is a race condition that can lead to another irq of the same type being issued while the irq-handler hasn't terminated yet (only a few ns or us missing...). Since an irq cannot be interrupted by an irq of the same level, the irq gets lost and things start to go wrong badly. Now I'm not at all a kernel-guru so I need to ask for a tiny thing that should solve this problem: in a 2.4 kernel, how do I leave irq-level (without doing a "return") so that the irq-handler get interruptible? In assembly this would just mean to clear the irq-bit in the processor's status register (talking about ARM) but I don't know how to do this in C. Surely there is a kernel function for this?



Thanks a lot, Philipp.



A kind kernel maintainer has helped me with this. He told me that there was no such function. So I changed the implementation and now use the traditional bottom-half approach. And suddenly it works fine (surprise, surprise). I don't know why the original author of the module didn't do this in the first place...

Thanks, Philipp.

How do you know this? By far the biggest problem of missing interrupts is to spend way to long in the interrupt routine. In 2.4 use a bottom half for your long term processing. If you truly have an interrupt less than a few microseconds after another one, then something different is wrong.

This would be a bad idea. How would you ever exit the interrupt routine? Hard disks are really slow compared to a processor. You are doing something else wrong (this is not the droid you are looking for "starwars 1 or 4 depending on how you count").

There is no "x" in my email address.

Steve Calfee schrieb:

Well, the code starts writing to the hdd registers on irq-level, enables the irq. And under some circumstances I get timeouts for the interrupt although according to the hdd's status registers everything was fine. So if the interrupt never got to the irq-handler, to me the only reason would be that it is blocked by the code still running on irq-level.

And I guess getting the next request from the ide-layer is way too long to spend on irq-level... ;)

Now I do and everything is fine. I hesitated to do so because the original driver author wrote in a comment in the source code that he preferred his (strange) mechanism over a bottom-half because it was faster and speed was critical. It's not true.

Just taking the usual exit. At least from my assembly-based and limited understanding this should work fine as it will restore the original processor status. And it wouldn't matter if we did that from irq-level or already on normal level.

First, the processor is really slow, too. And I suspect this situation to appear when there is data in the hdd cache. So the interrupt could get there fast, I guess. But anyway, now with the bottom half everything is fine and no need to wonder what actually went wrong... :)

Thanks!

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required