Linux内核-tasklet微任务

Linux下中断机制之tasklet执行过程(详细)总结 一、简介 由于中断会打断内核中进程的正常调度运行,所以要求中断服务程序尽可能的短小精悍;但是在实际系统中,当中断到来时,要完成工作往往进行大量的耗时处理。因此期望让中断处理程序运行得快,并想让它完成的工作量多,这两个目标相互制约,诞生——顶/底半部机制,本文主要介绍tasklet的执行过程。 读者可根据情况了解以下知识: 软中断过程总结 中断机制详细总结 由于软中断必须使用可重入函数,这就导致设计上的复杂度变高,作为设备驱动程序的开发者来说,增加了负担。而如果某种应用并不需要在多个CPU上并行执行,那么软 阅读详情

tasklet用于处理一些不那么紧急的任务,可以延后在将来的某个时间点来执行,linux通过中断来响应处理一些任务,这类任务通常是很紧急的需要立即处理,此类任务通常运行于interrupt context(中断上下文),存在较多限制。

  • tasklet实现原理

tasklet实现基于软中断(softirq),而软中断基于硬件中断,它们的优先级逐次递增。

 简单描述下处理流程,当前硬件中断时,内核根据irq号进而执行该IRQ的处理例程(ISR),irq处理例程结束后处理软中断,tasklet软中断例程遍历所有注册的tasklet并依次执行它们。

执行中断例程(非ISR)
run_irq_on_irqstack_cond
中断例程执行完成后,在该函数中触发软中断
irq_exit_rcu();

irq_exit_rcu只是一个前端,所有的工作由__irq_exit_rcu实现

static inline void __irq_exit_rcu(void)
{
#ifndef __ARCH_IRQ_EXIT_IRQS_DISABLED
	local_irq_disable();
#else
	lockdep_assert_irqs_disabled();
#endif
	account_hardirq_exit(current);
	preempt_count_sub(HARDIRQ_OFFSET);
	if (!in_interrupt() && local_softirq_pending())
		invoke_softirq(); //触发软中断执行

	tick_irq_exit();
}

该函数负责执行软中断例程(tasklet例程),该函数比较长,我这里摘抄核心部分说明,其余的是内核统计、中断禁用等与核心流程关系不大。

__do_softirq
    //softirq_vec中存放了所有已注册的软中断例程
    h = softirq_vec;
    //循环处理所有待处理软中断
	while ((softirq_bit = ffs(pending))) {
		unsigned int vec_nr; //中断号
		int prev_count;

		h += softirq_bit - 1;

		vec_nr = h - softirq_vec;
		prev_count = preempt_count();

		kstat_incr_softirqs_this_cpu(vec_nr);

		trace_softirq_entry(vec_nr);

        //这里执行软中断例程
		h->action(h);

		trace_softirq_exit(vec_nr);
		if (unlikely(prev_count != preempt_count())) {
			pr_err("huh, entered softirq %u %s %p with preempt_count %08x, exited with %08x?\n",
			       vec_nr, softirq_to_name[vec_nr], h->action,
			       prev_count, preempt_count());
			preempt_count_set(prev_count);
		}
		h++;
		pending >>= softirq_bit;
	}

该函数循环处理所有软中断例程,其中实现tasklet的中断例程会执行,tasklet例程会执行所有已注册的tasklet任务。

  • tasklet数据结构
/**
tasklet任务结构,表示一个tasklet。
*/
struct tasklet_struct
{
	struct tasklet_struct *next; //多个tasklet通过next成员连接起来
	unsigned long state; //任务状态
	atomic_t count;
	bool use_callback; //为1时调用callback函数
	union {
        /*
        由于是union 结构所有func和callback只能设置一个
        */
		void (*func)(unsigned long data); //任务例程
		void (*callback)(struct tasklet_struct *t); //任务例程
	};
	unsigned long data; //需要传给任务函数的参数
};

如下图,通过宏DECLARE_TASKLET创建tasklet任务结构后,调用tasklet_schedule将该tasklet添加到当前CPU的tasklet_head结构,然后触发tasklet软中断,执行tasklet_action软中断处理例程,该中断例程除了启用中断、获取当前CPU的tasklet_head结构,核心处理逻辑是从tasklet_heap中取出任务并执行任务函数(tasklet_struct->func)。

 内核提供的tasklet处理接口


//创建tasklet_struck实例
#define DECLARE_TASKLET(name, _callback)		\
struct tasklet_struct name = {				\
	.count = ATOMIC_INIT(0),			\
	.callback = _callback,				\
	.use_callback = true,				\
}

