Re: [PATCH] x86/hyperv: Disable preemption while setting reenlightenment vector

From: Peter Zijlstra
Date: Fri Jun 14 2019 - 08:32:23 EST


On Fri, Jun 14, 2019 at 12:50:51PM +0100, Dmitry Safonov wrote:
> On 6/14/19 11:08 AM, Vitaly Kuznetsov wrote:
> > Peter Zijlstra <peterz@xxxxxxxxxxxxx> writes:
> >
> >> @@ -182,7 +182,7 @@ void set_hv_tscchange_cb(void (*cb)(void))
> >> struct hv_reenlightenment_control re_ctrl = {
> >> .vector = HYPERV_REENLIGHTENMENT_VECTOR,
> >> .enabled = 1,
> >> - .target_vp = hv_vp_index[smp_processor_id()]
> >> + .target_vp = hv_vp_index[raw_smp_processor_id()]
> >> };
> >> struct hv_tsc_emulation_control emu_ctrl = {.enabled = 1};
> >>
> >
> > Yes, this should do, thanks! I'd also suggest to leave a comment like
> > /*
> > * This function can get preemted and migrate to a different CPU
> > * but this doesn't matter. We just need to assign
> > * reenlightenment notification to some online CPU. In case this
> > * CPU goes offline, hv_cpu_die() will re-assign it to some
> > * other online CPU.
> > */
>
> What if the cpu goes down just before wrmsrl()?
> I mean, hv_cpu_die() will reassign another cpu, but this thread will be
> resumed on some other cpu and will write cpu number which is at that
> moment already down?
>
> (probably I miss something)
>
> And I presume it's guaranteed that during hv_cpu_die() no other cpu may
> go down:
> : new_cpu = cpumask_any_but(cpu_online_mask, cpu);
> : re_ctrl.target_vp = hv_vp_index[new_cpu];
> : wrmsrl(HV_X64_MSR_REENLIGHTENMENT_CONTROL, *((u64 *)&re_ctrl));

Then cpus_read_lock() is the right interface, not preempt_disable().

I know you probably can't change the HV interface, but I'm thinking its
rather daft you have to specify a CPU at all for this. The HV can just
pick one and send the notification there, who cares.