当前位置: 首页 > news >正文

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

软中断初始化softirq_init

void __init softirq_init(void)
{open_softirq(TASKLET_SOFTIRQ, tasklet_action, NULL);open_softirq(HI_SOFTIRQ, tasklet_hi_action, NULL);
}
void open_softirq(int nr, void (*action)(struct softirq_action*), void *data)
{softirq_vec[nr].data = data;softirq_vec[nr].action = action;
}

1. 函数功能概述

这两个函数用于初始化 Linux 内核的软中断系统,特别是为任务队列(tasklet)机制注册对应的软中断处理函数

2. softirq_init 函数分析

2.1. 函数定义

void __init softirq_init(void)
{
  • void:函数没有返回值
  • __init:宏标记,表示该函数只在内核初始化阶段使用,初始化完成后占用的内存会被释放
  • 函数名表明这是软中断系统的初始化函数

2.2. 注册普通任务队列软中断

    open_softirq(TASKLET_SOFTIRQ, tasklet_action, NULL);
  • open_softirq:软中断注册函数
  • TASKLET_SOFTIRQ:软中断号,表示普通优先级任务队列软中断
  • tasklet_action:软中断处理函数,负责执行普通优先级的任务队列
  • NULL:没有额外的数据参数传递给处理函数

2.3. 注册高优先级任务队列软中断

    open_softirq(HI_SOFTIRQ, tasklet_hi_action, NULL);
}
  • HI_SOFTIRQ:软中断号,通常定义为 0,表示高优先级任务队列软中断
  • tasklet_hi_action:软中断处理函数,负责执行高优先级的任务队列
  • NULL:没有额外的数据参数

3. open_softirq 函数分析

3.1. 函数定义和参数

void open_softirq(int nr, void (*action)(struct softirq_action*), void *data)
{
  • void:没有返回值
  • int nr:软中断号(0-9),内核预定义了 10 个软中断
  • void (*action)(struct softirq_action*):函数指针,指向软中断的处理函数
  • void *data:可选的数据指针,会传递给处理函数

3.2. 设置软中断数据

    softirq_vec[nr].data = data;
  • softirq_vec[nr]:访问软中断向量数组中指定编号的软中断
  • .data = data:将用户数据指针保存到软中断结构中
  • 作用:允许在处理函数中访问特定的数据

3.3. 设置软中断处理函数

    softirq_vec[nr].action = action;
}
  • .action = action:将处理函数指针保存到软中断结构中
  • 作用:当软中断被触发时,内核会调用这个函数来处理

4. 系统整体架构

硬件中断↓
中断处理程序 (top half)↓
触发软中断 ←── softirq_init 初始化↓
软中断处理 (bottom half)├── HI_SOFTIRQ (0) → tasklet_hi_action → 高优先级tasklet├── TIMER_SOFTIRQ (1) → run_timer_softirq → 定时器├── ...└── TASKLET_SOFTIRQ (6) → tasklet_action → 普通tasklet

高优先级任务队列的软中断处理函数tasklet_hi_action

static void tasklet_hi_action(struct softirq_action *a)
{struct tasklet_struct *list;local_irq_disable();list = __get_cpu_var(tasklet_hi_vec).list;__get_cpu_var(tasklet_hi_vec).list = NULL;local_irq_enable();while (list) {struct tasklet_struct *t = list;list = list->next;if (tasklet_trylock(t)) {if (!atomic_read(&t->count)) {if (!test_and_clear_bit(TASKLET_STATE_SCHED, &t->state))BUG();t->func(t->data);tasklet_unlock(t);continue;}tasklet_unlock(t);}local_irq_disable();t->next = __get_cpu_var(tasklet_hi_vec).list;__get_cpu_var(tasklet_hi_vec).list = t;__raise_softirq_irqoff(HI_SOFTIRQ);local_irq_enable();}
}

1. 函数功能概述

tasklet_hi_action 函数负责处理高优先级任务队列(tasklet),在软中断上下文中执行延迟的任务,确保高优先级的延迟处理能够得到及时执行

2. 代码逐段分析

2.1. 函数定义

