首页 > 其他分享 >3.5.1 发送并处理IPIPE_CRITICAL_IPI

3.5.1 发送并处理IPIPE_CRITICAL_IPI

时间:2024-09-22 08:51:21浏览次数:3  
标签:__ CRITICAL IPI sync 3.5 gic ipipe CPU

点击查看系列文章 =》 Interrupt Pipeline系列文章大纲-CSDN博客

原创不易,需要大家多多鼓励!您的关注、点赞、收藏就是我的创作动力!

3.5.1 发送并处理IPIPE_CRITICAL_IPI

       __ipipe_init()最核心的就是__ipipe_enable_pipeline(),接下来对其展开分析!__ipipe_enable_pipeline()又可以分成两大部分来分析。本小节分析第一部分:ipipe_critical_enter和ipipe_critical_exit。

第一步:ipipe_send_ipi(IPIPE_CRITICAL_IPI, allbutself);

传入的ipi号是IPIPE_CRITICAL_IPI,它的定义是IPIPE_IPI_BASE + NR_IPI,它的值是virtual interrupt编号1031。在函数ipipe_send_ipi中减掉IPIPE_IPI_BASE得到7,存入ipinr并传递给函数smp_cross_call。

传入的cpumask是allbutself,它在ipipe_critical_enter中被初始化,除了bootup的CPU core 0,其它所有online CPU cores对应的bit位被置位1.

第二步:smp_cross_call(&cpumask, ipinr);

如果传入的ipinr小于7即0~6,说明是Linux的原生IPI,需要复用SGI0,变量sgi等于0。此时需要把ipinr记录到per cpu变量ipi_messages,方便其它CPU Core接收到SGI0中断时,从per cpu变量ipi_messages读出正确的ipinr的数值。

在当前的例子中,传入的ipinr等于7,所以在第862行sgi等于1。这就印证了《3.4.1.2 IPIPE对Linux中断号的改造》里面的分析,3个OOB IPI使用SGI1/2/3.

第三步:__smp_cross_call(target, sgi);

函数指针__smp_cross_call是在gic_init_bases-> gic_smp_init中初始化的,指向函数gic_raise_softirq。

drivers/irqchip/irq-gic-v3.c:
static void gic_smp_init(void)
{
	set_smp_cross_call(gic_raise_softirq);
	cpuhp_setup_state_nocalls(CPUHP_AP_IRQ_GIC_STARTING,
				  "irqchip/arm/gicv3:starting",
				  gic_starting_cpu, NULL);
}

arch/arm64/kernel/smp.c:
void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int))
{
	__smp_cross_call = fn;
}

第四步:set_smp_cross_call(gic_raise_softirq);

GIC V3中断控制器,最终通过写SYS_ICC_SGI1R_EL1寄存器像其它CPU Cores发生SGI 1中断。

gic_raise_softirq
->gic_send_sgi
->gic_write_sgi1r
->write_sysreg_s(val, SYS_ICC_SGI1R_EL1)

第五步:gic_handle_irq

SGI 1中断发生后,根据《2.3.5 irq_handler》的分析,GIC V3中断控制器调用gic_handle_irq来处理中断。因为是IPI中断,所以调用ipipe_handle_multi_ipi来处理。

第六步:ipipe_handle_multi_ipi(irqnr, regs)

只调用了一个函数__ipipe_grab_ipi(irq, regs)。

第七步:__ipipe_grab_ipi(irq, regs);

如果sgi为非0,则说明是OOB IPI。在当前分析的上下文中,因为sgi传入的是1,所以irq最终等于1031,就是IPIPE_CRITICAL_IPI。所以,在这一步已经还原出需要响应的virtual interrupt编号。

如果sgi编号为0,则说明是Linux原生IPI,从per cpu变量ipi_messages还原出Linux原生IPI编号0~6,再加上IPIPE_IPI_BASE,变成1024~1030。对照第二步,就搞清楚了Linux原生IPI是如何复用SGI0了。

第八步:__ipipe_dispatch_irq

实时内核的注册是在start_kernel->rest_init中,是在_ipipe_init()之后才调用的。所以此时实时内核并没有注册,即ipipe_head_domain其实就等于ipipe_root_domain。在此背景下,virtual interrupt编号1031就会被__ipipe_set_irq_pending记录到interrupt log。

最后层层调用__ipipe_sync_pipeline ->__ipipe_do_sync_pipeline ->__ipipe_sync_stage->__ipipe_do_sync_stage,通过__ipipe_next_irq进行interrupt log回放。找到virtual interrupt编号1031,执行它的中断处理程序。

根据《3.4.3 __ipipe_init_early之初始化root domain》,IPIPE_CRITICAL_IPI(1031)对应的中断处理程序初始化为__ipipe_do_critical_sync()。也就是说,除了CPU Core 0,其它online的CPU cores都开始执行__ipipe_do_critical_sync()。

第九步:_ipipe_do_critical_sync()

除了CPU Core 0,其它online的CPU cores都开始执行__ipipe_do_critical_sync()。这些CPU core都把自身的cpu编号在__ipipe_cpu_sync_map中进行置位,以此来通知CPU Core 0:老大,我已顺利收到IPIPE_CRITICAL_IPI(1031),并开始执行__ipipe_do_critical_sync()。

