FAILED: patch "[PATCH] irqchip/gic: Atomically update affinity" failed to apply to 4.9-stable tree
[email protected]
maintainerThe patch below does not apply to the 4.9-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 005c34ae4b44f085120d7f371121ec7ded677761 Mon Sep 17 00:00:00 2001
From: Marc Zyngier <[email protected]>
Date: Sun, 21 Jun 2020 14:43:15 +0100
Subject: [PATCH] irqchip/gic: Atomically update affinity
The GIC driver uses a RMW sequence to update the affinity, and relies on the gic_lock_irqsave/gic_unlock_irqrestore sequences to update it atomically.
But these sequences only expand into anything meaningful if the BL_SWITCHER option is selected, which almost never happens.
It also turns out that using a RMW and locks is just as silly, as the GIC distributor supports byte accesses for the GICD_TARGETRn registers, which when used make the update atomic by definition.
Drop the terminally broken code and replace it by a byte write.
drivers/irqchip/irq-gic.c +3 -11
@@ -329,10 +329,8 @@ static int gic_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu)static int gic_set_affinity (struct irq_data *d,const struct cpumask *mask_val,bool force) { -void __iomem *reg =gic_dist_base (d) +GIC_DIST_TARGET + (gic_irq (d) & ~3 ); -unsigned int cpu, shift = (gic_irq (d) %4 ) *8 ; -u32 val, mask, bit; -unsigned long flags; +void __iomem *reg =gic_dist_base (d) +GIC_DIST_TARGET +gic_irq (d); +unsigned int cpu;if (!force) cpu =cpumask_any_and (mask_val, cpu_online_mask);
@@ -342,13 +340,7 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,if (cpu >=NR_GIC_CPU_IF || cpu >= nr_cpu_ids)return -EINVAL ; -gic_lock_irqsave (flags); - mask =0xff << shift; - bit = gic_cpu_map[cpu] << shift; - val =readl_relaxed (reg) & ~mask; -writel_relaxed (val | bit, reg); -gic_unlock_irqrestore (flags); - +writeb_relaxed (gic_cpu_map[cpu], reg);irq_data_update_effective_affinity (d,cpumask_of (cpu));return IRQ_SET_MASK_OK_DONE ;