安庆

导航

ipi发送阻塞导致crash

3.10的内核,

在子进程退出的时候,发送信号通知父进程,此时是持有父进程的sighand中的spinlock的,然后父进程和该子进程不在一个核上,发送ipi的reschedule中断给对应的核,

但是,由于信号其实是异步机制,在没有发送ipi之前,对应的接收进程已经在处理信号,

处理信号的过程中,又需要拿自己对应task_struct中的sighand里面的spinlock,导致了死锁。

 

那么,为什么子进程发送ipi需要这么久呢?按道理不是发送完ipi中断不就可以释放锁了么?

 调用链为:kick_process--->smp_send_reschedule(父进程所在的cpu)--->native_smp_send_reschedule--->(apic->send_IPI_mask)

---->physflat_send_IPI_mask---default_send_IPI_mask_sequence_phys--->__default_send_IPI_dest_filed--->__xapic_wait_icr_idle

最后循环在:

static inline void __xapic_wait_icr_idle(void)
{
	while (native_apic_mem_read(APIC_ICR) & APIC_ICR_BUSY)
		cpu_relax();
}

嗯,操作对应的内存,发现APIC_ICR_BUSY一直满足,然后就死等了。

 

有一点没想清楚:

static inline void
 __default_send_IPI_dest_field(unsigned int mask, int vector, unsigned int dest)
{
	unsigned long cfg;

	/*
	 * Wait for idle.
	 */
	if (unlikely(vector == NMI_VECTOR))-----为啥发送NMI就需要用safe,而发送reschedule则不需要呢?
		safe_apic_wait_icr_idle();
	else
		__xapic_wait_icr_idle();

从代码看,APIC_ICR是local apic,发送ipi的时候,按道理只需要自己这边空闲就行。

posted on 2019-10-16 21:35  _备忘录  阅读(633)  评论(0编辑  收藏  举报