linux中的SGI(核间中断)IPI_RESCHEDULE详解
1、SGI中斷(核間通信中斷)
在gicv2/gicv3中,SGI中斷(中斷號0-15)是software generate interrupt,用戶核間中斷。
我們一般將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中斷的調用流程
(1)、CPU收到IRQ后的處理
當ARM core收到IRQ后,會觸發cpu的irq異常,會跳轉到linux kernel的irq異常向量表,在該向量表中,會調用gicv2/gicv3的gic_handle_irq函數,在kernel/drivers/irqchip/irq-gic-v3.c中
- irqnr = gic_read_iar() 讀gic寄存器獲取硬件中斷號
- likely(irqnr > 15 && irqnr < 1020) || irqnr >= 8192 這這個條件下處理PPI中斷和SPI中斷
- if (irqnr < 16) 在這個條件下調用handle_IPI(irqnr, regs)來處理SGI中斷
(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(); }總結
以上是生活随笔為你收集整理的linux中的SGI(核间中断)IPI_RESCHEDULE详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [architecture]-ARMV8
- 下一篇: linux 其他常用命令