在飞腾CPU平台上,SMP机间中断主要用来在指定CPU上实现七个目标:
| IPI序号 | 目标 |
| IPI_RESCHEDULE | 远程cpu执行任务调度 当被唤醒进程不是运行本地cpu上,就需要给被唤醒进程所在的远程cpu发送IPI中断,让远程cpu重新调度。在接收到IPI时无论远程cpu是否处于空闲态,被唤醒进程都会在IPI中断过渡到内核态时得到执行。 |
| IPI_CALL_FUNC | 远程cpu执行回调函数 当本地cpu将指定远程cpu调用的回调函数挂到远程cpu的队列上,然后给远程cpu发送IPI_CALL_FUNC机间中断; 远程cpu就会将执行队列上的所有回调函数,整个过程必须保持中断屏蔽状态。 |
| IPI_CPU_STOP | 远程CPU停止运行 先将指定的远程cpu从在线CPU位图中删除,然后将屏蔽D,A,I,F中断屏蔽,最后处理器进入低功耗循环。 |
| IPI_CPU_CRASH_STOP | 可选配置KEXEC_CORE 执行崩溃转储 |
| IPI_TIMER | 可选配置GENERIC_CLOCKEVENTS_BROADCAST 定时器广播 |
| IPI_IRQ_WORK | 可选配置IRQ_WORK 远程cpu在中断上下文中运行回调函数 |
| IPI_WAKEUP | 可选配置ARM64_ACPI_PARKING_PROTOCOL 唤醒CPU |
1. 远程cpu执行任务调度
本地cpu端的Linux核心层通过函数smp_send_reschedule,向指定cpu发送“执行任务调度”需求。
void smp_send_reschedule(int cpu) { smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE); }
远程cpu端相应的中断处理
static __always_inline void scheduler_ipi(void) { /* * 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(); }
2. 远程cpu执行回调函数
本地cpu端的Linux核心层通过调用函数arch_send_call_function_xxx,向指定cpu发送“执行回调函数”需求。
void arch_send_call_function_ipi_mask(const struct cpumask *mask) { smp_cross_call(mask, IPI_CALL_FUNC); } void arch_send_call_function_single_ipi(int cpu) { smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC); }
远程cpu端相应的中断处理
void generic_smp_call_function_single_interrupt(void) { cfd_seq_store(this_cpu_ptr(&cfd_seq_local)->gotipi, CFD_SEQ_NOCPU, smp_processor_id(), CFD_SEQ_GOTIPI); flush_smp_call_function_queue(true); }
3.远程CPU停止运行
本地cpu端发起machine_halt、machine_power_off、machine_restart等操作时,需要向其他所有cpu发送“停止运行”需求。
void smp_send_stop(void)
{
unsigned long timeout;
if (num_other_online_cpus()) {
cpumask_t mask;
cpumask_copy(&mask, cpu_online_mask);
cpumask_clear_cpu(smp_processor_id(), &mask);
if (system_state <= SYSTEM_RUNNING)
pr_crit("SMP: stopping secondary CPUs\n");
smp_cross_call(&mask, IPI_CPU_STOP);
}
/* Wait up to one second for other CPUs to stop */
timeout = USEC_PER_SEC;
while (num_other_online_cpus() && timeout--)
udelay(1);
if (num_other_online_cpus())
pr_warn("SMP: failed to stop secondary CPUs %*pbl\n",
cpumask_pr_args(cpu_online_mask));
sdei_mask_local_cpu();
}
远程cpu端相应的中断处理
static void local_cpu_stop(void) { set_cpu_online(smp_processor_id(), false); local_daif_mask(); sdei_mask_local_cpu(); cpu_park_loop(); }
本文详细介绍了飞腾CPU平台上的SMP(Symmetric MultiProcessing)中断处理,包括IPI_RESCHEDULE用于远程CPU的任务调度,IPI_CALL_FUNC用于执行回调函数,以及IPI_CPU_STOP用于停止远程CPU运行等关键操作。通过smp_cross_call函数发送中断请求,远程CPU接收到中断后执行相应处理,如preempt_fold_need_resched()和flush_smp_call_function_queue()。此外,还讨论了IPI在不同场景下的应用,如定时器广播、中断上下文回调和CPU唤醒等。
&spm=1001.2101.3001.5002&articleId=121486667&d=1&t=3&u=ad11d5c949a54f509f9417ee13de07f1)
1371

被折叠的 条评论
为什么被折叠?