而CPU Core 0在ipipe_critical_enter中,不断检查__ipipe_cpu_sync_map的值,只要所有CPU cores对应的bit已经置位了,则说明:兄弟们都收到通知并开始执行了。

第十步,ipipe_critical_exit

其它online的CPU cores执行完__ipipe_do_critical_sync(),会最终把自身的cpu编号在__ipipe_cpu_sync_map中进行清空,以此来通知CPU Core 0:老大,我已顺利完成任务。

而CPU Core 0在ipipe_critical_exit中,不断检查__ipipe_cpu_sync_map,确定兄弟们都完成了任务,则最终退出循环,代表整个IPIPE_CRITICAL_IPI处理完美结束。

点击查看系列文章 =》 Interrupt Pipeline系列文章大纲-CSDN博客

原创不易,需要大家多多鼓励!您的关注、点赞、收藏就是我的创作动力!

标签:__,CRITICAL,IPI,sync,3.5,gic,ipipe,CPU
From: https://blog.csdn.net/aspirestro/article/details/142427010

相关文章

  • 3.4.4 __ipipe_init_early之再论虚拟中断
    点击查看系列文章=》 InterruptPipeline系列文章大纲-CSDN博客3.4.4__ipipe_init_early之再论虚拟中断     根据《3.4.1.2IPIPE对Linux中断号的改造》的分析,IPIPE引入的虚拟中断virtualinterrupt的概念,其中前10个虚拟中断本质上是利用SGI实现的IPI中断。IPIPE在......
  • centos789手动无脑用sh脚本安装hadoop3.3.5
    和上篇一样的操作查看代码#!/bin/bash#确保以root用户运行if["$(id-u)"-ne"0"];thenecho"请以root用户运行此脚本!"exit1fi#定义目录和文件路径SOFTWARE_DIR="/export/software"SERVER_DIR="/export/servers"HADOOP_TAR="......
  • 【vue3】vue3.5
    vue3.5是9.1发布的,还挺热乎的,赶快学习起来!!!组件属性结构解析赋值组件属性结构解析赋值,高度提高开发体验,这个特性曾经在vue3.3提出过,然后3.4废弃,终于3.5稳定了。下面一起来看看怎么用的吧。<scriptsetuplang="ts">import{watch}from'vue';//自定义属性......
  • 亲测好用,ChatGPT 3.5/4.0新手使用手册~
     都知道ChatGPT很强大,聊聊天、写论文、搞翻译、写代码、写文案、审合同等等,无所不能~那么到底怎么使用呢?其实很简单了,国内AI产品发展也很快,很多都很好用了~我一直在用,建议收藏下来~  有最先进、最新的GPT模型,还有很多其他效率工具都是在各自领域,绝对领先地位的产品~......
  • 一文超详解锁 Vue 3.5新特性
    前端人的苦恼叕来了,前端技术隔三岔五的更新,学习别想停了,趁着中秋即将来临卷起来吧(说好的中秋假期咱不卷的呢)。就在这个9月,尤大叕更新了,没事,一文总结重要更新,大概更新了以下内容:响应式重构。性能提升了,内存使用率下降了(56%)响应式props解构新增useTemplateRef函数服......
  • Vue3.5中解构props,让父子组件通信更加丝滑
    前言在Vue3.5版本中响应式Props解构终于正式转正了,这个功能之前一直是试验性的。这篇文章来带你搞清楚,一个String类型的props经过解构后明明应该是一个常量了,为什么还没丢失响应式呢?本文中使用的Vue版本为欧阳写文章时的最新版Vue3.5.5关注公众号:【前端欧阳】,给自己一个进阶vu......
  • Vue3.5+ 侦听器的3个更新
    你好同学,我是沐爸,欢迎点赞、收藏、评论和关注。在Vue3.5+中,对于侦听器的更新有以下几个方面:暂停/恢复侦听器、副作用清理/onWatcherCleanup和deep遍历深度,如果对此熟悉可以直接划走了,如果没有划走就一起看看吧。暂停/恢复侦听器在Vue3.5之前,watch和watchEffect有......
  • 3.4.3 __ipipe_init_early之初始化root domain
    点击查看系列文章=》 InterruptPipeline系列文章大纲-CSDN博客3.4.3__ipipe_init_early之初始化rootdomain      如下图所示,红框里面的函数当前都是空的,本章还是分析蓝框中的代码片段。第295行,变量ipd指向了ipipe_root即ipd代表rootdomain。第305行,rootdoma......
  • Vue3.5+ 响应式 Props 解构
    你好同学,我是沐爸,欢迎点赞、收藏、评论和关注。在Vue3.5+中,响应式Props解构已经稳定并默认启用。这意味着在<scriptsetup>中从defineProps调用解构的变量现在是响应式的。这一改进大大简化了声明带有默认值的props的方式,并使得在子组件中直接使用解构后的pro......
  • 3.4.1.2 IPIPE对Linux中断号的改造
    点击查看系列文章=》 InterruptPipeline系列文章大纲-CSDN博客3.4.1.2IPIPE对Linux中断号的改造    在IPIPEdomain中,IPIPE_NR_IRQS代表中断总数量,在代码中经常用到,最具代表的就是下图中定义structipipe_irqdescirqs[IPIPE_NR_IRQS].        先列一......