LinuxQuestions.org
Visit Jeremy's Blog.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 06-24-2016, 05:15 PM   #1
maduino
LQ Newbie
 
Registered: Jun 2016
Posts: 5

Rep: Reputation: Disabled
How to run longer code in an ISR - kthread isn't working


Hi,

hopefully I found the right forum to post my question. The basic setting is that I'm developing a device driver as Linux Kernel Module which listens on an interrupt of an external device. Using request_irq(ird_id, (irq_handler_t) handler, IRQF_DISABLED, "yyy", NULL); I can successfully register my callback for the interrupt. The interrupt is also fired at the right moment.

So my final source code - which I need to run after the interrupt was triggered - will take between 500 µs and 10 ms. It works just fine placing the code inside the ISR, but I learned that such "fragile" functions should be as short as possible.

I thought that a kthread would be ideal: it contains the source code to be executed and in the ISR a call to kthread_run() is short and enough to start it. Therefore my ISR looks like:

Code:
struct task_struct *task;

static irqreturn_t handler(int irq, void *data) {
    if (external_condition) {
        task = kthread_run(&thread_cb, NULL, "xxx");
    }
    return IRQ_HANDLED;
}
But when I execute this piece of code (better: the interrupt is triggered and the ISR is executed) the entire system hangs and I need to hard reset it.

Beneath some mistakes in my code (which I'll check a second time for tomorrow): is there any reason why this didn't work? How to fix it? Or is there an even better way to perform my task?

Regards,
maduino
 
Old 06-25-2016, 11:08 PM   #2
smallpond
Senior Member
 
Registered: Feb 2011
Location: Massachusetts, USA
Distribution: Fedora
Posts: 4,125

Rep: Reputation: 1260Reputation: 1260Reputation: 1260Reputation: 1260Reputation: 1260Reputation: 1260Reputation: 1260Reputation: 1260Reputation: 1260
A typical reason would be getting another interrupt before finishing processing on the first one.
 
1 members found this post helpful.
Old 06-26-2016, 04:37 AM   #3
maduino
LQ Newbie
 
Registered: Jun 2016
Posts: 5

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by smallpond View Post
A typical reason would be getting another interrupt before finishing processing on the first one.
You're totally right. I checked it and I really get a second interrupt which causes the error. I fixed it and it works :-)

Is it save to block an ISR for 250 µs? Where is the border?
 
Old 06-26-2016, 01:04 PM   #4
smallpond
Senior Member
 
Registered: Feb 2011
Location: Massachusetts, USA
Distribution: Fedora
Posts: 4,125

Rep: Reputation: 1260Reputation: 1260Reputation: 1260Reputation: 1260Reputation: 1260Reputation: 1260Reputation: 1260Reputation: 1260Reputation: 1260
250,000 nsec is a long time. The normal scheme is to do the minimum processing in the ISR, put the work on a queue, and poke the kthread. The kthread wakes up, checks the queue, and runs til its empty. If the queue is full, the ISR starts dropping work and logs an error to avoid hanging the rest of the system. The network stack doesn't even log an error, it's such a common occurrence that it just counts dropped packets and lets the TCP protocol sort it out.
 
Old 06-26-2016, 05:43 PM   #5
maduino
LQ Newbie
 
Registered: Jun 2016
Posts: 5

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by smallpond View Post
250,000 nsec is a long time. The normal scheme is to do the minimum processing in the ISR, put the work on a queue, and poke the kthread. The kthread wakes up, checks the queue, and runs til its empty. If the queue is full, the ISR starts dropping work and logs an error to avoid hanging the rest of the system. The network stack doesn't even log an error, it's such a common occurrence that it just counts dropped packets and lets the TCP protocol sort it out.
I got your point. So I went to effort and implemented both variants: the 250µs code inside the ISR and in an separate kthread which is waiting by default (through wait_event_timeout()) and "freed" (through wake_up()) by the ISR. Then I measured the performance and noticed that the kthread-variant is between 20% to 40% slower. And that's not good for me, I really need this high performance. So if I go with the code inside the ISR: which bad thing could happen?
 
Old 06-27-2016, 07:46 AM   #6
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 10,610
Blog Entries: 4

Rep: Reputation: 3905Reputation: 3905Reputation: 3905Reputation: 3905Reputation: 3905Reputation: 3905Reputation: 3905Reputation: 3905Reputation: 3905Reputation: 3905Reputation: 3905
The key idea here is that it "pokes" the thread, in order to be certain that the thread is not asleep, after first putting a new unit-of-work onto the queue (if it can). Every (productive) interrupt "wakes up the sleepyhead." It does not create the thread, nor start it: the thread is always out there.

The thread, since it does operate asynchronously, can take as long as it needs to, to complete any request. (Of course, it must be mindful that it must not monopolize kernel time, since it can't be pre-empted.)

Another strategy that is sometimes used is a "virtual device driver," which actually exposes a /dev entry (or somesuch ...) that a suitably privileged user-land daemon can use. The kernel thread hands-off the work to user-land, using ordinary and easy-to-use filesystem semantics.

As always, look through the kernel source tree (and GitHub) for "prior art." "Somebody out there has already done this ... I don't need to write this from scratch. I just need to steal 'borrow it,' then whack on it until it becomes what I need." (And then, like a good netizen, contribute it back to GitHub ...)

Last edited by sundialsvcs; 06-27-2016 at 07:50 AM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
LXer: Open source code isn't a warranty LXer Syndicated Linux News 0 10-27-2015 11:20 AM
kthread issue XDimensioN Programming 1 12-09-2014 07:00 AM
ISR routine takes longer than expected on 3.13 newhorizon101 Linux - Kernel 7 05-01-2014 09:45 AM
Wireless keyboard (working) with integral touchpad (no longer working) tharmar Ubuntu 0 07-21-2011 03:38 PM
Why this code isn't working?? Script crazygyhrous Linux - Networking 5 12-19-2005 08:38 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 12:06 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration