On Mon, Jul 27, 2020 at 03:05:36PM +0200, pet...@infradead.org wrote: > Yeah, I'm not sure.. the 'funny' thing is that typically call > sync_core() from an IPI anyway. And the synchronous broadcast IPI is by > far the most expensive part of that. > > Something like this... > > diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c > index 20e07feb4064..528e049ee1d9 100644 > --- a/arch/x86/kernel/alternative.c > +++ b/arch/x86/kernel/alternative.c > @@ -989,12 +989,13 @@ void *text_poke_kgdb(void *addr, const void *opcode, > size_t len) > > static void do_sync_core(void *info) > { > - sync_core(); > + /* IRET implies sync_core() */ > } > > void text_poke_sync(void) > { > on_each_cpu(do_sync_core, NULL, 1); > + sync_core(); > } > > struct text_poke_loc {
So 'people' have wanted to optimize this for NOHZ_FULL and I suppose virt as well. IFF VMENTER is serializing, I suppose we can simply do something like: bool text_poke_cond(int cpu, void *info) { /* * If we observe the vCPU is preempted, it will do VMENTER * no point in sending an IPI to SERIALIZE. */ return !vcpu_is_preempted(cpu); } void text_poke_sync(void) { smp_call_function_many_cond(cpu_possible_mask, do_sync_core, NULL, 1, text_poke_cond); sync_core(); } The 'same' for NOHZ_FULL, except we need to cmpxchg a value such that if the cmpxchg() succeeds we know the CPU is in userspace and will SERIALIZE on the next entry. Much like kvm_flush_tlb_others(). Anyway, that's all hand-wavey.. I'll let someone that cares about those things write actual patches :-)