日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > linux >内容正文

linux

linux中的SGI(核间中断)IPI_RESCHEDULE详解

發(fā)布時(shí)間:2025/3/21 linux 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux中的SGI(核间中断)IPI_RESCHEDULE详解 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1、SGI中斷(核間通信中斷)

在gicv2/gicv3中,SGI中斷(中斷號(hào)0-15)是software generate interrupt,用戶(hù)核間中斷。
我們一般將0-7劃分給linux中使用,8-15給TEE使用。在smp.c定義了linux中使用的SGI中斷。

kernel/arch/arm/kernel/smp.c
enum ipi_msg_type {
IPI_WAKEUP,
IPI_TIMER,
IPI_RESCHEDULE,
IPI_CALL_FUNC,
IPI_CPU_STOP,
IPI_IRQ_WORK,
IPI_COMPLETION,
/*
* CPU_BACKTRACE is special and not included in NR_IPI
* or tracable with trace_ipi_*
/
IPI_CPU_BACKTRACE,
#ifdef CONFIG_TRUSTY
IPI_CUSTOM_FIRST,
IPI_CUSTOM_LAST = 15,
#endif
/
* SGI8-15 can be reserved by secure firmware, and thus may
* not be usable by the kernel. Please keep the above limited
* to at most 8 entries.
*/
};

2、SGI中斷的調(diào)用流程

(1)、CPU收到IRQ后的處理

當(dāng)ARM core收到IRQ后,會(huì)觸發(fā)cpu的irq異常,會(huì)跳轉(zhuǎn)到linux kernel的irq異常向量表,在該向量表中,會(huì)調(diào)用gicv2/gicv3的gic_handle_irq函數(shù),在kernel/drivers/irqchip/irq-gic-v3.c中

  • irqnr = gic_read_iar() 讀gic寄存器獲取硬件中斷號(hào)
  • likely(irqnr > 15 && irqnr < 1020) || irqnr >= 8192 這這個(gè)條件下處理PPI中斷和SPI中斷
  • if (irqnr < 16) 在這個(gè)條件下調(diào)用handle_IPI(irqnr, regs)來(lái)處理SGI中斷
static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) {u32 irqnr;do {irqnr = gic_read_iar();if (likely(irqnr > 15 && irqnr < 1020) || irqnr >= 8192) {int err;if (static_key_true(&supports_deactivate))gic_write_eoir(irqnr);err = handle_domain_irq(gic_data.domain, irqnr, regs);if (err) {WARN_ONCE(true, "Unexpected interrupt received!\n");if (static_key_true(&supports_deactivate)) {if (irqnr < 8192)gic_write_dir(irqnr);} else {gic_write_eoir(irqnr);}}continue;}if (irqnr < 16) {gic_write_eoir(irqnr);if (static_key_true(&supports_deactivate))gic_write_dir(irqnr); #ifdef CONFIG_SMP/** Unlike GICv2, we don't need an smp_rmb() here.* The control dependency from gic_read_iar to* the ISB in gic_write_eoir is enough to ensure* that any shared data read by handle_IPI will* be read after the ACK.*/handle_IPI(irqnr, regs); #elseWARN_ONCE(true, "Unexpected SGI received!\n"); #endifcontinue;}} while (irqnr != ICC_IAR1_EL1_SPURIOUS); }
(2)、處理SGI中斷(也叫核間通信中斷)
void handle_IPI(int ipinr, struct pt_regs *regs) { ......case IPI_RESCHEDULE:scheduler_ipi();break; ...... }
(3)、處理IPI_RESCHEDULE中斷的操作
void scheduler_ipi(void) {int cpu = smp_processor_id();/** Fold TIF_NEED_RESCHED into the preempt_count; anybody setting* TIF_NEED_RESCHED remotely (for the first time) will also send* this IPI.*/preempt_fold_need_resched();if (llist_empty(&this_rq()->wake_list) && !got_nohz_idle_kick()) { #ifdef CONFIG_MTK_SCHED_MONITORmt_trace_IPI_start(IPI_RESCHEDULE);mt_trace_IPI_end(IPI_RESCHEDULE); #endifreturn;}/** Not all reschedule IPI handlers call irq_enter/irq_exit, since* traditionally all their work was done from the interrupt return* path. Now that we actually do some work, we need to make sure* we do call them.** Some archs already do call them, luckily irq_enter/exit nest* properly.** Arguably we should visit all archs and update all handlers,* however a fair share of IPIs are still resched only so this would* somewhat pessimize the simple resched case.*/irq_enter(); #ifdef CONFIG_MTK_SCHED_MONITORmt_trace_IPI_start(IPI_RESCHEDULE); #endifsched_ttwu_pending();/** Check if someone kicked us for doing the nohz idle load balance.*/if (unlikely(got_nohz_idle_kick()) && !cpu_isolated(cpu)) {this_rq()->idle_balance = 1;raise_softirq_irqoff(SCHED_SOFTIRQ);} #ifdef CONFIG_MTK_SCHED_MONITORmt_trace_IPI_end(IPI_RESCHEDULE); #endifirq_exit(); }

總結(jié)

以上是生活随笔為你收集整理的linux中的SGI(核间中断)IPI_RESCHEDULE详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。