static void tasklet_hi_action(struct softirq_action *a)
{
  • static:函数只在当前文件内可见
  • struct softirq_action *a:软中断动作结构指针,包含处理函数和数据

2.2. 获取并清空当前CPU的任务队列

        struct tasklet_struct *list;local_irq_disable();list = __get_cpu_var(tasklet_hi_vec).list;__get_cpu_var(tasklet_hi_vec).list = NULL;local_irq_enable();
  • struct tasklet_struct *list:临时链表指针
  • local_irq_disable():禁用本地中断,防止并发访问
  • list = __get_cpu_var(tasklet_hi_vec).list:获取当前CPU的高优先级任务链表
  • __get_cpu_var(tasklet_hi_vec).list = NULL:清空原链表(原子操作)
  • local_irq_enable():重新启用中断
  • 关键:在中断保护下快速获取并清空链表,减少锁持有时间

2.3. 遍历处理任务队列

        while (list) {struct tasklet_struct *t = list;list = list->next;
  • while (list):循环处理链表中的每个任务
  • struct tasklet_struct *t = list:获取当前任务
  • list = list->next:移动到下一个任务
  • 作用:逐个处理链表中的所有任务

2.4. 尝试锁定任务

                if (tasklet_trylock(t)) {
  • tasklet_trylock(t):尝试获取任务的锁
  • 非阻塞操作,如果锁已被占用则立即返回失败
  • 目的:防止同一任务在多个CPU上并发执行

2.5. 检查任务状态和引用计数

                        if (!atomic_read(&t->count)) {
  • atomic_read(&t->count):原子读取任务的引用计数
  • !atomic_read(&t->count):如果引用计数为0(任务可用)
  • 作用:检查任务是否被禁用(count > 0 表示任务被禁用)

2.6. 状态检查和清除

                                if (!test_and_clear_bit(TASKLET_STATE_SCHED, &t->state))BUG();
  • test_and_clear_bit(TASKLET_STATE_SCHED, &t->state):测试并清除"已调度"状态位
  • 如果清除失败(原本未设置),触发内核错误 BUG()
  • 作用:确保任务确实处于已调度状态

2.7. 执行任务回调函数

                                t->func(t->data);
  • t->func:任务回调函数指针
  • t->data:传递给回调函数的数据
  • 核心操作:实际执行用户注册的任务函数

2.8. 任务执行完成处理

                                tasklet_unlock(t);continue;}tasklet_unlock(t);}
  • tasklet_unlock(t):释放任务锁
  • continue:跳过后续代码,处理下一个任务
  • 如果引用计数不为0,也释放锁但继续后续处理

2.9. 任务重新调度

                local_irq_disable();t->next = __get_cpu_var(tasklet_hi_vec).list;__get_cpu_var(tasklet_hi_vec).list = t;__raise_softirq_irqoff(HI_SOFTIRQ);local_irq_enable();}
}

重新调度流程:

  • local_irq_disable():禁用中断
  • t->next = __get_cpu_var(tasklet_hi_vec).list:将任务添加到链表头部
  • __get_cpu_var(tasklet_hi_vec).list = t:更新链表头
  • __raise_softirq_irqoff(HI_SOFTIRQ):重新触发高优先级软中断
  • local_irq_enable():启用中断

3. 函数工作流程图

开始tasklet_hi_action
禁用本地中断
获取当前CPU的hi_tasklet链表
清空原链表list=NULL
启用本地中断
循环: list != NULL?
获取当前任务t=list
list=list->next移动到下一任务
尝试锁定任务tasklet_trylockt
锁定成功?
检查引用计数atomic_read&t.count
计数为0?
清除SCHED状态位
执行回调函数t.func t.data
释放任务锁tasklet_unlockt
释放任务锁
需要重新调度
禁用本地中断
将任务重新加入链表头部
触发HI_SOFTIRQ软中断
启用本地中断
处理完成
http://www.dtcms.com/a/495306.html

相关文章:

  • 网站制作的重要流程世界优秀摄影作品网站
  • 技术剖析:智能体工作流与RPA流程自动化的架构差异与融合实现
  • 深圳比斯特自动化|圆柱电池测试设备核心功能与技术发展解析
  • 【软考备考】系统架构设计需要考虑的因素 性能 、安全、成本、可维护性详解知识点五
  • 面试反馈 Spring Cloud 的25连环炮
  • 第八篇: `lsmod`, `modinfo`, `modprobe` - 深入内核模块
  • aspx网站服务器失去响应天工网工程新希望官网
  • 网站服务器要多少钱【邯郸网络推广公司|邯郸网络营销公司】
  • 做网站用什么域名比较好找公司开发网站
  • 【Python】求解GPS未知及高斯噪声
  • Linux 教程:如何查找服务器中的大文件
  • 计算机网络基础篇——应用层
  • 2025年主流外贸管理软件深度测评和选型策略咨询报告
  • 玩Android Harmony next版,通过项目了解harmony项目快速搭建开发
  • 公司免费网站域名申请免费网址
  • 华为鲲鹏 Aarch64 环境下多 Oracle 数据库汇聚操作指南 CMP(类 Cloudera CDP 7.3)
  • Chromedriver放项目里就行!Selenium 3 和 4 指定路径方法对比 + 兼容写法
  • Spring Boot 项目, idea 控制台日志设置彩色
  • wap网站建设好不好百度小程序官方收费标准
  • Go语言数据竞争Data Race 问题怎么检测?怎么解决?
  • 作为项目经理,如何做好项目复盘?
  • 网站建设百度不通过杭州建站模板系统
  • A函数里调用B函数 ,且往B函数里传了个二级指针,并在B返回后,释放该指针
  • 茶社网站开发与设计的开题报告自适应网站好建们
  • 做拍福利爱福利视频网站网站建设与维护实训
  • LangGraph学习笔记(一):langgraph安装
  • DFS算法原理及其模板
  • 【小程序】微信小程序点击效果(view、button、navigator)
  • 快速上手 Scrapy:5 分钟创建一个可扩展的爬虫项目
  • 青岛网站设计公司在哪找网店代运营什么意思