forked from Minki/linux
irqchip/gic-v3-its: Remove cpumask_var_t allocation
Running a PREEMPT_RT kernel based on v5.19-rc3-rt4 on an Ampere Altra
triggers:
[ 22.616229] BUG: sleeping function called from invalid context at kernel/locking/spinlock_rt.c:46
[ 22.616239] in_atomic(): 1, irqs_disabled(): 128, non_block: 0, pid: 1884, name: kworker/80:1
[ 22.616243] preempt_count: 3, expected: 0
[ 22.616244] RCU nest depth: 0, expected: 0
[...]
[ 22.616250] hardirqs last enabled at (33): _raw_spin_unlock_irq (/home/piegon01/linux/./arch/arm64/include/asm/irqflags.h:35)
[ 22.616273] hardirqs last disabled at (34): __schedule (/home/piegon01/linux/kernel/sched/core.c:6432 (discriminator 1))
[ 22.616283] softirqs last enabled at (0): copy_process (/home/piegon01/linux/./include/linux/lockdep.h:191)
[ 22.616297] softirqs last disabled at (0): 0x0
[ 22.616305] Preemption disabled at:
[ 22.616307] __setup_irq (/home/piegon01/linux/kernel/irq/manage.c:1612)
[ 22.616322] CPU: 80 PID: 1884 Comm: kworker/80:1 Tainted: G W [...]
[ 22.616328] Hardware name: WIWYNN Mt.Jade Server System B81.03001.0005/Mt.Jade Motherboard, BIOS 1.08.20220218 (SCP: 1.08.20220218) 2022/02/18
[ 22.616333] Workqueue: events work_for_cpu_fn
[ 22.616344] Call trace:
[...]
[ 22.616403] alloc_cpumask_var_node (/home/piegon01/linux/lib/cpumask.c:115)
[ 22.616414] alloc_cpumask_var (/home/piegon01/linux/lib/cpumask.c:147)
[ 22.616417] its_select_cpu (/home/piegon01/linux/drivers/irqchip/irq-gic-v3-its.c:1580)
[ 22.616428] its_set_affinity (/home/piegon01/linux/drivers/irqchip/irq-gic-v3-its.c:1659)
[ 22.616431] msi_domain_set_affinity (/home/piegon01/linux/kernel/irq/msi.c:501)
[ 22.616440] irq_do_set_affinity (/home/piegon01/linux/kernel/irq/manage.c:276)
[ 22.616443] irq_setup_affinity (/home/piegon01/linux/kernel/irq/manage.c:633)
[ 22.616447] irq_startup (/home/piegon01/linux/kernel/irq/chip.c:280)
[ 22.616453] __setup_irq (/home/piegon01/linux/kernel/irq/manage.c:1777)
Follow the pattern established in commit cba4235e60
("genirq: Remove
mask argument from setup_affinity()") and co to overcome this issue by
defining a static struct cpumask and protecting it by a raw spinlock.
Since its_select_cpu() can be executed with IRQs enabled or disabled,
enforce that the cpumask computation is done with interrupts disabled.
Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20220912141857.1391343-1-pierre.gondois@arm.com
This commit is contained in:
parent
8fc7a6198a
commit
f55a9b59e8
@ -1574,13 +1574,15 @@ static int its_select_cpu(struct irq_data *d,
|
||||
const struct cpumask *aff_mask)
|
||||
{
|
||||
struct its_device *its_dev = irq_data_get_irq_chip_data(d);
|
||||
cpumask_var_t tmpmask;
|
||||
static DEFINE_RAW_SPINLOCK(tmpmask_lock);
|
||||
static struct cpumask __tmpmask;
|
||||
struct cpumask *tmpmask;
|
||||
unsigned long flags;
|
||||
int cpu, node;
|
||||
|
||||
if (!alloc_cpumask_var(&tmpmask, GFP_ATOMIC))
|
||||
return -ENOMEM;
|
||||
|
||||
node = its_dev->its->numa_node;
|
||||
tmpmask = &__tmpmask;
|
||||
|
||||
raw_spin_lock_irqsave(&tmpmask_lock, flags);
|
||||
|
||||
if (!irqd_affinity_is_managed(d)) {
|
||||
/* First try the NUMA node */
|
||||
@ -1634,7 +1636,7 @@ static int its_select_cpu(struct irq_data *d,
|
||||
cpu = cpumask_pick_least_loaded(d, tmpmask);
|
||||
}
|
||||
out:
|
||||
free_cpumask_var(tmpmask);
|
||||
raw_spin_unlock_irqrestore(&tmpmask_lock, flags);
|
||||
|
||||
pr_debug("IRQ%d -> %*pbl CPU%d\n", d->irq, cpumask_pr_args(aff_mask), cpu);
|
||||
return cpu;
|
||||
|
Loading…
Reference in New Issue
Block a user