1、软中断由内核线程ksoftirqd处理,下面说一下它的创建过程。
start_kernel()创建init线程,init()调用do_pre_smp_initcalls()->spawn_ksoftirqd(
),spawn_ksoftirqd()分两次调用cpu_callback(),
分别使用参数CPU_UP_PREPARE和CPU_ONLINE。使用CPU_UP_PREPARE调用cpu_callback()
时,创建了ksoftirqd线程,并把task_struct指针存于per_cpu变量per_cpu(ksoftirqd,
hotcpu)中;使用CPU_ONLINE调用该函数对ksoftirqd线程进行唤醒。

--------------linux/init/main.c---------------------
static void do_pre_smp_initcalls(void)
{extern int spawn_ksoftirqd(void);
#ifdef CONFIG_SMPextern int migration_init(void);migration_init();
#endifspawn_ksoftirqd();
}
----------------linux/kernel/softirq.c-----------------
/*
主cpu(即引导cpu)通过spawn_ksoftirqd()->cpu_callback()创建该cpu上的ksoftirqd
内核线程,并调用register_cpu_notifier()
将cpu_nfb注册到cpu通知链)
*/
__init int spawn_ksoftirqd(void)
{void *cpu = (void *)(long)smp_processor_id();cpu_callback(&cpu_nfb, CPU_UP_PREPARE, cpu);cpu_callback(&cpu_nfb, CPU_ONLINE, cpu);register_cpu_notifier(&cpu_nfb);return 0;
}
----------------linux/kernel/softirq.c---------------------
//cpu_callback()建立了ksoftirqd内核线程,并把task_struct指针存于per_cpu变量per_cpu(ksoftirqd, hotcpu)中
static int __devinit cpu_callback(struct notifier_block *nfb,unsigned long action,void *hcpu)
{int hotcpu = (unsigned long)hcpu;struct task_struct *p;switch (action) {case CPU_UP_PREPARE:BUG_ON(per_cpu(tasklet_vec, hotcpu).list);BUG_ON(per_cpu(tasklet_hi_vec, hotcpu).list);p = kthread_create(ksoftirqd, hcpu, "ksoftirqd/%d", hotcpu);if (IS_ERR(p)) {printk("ksoftirqd for %i failed\n", hotcpu);return NOTIFY_BAD;}kthread_bind(p, hotcpu);per_cpu(ksoftirqd, hotcpu) = p;break;case CPU_ONLINE:wake_up_process(per_cpu(ksoftirqd, hotcpu));break;
#ifdef CONFIG_HOTPLUG_CPUcase CPU_UP_CANCELED:/* Unbind so it can run.  Fall thru. */kthread_bind(per_cpu(ksoftirqd, hotcpu), smp_processor_id());case CPU_DEAD:p = per_cpu(ksoftirqd, hotcpu);per_cpu(ksoftirqd, hotcpu) = NULL;kthread_stop(p);takeover_tasklets(hotcpu);break;
#endif /* CONFIG_HOTPLUG_CPU */}return NOTIFY_OK;
}

2、从cpu的ksoftirqd线程的创建。从cpu调用start_kernel()->init()->smp_init()->cpu_up(),cpu_up()在各cpu上线前后分别调用notifier_call_chain()。

static void __init smp_init(void)
{unsigned int i;/* FIXME: This should be done in userspace --RR */for_each_present_cpu(i) {if (num_online_cpus() >= max_cpus)break;if (!cpu_online(i))cpu_up(i);}
……
}
int __devinit cpu_up(unsigned int cpu)
{……//上线前调用ret = notifier_call_chain(&cpu_chain, CPU_UP_PREPARE, hcpu);……//等cpu上线:cpu_isset(cpu, cpu_online_map)ret = __cpu_up(cpu);……/* Now call notifier in preparation. *///上线后调用notifier_call_chain(&cpu_chain, CPU_ONLINE, hcpu);
}//函数notifier_call_chain()以cpu标号为参数运行cpu通知链上的各函数,其中包含上述spawn_ksoftirqd()中注册的cpu_nfb。
static struct notifier_block __devinitdata cpu_nfb = {.notifier_call = cpu_callback
};//通知链元素cpu_nb上的函数cpu_callback即用来创建各非引导cpu上的ksoftirqd线程。
int notifier_call_chain(struct notifier_block **n, unsigned long val, void *v)
{int ret=NOTIFY_DONE;struct notifier_block *nb = *n;while(nb){ret=nb->notifier_call(nb,val,v);if(ret&NOTIFY_STOP_MASK){return ret;}nb=nb->next;}return ret;
}

linux kernel2.6中软中断运行线程ksoftirqd的创建相关推荐

  1. 关于linux的进程中的各个线程cpu占用情况的分析和查看

    我们经常会在新开的服搭建一个游戏的服务器,有时候要进行压力测试,那么如何来看呢,一般我们会通过top命令查看各个进程的cpu和内存占用情况,获得到了我们的进程id,然后我们也许会通过pstack命令查 ...

  2. linux 使用jstack_技德发布JStack 2.0,在Linux系统中无缝运行移动应用

    近日,技德系统发布了融合桌面产品JStack 2.0.在上一版基础上,JStack 2.0取得了重大突破,实现了在Linux环境下,直接同时开启并运行Linux应用与移动应用 图:采用JStack2. ...

  3. linux原生系统_技德发布JStack 2.0,在Linux系统中无缝运行移动应用

    近日,技德系统发布了融合桌面产品JStack 2.0.在上一版基础上,JStack 2.0取得了重大突破,实现了在Linux环境下,直接同时开启并运行Linux应用与移动应用. 图:使用JStack2 ...

  4. Linux 多线程应用中编写安全的信号处理函数

    2019独角兽企业重金招聘Python工程师标准>>> Linux 多线程应用中编写安全的信号处理函数 在 开发多线程应用时,开发人员一般都会考虑线程安全,会使用 pthread_m ...

  5. Linux 多线程应用中如何编写安全的信号处理函数

    Linux 多线程应用中编写安全的信号处理函数 在开发多线程应用时,开发人员一般都会考虑线程安全,会使用 pthread_mutex 去保护全局变量.如果应用中使用了信号,而且信号的产生不是因为程序运 ...

  6. 【OS】Linux命令如何放到后台运行

    [OS]Linux命令如何放到后台运行 linux命令后台运行  有两种方式:    1. command & : 后台运行,你关掉终端会停止运行    2. nohup command &a ...

  7. Linux内核网络中的软中断ksoftirqd

    1. 前言 之前分享过Linux内核网络数据包的接收过程,当执行到网卡通过硬件中断(IRQ)通知CPU,告诉它有数据来了,CPU会根据中断表,调用已经注册的中断函数,这个中断函数会调到驱动程序(NIC ...

  8. linux下c语言线程传参数,【linux】C语言多线程中运行线程池,在线程池中运行线程池,,传递的结构体参数值为空/NULL/0...

    C语言多线程中运行线程池,在线程池中运行线程池,,传递的结构体参数值为空/NULL/0 本贴问题,之前已经提问过一次,当时已经解决了,原贴在这里https://segmentfault.com/q/1 ...

  9. linux下IPROTO_TCP,TCP/IP协议栈在Linux内核中的运行时序分析

    可选题目三:TCP/IP协议栈在Linux内核中的运行时序分析 在深入理解Linux内核任务调度(中断处理.softirg.tasklet.wq.内核线程等)机制的基础上,分析梳理send和recv过 ...

最新文章

  1. 1.ireport基本使用
  2. c# 通过API启动外部程序
  3. Flask发送邮件,最基础
  4. Pattern-No.03 设计模式之策略模式
  5. [转]Java 关闭线程的安全方法
  6. 如何安装 Angular CLI 并且检查 CLI 的版本
  7. oracle 增量设为3 循环_Oracle 差异性增量 和 累计增量 原理(转)
  8. 服务器ie打不开http协议,在浏览器输入地址后,这个世界发生了什么(http协议浅谈)...
  9. java 流式_Java开发笔记(七十二)Java8新增的流式处理
  10. dba 权限_DBA如何玩转PG用户、角色和权限管理?
  11. php 增加数组下标_PHP数组排序更改下标KEY方法
  12. bzoj 4571 美味 —— 主席树
  13. 学习ARM64页表转换流程
  14. 【最全】PS各个版本下载安装及小试牛刀教程(PhotoShop CS3 ~~ PhotoShop 2022)
  15. 鲲鹏920服务器支持docker,鲲鹏云服务器上安装Dockerdocker-compose
  16. 计算机芯片的形成和发展,计算机中将cpu集成在一块芯片上所形成的元器件是什么...
  17. 面试表现不好时补救策略
  18. BGP简介-如何配置 EBGP(外部 BGP)
  19. linux中的setenv命令
  20. 微信小程序(uniapp)获取用户位置信息及选择位置

热门文章

  1. 情侣空间显示服务器失败,情侣空间error是什么意思
  2. itextpdf5.x实现合同签署盖章预览功能
  3. MACD多周期共振系统TB源码
  4. ppt护理文书流程图_病案管理试题及答案
  5. SpringMVC+Mybatis+Maven搭建 简单配置双数据源
  6. uniapp之webscoket聊天 文字/图片/表情/语音
  7. 有人(甚至国家)兜底就安全了吗?瑞士央行风暴小议。
  8. AltiumDesigner 18 菜单中英文对照表
  9. java 和c 多态比较_多态在 Java 和 C 编程语言中的实现比较
  10. java中insteadof_Java代码规范小结(一)