Soft interrupt processing in Linux kernel __linux

Source: Internet
Author: User

The soft interrupts defined by the Linux kernel are as follows:

static struct Softirq_actionsoftirq_vec[nr_softirqs] __CACHELINE_ALIGNED_IN_SMP;

Char *softirq_to_name[nr_softirqs] = {

"HI", "TIMER", "Net_tx", "Net_rx", "block",

"Tasklet", "SCHED", "Hrtimer", "RCU"

};

The soft interrupts registered during kernel startup are as follows.


Its registration function is:

void Open_softirq (int nr, void (*action) (struct softirq_action *))

{

softirq_vec[nr].action= Action;

}

is actually initializing the globally defined array variable Softirq_actionsoftirq_vec[nr_softirqs].

Enum

{

Hi_softirq=0,

TIMER_SOFTIRQ,

NET_TX_SOFTIRQ,

NET_RX_SOFTIRQ,

BLOCK_SOFTIRQ,

TASKLET_SOFTIRQ,

SCHED_SOFTIRQ,

HRTIMER_SOFTIRQ,

RCU_SOFTIRQ,/* Preferable RCU should always be the LASTSOFTIRQ * *

Nr_softirqs

}; The registration function is as follows:

OPEN_SOFTIRQ (hi_softirq,tasklet_hi_action);

OPEN_SOFTIRQ (TIMER_SOFTIRQ,RUN_TIMER_SOFTIRQ);

OPEN_SOFTIRQ (net_tx_softirq,net_tx_action);

OPEN_SOFTIRQ (net_rx_softirq,net_rx_action);

OPEN_SOFTIRQ (BLOCK_SOFTIRQ,BLK_DONE_SOFTIRQ);

OPEN_SOFTIRQ (tasklet_softirq,tasklet_action);

OPEN_SOFTIRQ (Sched_softirq,run_rebalance_domains);

OPEN_SOFTIRQ (HRTIMER_SOFTIRQ, RUN_HRTIMER_SOFTIRQ);

Each CPU in an IRQ has a structure

typedef struct {

Unsignedlong __softirq_pending;

} ____cacheline_aligned irq_cpustat_t; The interrupt handler function used to hold the current CPU for waiting.

As you can see in previous articles, function irq_exit (void) is invoked after each execution of the DO_IRQ () end of the system. In this function, the processing software is interrupted,

/*

*exit an interrupt. Process Softirqs if needed and possible:

*/

void Irq_exit (void)

{

Account_system_vtime (current);

Trace_hardirq_exit ();

Sub_preempt_count (Irq_exit_offset);

if (!in_interrupt () && local_softirq_pending ())//indicates that the processing software is interrupted without the interrupt environment.

INVOKE_SOFTIRQ ();//There is a software interrupt exists, then execute.

#ifdef CONFIG_NO_HZ

/*make sure that timer wheel updates are propagated * *

Rcu_irq_exit ();

if (Idle_cpu (smp_processor_id ()) &&!in_interrupt () &&!need_resched ())

Tick_nohz_stop_sched_tick (0);

#endif

Preempt_enable_no_resched ();

}

#ifdef __arch_irq_exit_irqs_disabled

# define INVOKE_SOFTIRQ () __DO_SOFTIRQ ()

#else

# define INVOKE_SOFTIRQ () DO_SOFTIRQ ()

#endif

its DO_SOFTIRQ () function is defined as follows: There is a similar logic in the function.

asmlinkage void Do_softirq (void)

{

__u32pending;

Unsignedlong flags;

if (In_interrupt ())

Return

Local_irq_save (flags);

pending= local_softirq_pending ()//There is a software interrupt pending and execution of the pending break.

if (pending)

__DO_SOFTIRQ ();

Local_irq_restore (flags);

}

#endif

In the processing software, the kernel defines a kernel thread to handle soft interrupt requests that cannot be processed in a timely manner. The function is:

static int ksoftirqd (void * __bind_cpu);

#define Max_softirq_restart 10

asmlinkage void __do_softirq (void)

{

---------------

h = softirq_vec;

do{

if (pending & 1) {

Intprev_count = Preempt_count ();

KSTAT_INCR_SOFTIRQS_THIS_CPU (H-softirq_vec);

Trace_softirq_entry (H,softirq_vec);

h->action (h);

Trace_softirq_exit (H,softirq_vec);

if (Unlikely (Prev_count!= Preempt_count ())) {

PRINTK (Kern_err "Huh, entered Softirq%td%s%p"

"With Preempt_count%08x,"

"Exited with%08x?\n", H-softirq_vec,

Softirq_to_name[h-softirq_vec],

H->action, Prev_count,preempt_count ());

Preempt_count () = Prev_count;

}

Rcu_bh_qsctr_inc (CPU);

}

h++;

pending >>= 1;

}while (pending);

Local_irq_disable ();

pending =local_softirq_pending ();

if (pending &&--max_restart)

goto Restart;

if (pending)

wakeup_softirqd ();

Lockdep_softirq_exit ();

Account_system_vtime (current);

_local_bh_enable ();

}

In the __DO_SOFTIRQ () function, handle a pending soft interrupt, with the pending bit to determine if there is an interrupt suspend.

When it reaches (max_restart==0), the pending is not 0. Called the function wakeup_softirqd ();

the creation of kernel threads can refer to other articles.

Switch (action) {

Casecpu_up_prepare:

Casecpu_up_prepare_frozen:

p = kthread_create (KSOFTIRQD, Hcpu, "ksoftirqd/%d", hotcpu);

 

Tasklet

struct TASKLET_STRUCT

{

Structtasklet_struct *next;

Unsignedlong State;

Atomic_tcount;

void (*func) (unsigned long);

Unsignedlong data;

};

There are two types of tasklet in the Linux kernel,

Its tasklet initialization is as follows:

void Tasklet_init (struct tasklet_struct*t,void (*func) (unsigned long), unsigned Long data)

{

T->next= NULL;

T->state= 0;

Atomic_set (&t->count,0);

t->func= func;

T->data= data;

}

After the Tasklet is initialized, it is added to the Tasklet queue.

the lower priority Tasklet scheduling functions are as follows:

static inline void Tasklet_schedule (structtasklet_struct *t)

{

if (!test_and_set_bit (tasklet_state_sched, &t->state))

__tasklet_schedule (t);

}

void __tasklet_schedule (Structtasklet_struct *t)

{

Unsignedlong flags;

Local_irq_save (flags);

T->next= NULL;

*__get_cpu_var (Tasklet_vec). tail= T;

__get_cpu_var (Tasklet_vec). Tail= & (T->next);

Raise_softirq_irqoff (TASKLET_SOFTIRQ);/Request soft interrupt.

Local_irq_restore (flags);

}

the scheduling functions for high-priority Tasklet are as follows:

Static inline Voidtasklet_hi_schedule (struct tasklet_struct *t)

{

if (!test_and_set_bit (tasklet_state_sched, &t->state))

__tasklet_hi_schedule (t);

}

void __tasklet_hi_schedule (Structtasklet_struct *t)

{

Unsignedlong flags;

Local_irq_save (flags);

T->next= NULL;

*__get_cpu_var (Tasklet_hi_vec). tail= T;

__get_cpu_var (Tasklet_hi_vec). Tail= & (T->next);

Raise_softirq_irqoff (HI_SOFTIRQ);/Request soft interrupt.

Local_irq_restore (flags);

}

With the above two-group functions, the Tasklet are placed in different Tasklet_vec and Tasklet_hi_vec queues.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.