提交 6ea55196 编写于 作者: Y Yipeng Zou 提交者: Yongqiang Liu

irqchip/gic-v3-its: introduce CONFIG_GENERIC_PENDING_IRQ

hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I6BO2R
CVE: NA

--------------------------------

Now, There is some issues about LPI migration on ARM SMP platform.

For example, NIC device generates MSI and sends LPI to CPU0 via ITS,
meanwhile irqbalance running on CPU1 set irq affinty of NIC to CPU1,
the next interrupt will be sent to CPU2, due to the state of irq is
still in progress, kernel does not end up performing irq handler on
CPU2, which results in some userland service timeouts, the sequence
of events is shown as follows:

NIC			CPU0			CPU1

Generate IRQ#1		READ_IAR
			Lock irq_desc
			Set IRQD_IN_PROGRESS
			Unlock irq_desc
						Lock irq_desc
						Change LPI Affinity
						Unlock irq_desc
			Call irq_handler
Generate IRQ#2
						READ_IAR
						Lock irq_desc
						Check IRQD_IN_PROGRESS
						Unlock irq_desc
						Return from interrupt#2
			Lock irq_desc
			Clear IRQD_IN_PROGRESS
			Unlock irq_desc
			return from interrupt#1

For this scenario, We can enable CONFIG_GENERIC_PENDING_IRQ to avoid this.

The CONFIG_GENERIC_PENDING_IRQ will delay all action that modify LPI
affinity until the next interrupt eoi handler.
Signed-off-by: NYipeng Zou <zouyipeng@huawei.com>
Reviewed-by: NLiao Chang <liaochang1@huawei.com>
Reviewed-by: NZhang Jianhua <chris.zjh@huawei.com>
Signed-off-by: NYongqiang Liu <liuyongqiang13@huawei.com>
上级 98cd4a57
...@@ -1162,6 +1162,12 @@ static void its_unmask_irq(struct irq_data *d) ...@@ -1162,6 +1162,12 @@ static void its_unmask_irq(struct irq_data *d)
lpi_update_config(d, 0, LPI_PROP_ENABLED); lpi_update_config(d, 0, LPI_PROP_ENABLED);
} }
static void its_irq_chip_eoi(struct irq_data *d)
{
irq_move_irq(d);
irq_chip_eoi_parent(d);
}
static int its_set_affinity(struct irq_data *d, const struct cpumask *mask_val, static int its_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
bool force) bool force)
{ {
...@@ -1485,7 +1491,7 @@ static struct irq_chip its_irq_chip = { ...@@ -1485,7 +1491,7 @@ static struct irq_chip its_irq_chip = {
.name = "ITS", .name = "ITS",
.irq_mask = its_mask_irq, .irq_mask = its_mask_irq,
.irq_unmask = its_unmask_irq, .irq_unmask = its_unmask_irq,
.irq_eoi = irq_chip_eoi_parent, .irq_eoi = its_irq_chip_eoi,
.irq_set_affinity = its_set_affinity, .irq_set_affinity = its_set_affinity,
.irq_compose_msi_msg = its_irq_compose_msi_msg, .irq_compose_msi_msg = its_irq_compose_msi_msg,
.irq_set_irqchip_state = its_irq_set_irqchip_state, .irq_set_irqchip_state = its_irq_set_irqchip_state,
......
...@@ -32,7 +32,9 @@ config GENERIC_IRQ_LEGACY_ALLOC_HWIRQ ...@@ -32,7 +32,9 @@ config GENERIC_IRQ_LEGACY_ALLOC_HWIRQ
# Support for delayed migration from interrupt context # Support for delayed migration from interrupt context
config GENERIC_PENDING_IRQ config GENERIC_PENDING_IRQ
bool bool "Support for delayed migration from interrupt context"
depends on SMP
default n
# Support for generic irq migrating off cpu before the cpu is offline. # Support for generic irq migrating off cpu before the cpu is offline.
config GENERIC_IRQ_MIGRATION config GENERIC_IRQ_MIGRATION
......
...@@ -117,3 +117,5 @@ void __irq_move_irq(struct irq_data *idata) ...@@ -117,3 +117,5 @@ void __irq_move_irq(struct irq_data *idata)
if (!masked) if (!masked)
idata->chip->irq_unmask(idata); idata->chip->irq_unmask(idata);
} }
void __weak irq_force_complete_move(struct irq_desc *desc) { }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册