此问题是artless noise对this question的回答的跟进。如上所示
对于分配器寄存器,通常全局中断具有读/写启用/禁用。每个CPU的寄存器在分发器中可能是只读的,并指示存在中断。另一组寄存器(每个CPU)是启用/禁用每个CPU中断的常规机制。当访问分发服务器时,软件应具有互锁(信号量),因为它对系统是全局的。
现在,体系结构规范版本2指示GICD_ISENABLERn
(取消屏蔽中断)和GICD_ICENABLERn
(屏蔽中断)仅在写入1
时更改状态,但写入{{ 1}}被忽略。因此,可以在不进行读取的情况下编写这些寄存器(如目前在Linux实现中所做的那样)。
0
此代码确实包含对分发服务器的配置寄存器的锁定,但我不确定这些是否真的需要(或者如果丢弃它们会发生什么)。
如果两个内核同时尝试屏蔽不同的中断(由同一个寄存器配置),则会导致两个/*
* Routines to acknowledge, disable and enable interrupts
*/
static void gic_mask_irq(struct irq_data *d)
{
u32 mask = 1 << (gic_irq(d) % 32);
raw_spin_lock(&irq_controller_lock);
gic_writel_relaxed(mask, gic_dist_base(d) +
GIC_DIST_ENABLE_CLEAR + (gic_irq(d) / 32) * 4);
if (gic_arch_extn.irq_mask)
gic_arch_extn.irq_mask(d);
raw_spin_unlock(&irq_controller_lock);
}
static void gic_unmask_irq(struct irq_data *d)
{
u32 mask = 1 << (gic_irq(d) % 32);
raw_spin_lock(&irq_controller_lock);
if (gic_arch_extn.irq_unmask)
gic_arch_extn.irq_unmask(d);
gic_writel_relaxed(mask, gic_dist_base(d) + GIC_DIST_ENABLE_SET +
(gic_irq(d) / 32) * 4);
raw_spin_unlock(&irq_controller_lock);
}
被写入同一寄存器的不同位置。但是,互连应该导致两次写入都通过,因此这将导致两个中断被屏蔽(如预期的那样)。
同样,如果两个内核都试图屏蔽相同的中断(在这种情况下,如果其中一个写入丢失则无关紧要。)
我能看到的唯一一个意味着麻烦的情况是,如果一个核心试图屏蔽中断,而另一个核心同时试图取消屏蔽相同的中断。但是在这种情况下,即使有锁定,结果也是相当不可预测的(如果没有锁定,分销商将不得不以某种方式“决定”,在锁定的情况下,行为取决于谁首先获得锁定)。所以再次锁定没有帮助。
或者我可能错了,从不同内核到同一个字的写入总是必须通过,内存优化可能导致其中一个写入丢失(这必须在互连中发生,因为没有真正的涉及记忆)。这是指定的位置?