//将该 t 添加到当前CPU的tasklet_head中并调度tasklet
static inline void tasklet_schedule(struct tasklet_struct *t)

//同tasklet_schedule一致,不过它执行高优先级的软中断例程
static inline void tasklet_hi_schedule(struct tasklet_struct *t)

//将 t 从tasklet_heap中移除
void tasklet_kill(struct tasklet_struct *t)

//这两个函数做的事情是一致的,都是将tasklet任务函数设置到tasklet_struct结构,出于兼容性考虑,内核都保留了下来。
void tasklet_setup(struct tasklet_struct *t,void (*callback)(struct tasklet_struct *))
void tasklet_init(struct tasklet_struct *t,void (*func)(unsigned long), unsigned long data)

实战编写tasklet案例,这里的tasklet任务函数只是打印一个消息到内核,实际驱动开发中,我们可以用tasklet完成很多简单、可快速完成的任务,这类任务用kthread太重了,tasklet则很合适。

#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/export.h>
#include <linux/module.h>
#include <linux/interrupt.h>


//tasklet处理函数
static void my_tasklet_fn(unsigned long data)
{
    printk("execute my_tasklet_fn data %ld\n",data);
}


static struct tasklet_struct _my_tasklet;


static int __init tasklet_example_init(void)
{
    int retval=0;
    
    //初始化tasklet
    tasklet_init(&_my_tasklet,&my_tasklet_fn,123);

    //将tasklet添加到待执行列表,并调度tasklet软中断
    tasklet_schedule(&_my_tasklet);

    printk("tasklet_example_init...");
    return retval;
}

static void __exit tasklet_example_exit(void)
{
    printk("tasklet_example_exit...");
}


module_init(tasklet_example_init);
module_exit(tasklet_example_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("ZhangQiang");

make -j 6 编译内核模块 

通过insmod tasklet_example.ko 加载内核模块到内核,可以看到成功执行了tasklet函数。

 

Linux中断——tasklet、workqueue --- 阅读详情

相关推荐

tasklet的实现(原理篇)

在前面的使用篇已经清晰的描述了tasklet的实现目的与使用方法。本节将重点描述tasklet的实现原理和方法。

难波儿万的博客 981

【Linux】Linux驱动开发:中断子系统

参考文档内核目录如果中断控制器有级联关系,下级的中断控制器还需要表明它的“interrupt-parent”是谁,用了interrupt-parent”中的哪一个“interrupts”你要用哪一个中断控制器里的中断?interrupts你要用哪一个中断?Interrupts里要用几个cell,由 interrupt-parent 对应的中断控制器决定。在中断控制器里有“#interrupt-cells”属性,它指明了要用几个cell来描述中断。

W__winter的博客 2021

cocos2dx lua + protobuf

vs 2015 cocos2dx 3.10  lua  protobuf1. 下载 protobuf 源码     https://github.com/bnnswyp/protobuf/tree/master/protobuf-2.5.0    解压后的文件列表如下所示         其中 vsprojects 文件夹为 protobuf 的vs 工程2. 打开 protobuf.sln 编译...

u014486706的博客 2163

Linux内核中断子系统

无

qq_45302555的博客 919

RK3568 解决MIPI屏幕开机只显示uboot logo的问题

之前写过一篇文章介绍了RK3568驱动MIPI屏幕的方法,这次产品迭代,硬件改版,选型的新的屏幕了。所以再次开启调试屏幕的过程。本以为会和上次一样会轻车熟路,事情总是事与愿违,同样的路,遇到新的坑。

fhqlongteng的博客 5425

AWSIM模拟器 新增多相机

本文介绍了基于Unity6引擎对AWSIM自动驾驶模拟器的优化方案,主要针对多相机系统的扩展实现。作者通过修改EgoVehicle.cs和AutowareSimulationDemo.cs核心代码,将原单相机系统升级为5相机配置。关键技术点包括:1)使用List容器管理多个CameraSensor组件;2)完善相机初始化流程;3)配置5个相机UI显示窗口;4)修改ROS话题设置。优化后的系统可支持BEVFusion等多传感器融合算法的测试验证,为Autoware.universe 0.45.0及以上版本提供

W805698955的博客 831

【分析笔记】Linux tasklet 机制的理解

Linux 内核的 tasklet 机制的分析和理解

lovemengx的博客 2442

导出库的版本_Windows下PaddleOCR在C++中的推理部署(CPU版本)CMake + VS2017

