mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
x86/HPET: replace handle_hpet_broadcast()'s on-stack cpumask_t
With large NR_CPUS on-stack cpumask_t variables are problematic. Now that
the IRQ handler can't be invoked in a nested manner anymore, we can
instead use a per-CPU variable. While we can't use scratch_cpumask in code
invoked from IRQ handlers, simply amend that one with a HPET-special form.
(Note that only one of the two IRQ handling functions can come into play
at any one time.)
Fixes: 996576b965 ("xen: allow up to 16383 cpus")
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
Release-Acked-By: Oleksii Kurochko<oleksii.kurochko@gmail.com>
This commit is contained in:
1 parent
ff8228ab46
commit
80c7c67164
3 files changed
+12
-4
No files matched your search
+4
-4
@@ -196,7 +196,7 @@ static void evt_do_broadcast(cpumask_t *mask)
|
||||
|
||||
static void cf_check handle_hpet_broadcast(struct hpet_event_channel *ch)
|
||||
{
|
||||
cpumask_t mask;
|
||||
cpumask_t *scratch = this_cpu(hpet_scratch_cpumask);
|
||||
s_time_t now, next_event;
|
||||
unsigned int cpu;
|
||||
unsigned long flags;
|
||||
@@ -209,7 +209,7 @@ again:
|
||||
spin_unlock_irqrestore(&ch->lock, flags);
|
||||
|
||||
next_event = STIME_MAX;
|
||||
cpumask_clear(&mask);
|
||||
cpumask_clear(scratch);
|
||||
now = NOW();
|
||||
|
||||
/* find all expired events */
|
||||
@@ -218,13 +218,13 @@ again:
|
||||
s_time_t deadline = ACCESS_ONCE(per_cpu(timer_deadline, cpu));
|
||||
|
||||
if ( deadline <= now )
|
||||
__cpumask_set_cpu(cpu, &mask);
|
||||
__cpumask_set_cpu(cpu, scratch);
|
||||
else if ( deadline < next_event )
|
||||
next_event = deadline;
|
||||
}
|
||||
|
||||
/* wakeup the cpus which have an expired event. */
|
||||
evt_do_broadcast(&mask);
|
||||
evt_do_broadcast(scratch);
|
||||
|
||||
if ( next_event != STIME_MAX )
|
||||
{
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
DECLARE_PER_CPU(cpumask_var_t, cpu_sibling_mask);
|
||||
DECLARE_PER_CPU(cpumask_var_t, cpu_core_mask);
|
||||
DECLARE_PER_CPU(cpumask_var_t, scratch_cpumask);
|
||||
DECLARE_PER_CPU(cpumask_var_t, hpet_scratch_cpumask);
|
||||
DECLARE_PER_CPU(cpumask_var_t, send_ipi_cpumask);
|
||||
|
||||
/*
|
||||
|
||||
@@ -55,6 +55,9 @@ DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_core_mask);
|
||||
DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, scratch_cpumask);
|
||||
static cpumask_t scratch_cpu0mask;
|
||||
|
||||
DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, hpet_scratch_cpumask);
|
||||
static cpumask_t hpet_scratch_cpu0mask;
|
||||
|
||||
DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, send_ipi_cpumask);
|
||||
static cpumask_t send_ipi_cpu0mask;
|
||||
|
||||
@@ -976,6 +979,8 @@ static void cpu_smpboot_free(unsigned int cpu, bool remove)
|
||||
FREE_CPUMASK_VAR(per_cpu(cpu_core_mask, cpu));
|
||||
if ( per_cpu(scratch_cpumask, cpu) != &scratch_cpu0mask )
|
||||
FREE_CPUMASK_VAR(per_cpu(scratch_cpumask, cpu));
|
||||
if ( per_cpu(hpet_scratch_cpumask, cpu) != &hpet_scratch_cpu0mask )
|
||||
FREE_CPUMASK_VAR(per_cpu(hpet_scratch_cpumask, cpu));
|
||||
if ( per_cpu(send_ipi_cpumask, cpu) != &send_ipi_cpu0mask )
|
||||
FREE_CPUMASK_VAR(per_cpu(send_ipi_cpumask, cpu));
|
||||
}
|
||||
@@ -1112,6 +1117,7 @@ static int cpu_smpboot_alloc(unsigned int cpu)
|
||||
if ( !(cond_zalloc_cpumask_var(&per_cpu(cpu_sibling_mask, cpu)) &&
|
||||
cond_zalloc_cpumask_var(&per_cpu(cpu_core_mask, cpu)) &&
|
||||
cond_alloc_cpumask_var(&per_cpu(scratch_cpumask, cpu)) &&
|
||||
cond_alloc_cpumask_var(&per_cpu(hpet_scratch_cpumask, cpu)) &&
|
||||
cond_alloc_cpumask_var(&per_cpu(send_ipi_cpumask, cpu))) )
|
||||
goto out;
|
||||
|
||||
@@ -1239,6 +1245,7 @@ void __init smp_prepare_boot_cpu(void)
|
||||
cpumask_set_cpu(cpu, &cpu_present_map);
|
||||
#if NR_CPUS > 2 * BITS_PER_LONG
|
||||
per_cpu(scratch_cpumask, cpu) = &scratch_cpu0mask;
|
||||
per_cpu(hpet_scratch_cpumask, cpu) = &hpet_scratch_cpu0mask;
|
||||
per_cpu(send_ipi_cpumask, cpu) = &send_ipi_cpu0mask;
|
||||
#endif
|
||||
|
||||
|
||||