I would like to create my own softirq in linux kernel. Is it the right way to do that:
In the init
of the module I would like to trigger the softirq
from I'll add a call to:
394 void open_softirq(int nr, void (*action)(struct softirq_action *))
395 {
396 softirq_vec[nr].action = action;
397 }
And in the snippet I would like to raise the softirq I'll add a call to raise_softirq
function:
379 void raise_softirq(unsigned int nr)
380 {
381 unsigned long flags;
382
383 local_irq_save(flags);
384 raise_softirq_irqoff(nr);
385 local_irq_restore(flags);
386 }
And add my new softirq
in:
411 /* PLEASE, avoid to allocate new softirqs, if you need not _really_ high
412 frequency threaded job scheduling. For almost all the purposes
413 tasklets are more than enough. F.e. all serial device BHs et
414 al. should be converted to tasklets, not to softirqs.
415 */
416
417 enum
418 {
419 HI_SOFTIRQ=0,
420 TIMER_SOFTIRQ,
421 NET_TX_SOFTIRQ,
422 NET_RX_SOFTIRQ,
423 BLOCK_SOFTIRQ,
424 BLOCK_IOPOLL_SOFTIRQ,
425 TASKLET_SOFTIRQ,
426 SCHED_SOFTIRQ,
427 HRTIMER_SOFTIRQ,
428 RCU_SOFTIRQ, /* Preferable RCU should always be the last softirq */
429 MY_NEW_SOFTIRQ
430 NR_SOFTIRQS
431 };
And in here:
60 char *softirq_to_name[NR_SOFTIRQS] = {
61 "HI", "TIMER", "NET_TX", "NET_RX", "BLOCK", "BLOCK_IOPOLL",
62 "TASKLET", "SCHED", "HRTIMER", "RCU", "MY_NEW_SOFTIRQ"
63 };
As a matter of fact, the term “softirq,” which appears in the kernel source code, often denotes both kinds of deferrable functions. Another widely used term is interrupt context : it specifies that the kernel is currently executing either an interrupt handler or a deferrable function.
Generally speaking, softirqs are re-entrant functions and must explicitly protect their data structures with spin locks. Tasklets differ from softirqs because a tasklet is always serialized with respect to itself; in other words, a tasklet cannot be executed by two CPUs at the same time.
The bottom two can preempt each other, but above that is a strict hierarchy: each can only be preempted by the ones above it. For example, while a softirq is running on a CPU, no other softirq will preempt it, but a hardware interrupt can. However, any other CPUs in the system execute independently.
Tasklets are a deferral scheme that you can schedule for a registered function to run later. The top half (the interrupt handler) performs a small amount of work, and then schedules the tasklet to execute later at the bottom half.
If you want to patch the kernel and recompile it, you are doing probably right (except you should move it before RCU_SOFTIRQ).
Otherwise, IOW if you want to do it in a kernel module, you have to use tasklet, which is based on SoftIRQ, to do something in SoftIRQ context:
tasklet_init()
is used to init your hook.
tasklet_schedule()
to schedule the tasklet you register.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With