Day28 softirq, tasklet, workqueue

前言

昨天连滚带爬的走出了 interrupt的泥淖,希望之後能够有空把他弄得更清楚,今天要讲的东西是下半部的 interrupt处理。

softirq

softirq 对应hardirq,只是softirq是纯软件的处理。目前softirq的数量已经固定了,并不会有其他增加,底下是在linux的注释,表示几乎所有想做的行为都可以利用tasklet完成,请避免增加新的softirq。

PLEASE, avoid to allocate new softirqs, if you need not really high
frequency threaded job scheduling. For almost all the purposes
tasklets are more than enough. F.e. all serial device BHs et
al. should be converted to tasklets, not to softirqs.

以下是在程序码中利用枚举静态声明softirq

enum
{
	HI_SOFTIRQ=0,
	TIMER_SOFTIRQ,
	NET_TX_SOFTIRQ,
	NET_RX_SOFTIRQ,
	BLOCK_SOFTIRQ,
	IRQ_POLL_SOFTIRQ,
	TASKLET_SOFTIRQ,
	SCHED_SOFTIRQ,
	HRTIMER_SOFTIRQ, /* Unused, but kept as tools rely on the
			    numbering. Sigh! */
	RCU_SOFTIRQ,    /* Preferable RCU should always be the last softirq */

	NR_SOFTIRQS
};

HI_SOFTIRQ=0 : 优先级最高的softirq
TIMER_SOFTIRQ : 用於计时器的softirq
NET_TX_SOFTIRQ: 发送网路封包的softirq
NET_RX_SOFTIRQ: 接收网路封包的softirq
BLOCK_SOFTIRQ: 用於block device的softirq
IRQ_POLL_SOFTIRQ: 用於block device的softirq
TASKLET_SOFTIRQ: 专门给 tasklet 调用的softirq
SCHED_SOFTIRQ: 用在排程与负载平衡
HRTIMER_SOFTIRQ: 高精度的计时器
RCU_SOFTIRQ: 服务RCU的softirq

NR_SOFTIRQS

tasklet

利用软中断实现的下半部中断处理机制,在linux可以看见 tasklet_struct 的结构,在稍後会看见。
tasklet 有几个性质

  • 可以动态的创建与删除
  • 使用 tasklet_schedule()函数之後,tasklet至少会在某个CPU上执行一次
    以下是tasklet的结构
struct tasklet_struct
{
	struct tasklet_struct *next;
	unsigned long state;
	atomic_t count;
	void (*func)(unsigned long);
	unsigned long data;
};

next :多个tasklet可以组成链表,指向下一个tasklet
stateTASKLET_STATE_SCHED表示tasklet已经被排程,TASKLET_STATE_RUN代表tasklet正在运行。
count : 若不为0代表该tasklet不允许执行。
func :代表tasklet的处理程序。
data :传递参数给tasklet。

利用open_softirq可以注册一个softirq, 利用 raise_softirq 可以主动触发softirq

void open_softirq(int nr, void (*action)(struct softirq_action *))
{
    softirq_vec[nr].action = action;
}

void raise_softirq(unsigned int nr)
{
    unsigned long flags;

    local_irq_save(flags);
    raise_softirq_irqoff(nr);
    local_irq_restore(flags);
}

workqueue

工作伫列(work queue)是另外一种将工作推後执行的形式,它和前面讨论的tasklet有所不同。工作伫列可以把工作推後,交由一个核心执行绪去执行,也就是说,这个下半部分可以在程序上下文中执行。这样,通过工作伫列执行的程序码能占尽程序上下文的所有优势。最重要的就是工作伫列允许被重新排程甚至是睡眠。


<<:  JS 28 - 客制化滚动卷轴:样式多,支援度也广!

>>:  【後转前要多久】# Day28 Angular - 四种资料系结 Binding

RESTful API 在 Amazon Linux 2 上传图片实作-Day 07

RESTful API 在 Amazon Linux 2 上传图片实作-Day 07 RESTful...

[资料库] 学习笔记 - 商城交易之上架商品

这次练习的题目是做出商城中上架商品的功能 功能主要需求:谁上架了什麽商品、上架数量多少,如果商品没有...

tkinter 实现台湾类股抽签程序

# -*- coding: utf-8 -*- import tkinter as tk impor...

[Day 14] Reverse 小入门

时间飞逝,已到第14天了 明天就一半ㄌ,好感动眼睛流汗 今天我们要干大事!!! 要来解 REVERS...

[D10] placeholder for d10

写在前面 placeholder for d10 placeholder for d10 place...