Skip to content

Commit dd3f050

Browse files
author
Marc Zyngier
committed
irqchip/gic-v4.1: Implement the v4.1 flavour of VMOVP
With GICv4.1, VMOVP is extended to allow a default doorbell to be specified, as well as a validity bit for this doorbell. As an added bonus, VMOVP isn't required anymore of moving a VPE between redistributors that share the same affinity. Let's add this support to the VMOVP builder, and make sure we don't issue the command if we don't really need to. Signed-off-by: Marc Zyngier <[email protected]> Reviewed-by: Zenghui Yu <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 0684c70 commit dd3f050

File tree

1 file changed

+33
-7
lines changed

1 file changed

+33
-7
lines changed

drivers/irqchip/irq-gic-v3-its.c

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,17 @@ static void its_encode_vmapp_default_db(struct its_cmd_block *cmd,
470470
its_mask_encode(&cmd->raw_cmd[1], vpe_db_lpi, 31, 0);
471471
}
472472

473+
static void its_encode_vmovp_default_db(struct its_cmd_block *cmd,
474+
u32 vpe_db_lpi)
475+
{
476+
its_mask_encode(&cmd->raw_cmd[3], vpe_db_lpi, 31, 0);
477+
}
478+
479+
static void its_encode_db(struct its_cmd_block *cmd, bool db)
480+
{
481+
its_mask_encode(&cmd->raw_cmd[2], db, 63, 63);
482+
}
483+
473484
static inline void its_fixup_cmd(struct its_cmd_block *cmd)
474485
{
475486
/* Let's fixup BE commands */
@@ -756,6 +767,11 @@ static struct its_vpe *its_build_vmovp_cmd(struct its_node *its,
756767
its_encode_vpeid(cmd, desc->its_vmovp_cmd.vpe->vpe_id);
757768
its_encode_target(cmd, target);
758769

770+
if (is_v4_1(its)) {
771+
its_encode_db(cmd, true);
772+
its_encode_vmovp_default_db(cmd, desc->its_vmovp_cmd.vpe->vpe_db_lpi);
773+
}
774+
759775
its_fixup_cmd(cmd);
760776

761777
return valid_vpe(its, desc->its_vmovp_cmd.vpe);
@@ -3327,22 +3343,32 @@ static int its_vpe_set_affinity(struct irq_data *d,
33273343
bool force)
33283344
{
33293345
struct its_vpe *vpe = irq_data_get_irq_chip_data(d);
3330-
int cpu = cpumask_first(mask_val);
3346+
int from, cpu = cpumask_first(mask_val);
33313347

33323348
/*
33333349
* Changing affinity is mega expensive, so let's be as lazy as
33343350
* we can and only do it if we really have to. Also, if mapped
33353351
* into the proxy device, we need to move the doorbell
33363352
* interrupt to its new location.
33373353
*/
3338-
if (vpe->col_idx != cpu) {
3339-
int from = vpe->col_idx;
3354+
if (vpe->col_idx == cpu)
3355+
goto out;
33403356

3341-
vpe->col_idx = cpu;
3342-
its_send_vmovp(vpe);
3343-
its_vpe_db_proxy_move(vpe, from, cpu);
3344-
}
3357+
from = vpe->col_idx;
3358+
vpe->col_idx = cpu;
3359+
3360+
/*
3361+
* GICv4.1 allows us to skip VMOVP if moving to a cpu whose RD
3362+
* is sharing its VPE table with the current one.
3363+
*/
3364+
if (gic_data_rdist_cpu(cpu)->vpe_table_mask &&
3365+
cpumask_test_cpu(from, gic_data_rdist_cpu(cpu)->vpe_table_mask))
3366+
goto out;
33453367

3368+
its_send_vmovp(vpe);
3369+
its_vpe_db_proxy_move(vpe, from, cpu);
3370+
3371+
out:
33463372
irq_data_update_effective_affinity(d, cpumask_of(cpu));
33473373

33483374
return IRQ_SET_MASK_OK_DONE;

0 commit comments

Comments
 (0)