0
votes

Is it possible to do a context switch in the interrupt handler to schedule another process I registered before? If it is, how to?

3
To be specific , I registered an user mode irq handler in a user mode process. So when the interrupt comes, I want to jump to the user mode handler immediately, but when the current process in do_IRQ is not the process I registered before ,I want to make a context switch to get the process that I registered run.goodjesse

3 Answers

1
votes

I am not sure I understand your question correctly, but are you referring to deferring work ?

There are established ways to defer work in ISR's by using tasklets etc.

If you want to schedule a user process, one way would be to pend the user thread on a semaphore (inside the kernel) and poke the semaphore in the ISR.

0
votes

Ok first, You cannot switch context in interrupt section i.e upper half.

However you can schedule another function to run in interrupt context or process context. The way of achieving this is bottom half of interrupt handler.

1: If you want to schedule your registered function to run in interrupt context use Tasklet.

DECLARE_TASKLET(my_tasklet, functionname, 0);

irqreturn_t my_tl_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
   tasklet_schedule(&my_tasklet);
   return IRQ_HANDLED;
}

2: if you want to schedule your registered function to run in process context use workqueue.

INIT_WORK(&my_wq, (void (*)(void *)) functionname, NULL);

irqreturn_t my_tl_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
   schedule_work(&short_wq); 
   return IRQ_HANDLED;
}
0
votes

No you cannot make context switch in interrupt context. The task which is running in interrupt context cannot be preempted as scheduler is disabled.

In case of bottom half, both softirq and tasklet run in interrupt context so context switch like sleep calls are not allowed. But in case of work queue bottom half context switch is possible because it runs in process context ksoftirqd.