PaddleOCR是一个与OCR相关的开源项目,不仅支持超轻量级中文OCR预测模型,总模型仅8.6M(单模型支持中英文数字组合识别、竖排文本识别、长文本识别,其中检测模型DB(4.1M)+识别模型CRNN(4.5M)),而且提供多种文本检测训练算法(EAST、DB)和多种文本识别训练算法(Rosetta、CRNN、STAR-Net、RARE)。本文将教大家通过PaddleOCR(CPU版...

weixin_31304817的博客 1914

下半部机制之微线程

微线程(tasklet)是一种更通用的下半部机制,大多数情况下应该优先使用微线程,只有在对性能要求非常高的时候才考虑使用软中断。然而,微线程是基于软中断的,它实际上是一个软中断。内核中的微线程用两个软中断表示:HI_SOFTIRQ和TASKLET_SOFTIRQ。两者唯一的区别在于HI_SOF...

chijiandao3197的博客 137

华为OD机试E卷 -猜字谜(Java & Python& JS & C++ & C )

小王设计了一个简单的猜字谜游戏,游戏的谜面是一个错误的单词,比如nesw,玩家需要猜出谜底库中正确的单词。猜中的要求如下:请你写一个程序帮忙在谜底库中找到正确的谜底。谜面是多个单词,都需要找到对应的谜底,如果找不到的话,返回”not found”

算法大师! 3488

qt医疗信息系统(HIS)

**UI 组件**: QWidget、QTextBrowser、QTableWidget、QGraphicsView 等。- **网络通信**: Qt Network (TCP/IP)- **DICOM 处理**: DCMTK 3.6.7。- **数据库**: SQLite (轻量、跨平台)**数据库文件**: `hospital.db`- **开发框架**: Qt 6 (C++)- 医疗影像 (DICOM) 查看器。**医疗影像 (DICOM) 查看器****电子病历 (EMR) 浏览器**

寒寒豆豆软件公司的博客 337

可延迟函数、内核微线程以及工作队列

本文研究多个用于在内核环境当中延迟处理的方法(特别是在 Linux 内核版本 2.6.27.14 当中)。 尽管这些方法针对 Linux 内核,但方法背后的理念, 对于系统架构研究具有更广泛的意义。例如, 可以将这些理念应用到传统的嵌入式系统当中,取代原有的调度程序来进行任务调度 。 在开始...

chijiandao3197的博客 211

pycharm下载continue插件接入DeepSeek的API,向其提问输出乱码,如何解决?

🏆本文收录于 《全栈Bug调优(实战版)》 专栏,该专栏专注于分享我在真实项目开发中遇到的各类疑难Bug及其深层成因,并系统提供高效、可复现的解决思路和实操方案。无论你是刚入行的新手开发者,还是拥有多年项目经验的资深工程师,本专栏都将为你提供一条系统化、高质量的问题排查与优化路径,助力你加速成长,攻克技术壁垒,迈向技术价值最大化与职业发展的更高峰🚀!

**My Coding Family** 2219

内核 API,第 2 部分:可延迟函数、内核微线程以及工作队列

转自:http://www.ibm.com/developerworks/cn/linux/l-tasklets/ Linux 2.6 bottom halves 简介 对于高频率线程操作,Linux® 内核提供微线程和工作队列。 微线程和工作队列执行可延迟功能并替代驱动程序当中原有的 bottom-half 机制。 本文研究如何在内核中使用微线程和工作队列,并

xishuang_gongzi的专栏 597

STM32串口控制LED灯的亮灭

STM32中的串口控制LED灯的亮灭,分为两种方式,一种是直接发送数字0和1来控制灯的亮灭,另一种是通过发送字符串来控制。 我所使用的开发板主控芯片是STM32F401RET6,主频84MHz, 首先要进行串口的初始化: /* 函数功能:串口的初始化 函数名:Usart_Init 返回值:无 参数:u32 brr 备注: USART1_TXD->PA9 USART1_RXD->PA10 */ void Usart_Init(u32 brr) { float div; u16 div

博客 2万+

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Linux内核tasklet机制

本文介绍了Linux内核中的tasklet机制及其在中断处理中的应用。tasklet是一种特殊的软中断,用于实现中断处理的底半部,具有在SMP系统上不会并发执行的特性。文章详细阐述了tasklet的数据结构tasklet_struct及其成员功能,包括状态管理、绑定函数和参数传递等。同时提供了tasklet的API使用方法,包括静态/动态初始化、调度控制等关键操作。

m0_67219632的博客 1360

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

linux内核之tasklet使用

内核微线程 ---- tasklet和工作队列一样,可以用于推后执行的代码。tasklet(小任务)机制是中断处理下半部分最常用的一种方法,其使用也是非常简单的。一个使用tasklet的中断程序首先会通过执行中断处理程序来快速完成上半部分的工作,接着通过调用tasklet使得下半部分的工作得以完成。在中断处理程序中,除了完成对中断的响应等工作,还要调用tasklet。 1、 数据结构 ...

仗劍走天涯 5442

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Linux内核之tasklet机制

Linux内核之tasklet机制

大吉 1696

12 内核开发-任务调度之tasklet

Tasklet 是一种轻量级内核调度机制,用于处理延迟敏感的任务,这些任务需要在中断处理程序上下文中立即执行,但不能阻塞系统。Tasklet 特性轻量级:Tasklet 是一种轻量级机制,开销很小。非阻塞:Tasklet 不会阻塞系统,因为它在软中断上下文中执行。并发:多个 Tasklet 可以同时执行,提高了并发性。延迟敏感:Tasklet 旨在处理延迟敏感的任务,需要在中断处理程序上下文中立即执行。

jxusthusiwen的专栏 1314

linux tasklet

软中断、tasklet 以及工作队列,均是 linux 中将任务推后执行的机制。其中工作队列与用户态使用的线程池类似。什么是任务推后执行呢?可以借助于开发应用时经常使用的线程池来理解。任务推后执行,就是任务本该执行的时候没有立即执行,而是将任务放到任务容器(标志位或者任务队列)中,相当于生产者;任务容器还有消费者,消费者从容器中取出任务来执行。这就是推后执行,其中有 3 个组成元素,生产者,任务容器和消费者。

weixin_38184628的博客 1501

Linux中软中断tasklet任务队列初始化

Linux内核软中断与高优先级任务队列处理机制分析 本文分析了Linux内核中软中断初始化和高优先级任务队列处理的关键函数。softirq_init函数初始化软中断系统,为普通任务队列(TASKLET_SOFTIRQ)和高优先级任务队列(HI_SOFTIRQ)注册对应的处理函数tasklet_action和tasklet_hi_action。open_softirq函数负责将处理函数和数据指针注册到软中断向量数组中。 tasklet_hi_action是高优先级任务队列的处理函数,在软中断上下文中执行延迟任

weixin_51019352的博客 878

内核软中断之tasklet机制

1. 软中断IRQ简介 软中断(SoftIRQ)是内核提供的一种基于中断的延时机制, Linux内核定义的软中断有以下几种: enum { HI_SOFTIRQ=0, /*高优先级的tasklet*/ TIMER_SOFTIRQ, NET_TX_SOFTIRQ, NET_RX_SOFTIRQ, BLOCK_SOFTIRQ, TASKLET_SOFTIRQ, /*普通tasklet...

遇见你是我最美丽的意外 1万+

linux 内核学习 tasklet 详解

软中断被执行的优先级要高于内核线程。硬中断是可以抢占内核线程的,硬中断退出时会立即执行软中断。这时软中断执行程序是运行在中断上下文的。如果软中断执行程序在指定时间内没处理完,就会挂起来等下次下次被执行。下次被执行可以是另一个硬中断退出时在中断上下文中执行,也可以是在特殊的内核线程ksoftirq被调度到来执行,这时是运行在线程上下文的。 总体来说,软中断执行程序被执行的机会会比普

676

RK3568中断-tasklet

/ 定义 tasklet 处理函数// Tasklet 处理逻辑// ...} // 静态初始化 tasklet// 驱动程序的其他代码my_tasklet 是 tasklet 的名称, my_tasklet_handler 是 tasklet 的处理函数, 0是传递给处理函数的参数。但是需要注意的是, 使用 DECLARE_TASKLET 静态初始化的 tasklet无法在运行时动态销毁, 因此在不需要 tasklet 时, 应该避免使用此方法。

十年饮冰,难凉热血 1852

Linux中断(tasklet,工作队列,内核线程的使用)

本篇文章来讲解在Linux中tasklet,工作队列,内核线程的使用。本篇文章就讲解到这里,需要大家好好理解并进行实践。

m0_49476241的博客 1622

linux 内核tasklet详解

本文内核版本为2.6.32 软中断被执行的优先级要高于内核线程。硬中断是可以抢占内核线程的,硬中断退出时会立即执行软中断。这时软中断执行程序是运行在中断上下文的。如果软中断执行程序在指定时间内没处理完,就会挂起来等下次下次被执行。下次被执行可以是另一个硬中断退出时在中断上下文中执行,也可以是在特殊的内核线程ksoftirq被调度到来执行,这时是运行在线程上下文的。 总体来说,软中断执行

huangqqshu2的专栏 551
上一篇: Linux内核中断(X86)
下一篇: Kubernetes 自定义控制器开发
IT回忆录
博客等级 码龄16年 42粉丝 100原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值