Re: [PATCH v11 4/6] x86/sev: Add support to perform RMP optimizations asynchronously
From: Kalra, Ashish
Date: Mon Aug 03 2026 - 15:00:14 EST
Hello Boris,
On 7/31/2026 7:37 AM, Kalra, Ashish wrote:
>
> On 7/31/2026 12:44 AM, Borislav Petkov wrote:
>>> + migrate_disable();
>>> + this_cpu = smp_processor_id();
>>> +
>>> + cpumask_andnot(follower_mask, rmpopt_cpumask,
>>> + topology_sibling_cpumask(this_cpu));
>>> +
>>> + for (pa = rmpopt_pa_start; pa < rmpopt_pa_end; pa += SZ_1G)
>>> + rmpopt(pa);
>>> +
>>> + migrate_enable();
>>> +
>>> + /*
>>> + * Followers: run RMPOPT on the remaining cores. cpus_read_lock() is
>>> + * intentionally not held here: CPU hotplug is disabled for the entire
>>> + * time SNP is active (see snp_prepare()), and this work only runs while
>>> + * SNP is active, so the follower set stays valid across the whole scan.
>>> + */
>>> + for (pa = rmpopt_pa_start; pa < rmpopt_pa_end; pa += SZ_1G)
>>> + on_each_cpu_mask(follower_mask, rmpopt_smp, (void *)pa, true);
>>
>> An IPI per 1G pa?!?!? On each CPU?!
>>
>> Instead of IPIing each CPU and inside the handler, doing the loop?
>>
>> Nope.
>>
>
> You're right — an IPI per 1 GB is far too many. Will restructure to a single IPI per follower core: a new on_each_cpu()
> callback can loop over the whole range on the CPU it runs on. The leader will call it directly (migrate-disabled) to populate
> the RMP scan cache, then one on_each_cpu_mask() will run it on the remaining cores.
>
> This will also fold nicely with the earlier cleanup: __rmpopt() getting merged into rmpopt().
>
> One important tradeoff to be aware of: each follower IPI handler will now run a 2048-iteration loop with IRQs disabled —
> but followers are RMP-scan cache hits (the leader populated the cache), so each rmpopt() there is cheap, and this only runs
> at setup and guest-teardown re-optimization time.
>
Following up again on the tradeoff above.
Referencing your point about not IPIing per 1 GB, two ways to run the follower scan (followers = primary threads only, one
per core, so ~half the logical CPUs — not every CPU):
A) Loop on the worker, IPI per 1 GB: loop is preemptible / IRQs on, only a single op per IPI runs IRQs-off — but 2048
IPIs per follower.
B) One IPI per core, loop in the handler: a single IPI per follower, but the whole ~2048-iteration loop runs
non-preemptible with IRQs disabled.
Followers are RMP-scan cache hits (cheap) and this only runs at setup/teardown, so I'm leaning toward (B) — but it does
mean a bounded non-preemptible/IRQ-off window per core. If you'd rather keep it preemptible, I can run the per-core loop
as per-CPU work instead. Which do you prefer?
Thanks,
Ashish