Re: [PATCH v11 4/6] x86/sev: Add support to perform RMP optimizations asynchronously

"Kalra, Ashish" <[email protected]> Mon, 3 Aug 2026 13:56:23 -0500
Newsgroups org.kernel.vger.linux-crypto,dev.linux.lists.linux-coco,org.kernel.vger.kvm,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
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