Skip to content

Commit 04c8b0f

Browse files
author
Marc Zyngier
committed
irqchip/gic: Make locking a BL_SWITCHER only feature
The BL switcher code manipulates the logical/physical CPU mapping, forcing a lock to be taken on the IPI path. With an IPI heavy load, this single lock becomes contended. But when CONFIG_BL_SWITCHER is not enabled, there is no reason to take this lock at all since the CPU mapping is immutable. This patch allows the lock to be entierely removed when BL_SWITCHER is not enabled (which is the case in most configurations), leading to a small improvement of "perf bench sched pipe" (measured on an 8 core AMD Seattle system): Before: 101370 ops/sec After: 103680 ops/sec Take this opportunity to remove a useless lock being taken when handling an interrupt on a secondary GIC. Signed-off-by: Marc Zyngier <[email protected]>
1 parent 9395452 commit 04c8b0f

File tree

1 file changed

+27
-9
lines changed

1 file changed

+27
-9
lines changed

drivers/irqchip/irq-gic.c

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,27 @@ struct gic_chip_data {
9191
#endif
9292
};
9393

94-
static DEFINE_RAW_SPINLOCK(irq_controller_lock);
94+
#ifdef CONFIG_BL_SWITCHER
95+
96+
static DEFINE_RAW_SPINLOCK(cpu_map_lock);
97+
98+
#define gic_lock_irqsave(f) \
99+
raw_spin_lock_irqsave(&cpu_map_lock, (f))
100+
#define gic_unlock_irqrestore(f) \
101+
raw_spin_unlock_irqrestore(&cpu_map_lock, (f))
102+
103+
#define gic_lock() raw_spin_lock(&cpu_map_lock)
104+
#define gic_unlock() raw_spin_unlock(&cpu_map_lock)
105+
106+
#else
107+
108+
#define gic_lock_irqsave(f) do { (void)(f); } while(0)
109+
#define gic_unlock_irqrestore(f) do { (void)(f); } while(0)
110+
111+
#define gic_lock() do { } while(0)
112+
#define gic_unlock() do { } while(0)
113+
114+
#endif
95115

96116
/*
97117
* The GIC mapping of CPU interfaces does not necessarily match
@@ -317,12 +337,12 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
317337
if (cpu >= NR_GIC_CPU_IF || cpu >= nr_cpu_ids)
318338
return -EINVAL;
319339

320-
raw_spin_lock_irqsave(&irq_controller_lock, flags);
340+
gic_lock_irqsave(flags);
321341
mask = 0xff << shift;
322342
bit = gic_cpu_map[cpu] << shift;
323343
val = readl_relaxed(reg) & ~mask;
324344
writel_relaxed(val | bit, reg);
325-
raw_spin_unlock_irqrestore(&irq_controller_lock, flags);
345+
gic_unlock_irqrestore(flags);
326346

327347
return IRQ_SET_MASK_OK_DONE;
328348
}
@@ -374,9 +394,7 @@ static void gic_handle_cascade_irq(struct irq_desc *desc)
374394

375395
chained_irq_enter(chip, desc);
376396

377-
raw_spin_lock(&irq_controller_lock);
378397
status = readl_relaxed(gic_data_cpu_base(chip_data) + GIC_CPU_INTACK);
379-
raw_spin_unlock(&irq_controller_lock);
380398

381399
gic_irq = (status & GICC_IAR_INT_ID_MASK);
382400
if (gic_irq == GICC_INT_SPURIOUS)
@@ -776,7 +794,7 @@ static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
776794
return;
777795
}
778796

779-
raw_spin_lock_irqsave(&irq_controller_lock, flags);
797+
gic_lock_irqsave(flags);
780798

781799
/* Convert our logical CPU mask into a physical one. */
782800
for_each_cpu(cpu, mask)
@@ -791,7 +809,7 @@ static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
791809
/* this always happens on GIC0 */
792810
writel_relaxed(map << 16 | irq, gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT);
793811

794-
raw_spin_unlock_irqrestore(&irq_controller_lock, flags);
812+
gic_unlock_irqrestore(flags);
795813
}
796814
#endif
797815

@@ -859,7 +877,7 @@ void gic_migrate_target(unsigned int new_cpu_id)
859877
cur_target_mask = 0x01010101 << cur_cpu_id;
860878
ror_val = (cur_cpu_id - new_cpu_id) & 31;
861879

862-
raw_spin_lock(&irq_controller_lock);
880+
gic_lock();
863881

864882
/* Update the target interface for this logical CPU */
865883
gic_cpu_map[cpu] = 1 << new_cpu_id;
@@ -879,7 +897,7 @@ void gic_migrate_target(unsigned int new_cpu_id)
879897
}
880898
}
881899

882-
raw_spin_unlock(&irq_controller_lock);
900+
gic_unlock();
883901

884902
/*
885903
* Now let's migrate and clear any potential SGIs that might be

0 commit comments

Comments
 (0)