Re: [patch 27/30] xen/events: Only force affinity mask for percpu interrupts

From: Thomas Gleixner
Date: Fri Dec 11 2020 - 17:58:31 EST


Andrew,

On Fri, Dec 11 2020 at 22:21, Andrew Cooper wrote:
> On 11/12/2020 21:27, Thomas Gleixner wrote:
>> It's not any different from the hardware example at least not as far as
>> I understood the code.
>
> Xen's event channels do have a couple of quirks.

Why am I not surprised?

> Binding an event channel always results in one spurious event being
> delivered.  This is to cover notifications which can get lost during the
> bidirectional setup, or re-setups in certain configurations.
>
> Binding an interdomain or pirq event channel always defaults to vCPU0. 
> There is no way to atomically set the affinity while binding.  I believe
> the API predates SMP guest support in Xen, and noone has fixed it up
> since.

That's fine. I'm not changing that.

What I'm changing is the unwanted and unnecessary overwriting of the
actual affinity mask.

We have a similar issue on real hardware where we can only target _one_
CPU and not all CPUs in the affinity mask. So we still can preserve the
(user) requested mask and just affine it to one CPU which is reflected
in the effective affinity mask. This the right thing to do for two
reasons:

1) It allows proper interrupt distribution

2) It does not break (user) requested affinity when the effective
target CPU goes offline and the affinity mask still contains
online CPUs. If you overwrite it you lost track of the requested
broader mask.

> As a consequence, the guest will observe the event raised on vCPU0 as
> part of setting up the event, even if it attempts to set a different
> affinity immediately afterwards.  A little bit of care needs to be taken
> when binding an event channel on vCPUs other than 0, to ensure that the
> callback is safe with respect to any remaining state needing
> initialisation.

That's preserved for all non percpu interrupts. The percpu variant of
VIRQ and IPIs did binding to vCPU != 0 already before this change.

> Beyond this, there is nothing magic I'm aware of.
>
> We have seen soft lockups before in certain scenarios, simply due to the
> quantity of events hitting vCPU0 before irqbalance gets around to
> spreading the load.  This is why there is an attempt to round-robin the
> userspace event channel affinities by default, but I still don't see why
> this would need custom affinity logic itself.

Just the previous attempt makes no sense for the reasons I outlined in
the changelog. So now with this new spreading mechanics you get the
distribution for all cases:

1) Post setup using and respecting the default affinity mask which can
be set as a kernel commandline parameter.

2) Runtime (user) requested affinity change with a mask which contains
more than one vCPU. The previous logic always chose the first one
in the mask.

So assume userspace affines 4 irqs to a CPU 0-3 and 4 irqs to CPU
4-7 then 4 irqs end up on CPU0 and 4 on CPU4

The new algorithm which is similar to what we have on x86 (minus
the vector space limitation) picks the CPU which has the least
number of channels affine to it at that moment. If e.g. all 8 CPUs
have the same number of vectors before that change then in the
example above the first 4 are spread to CPU0-3 and the second 4 to
CPU4-7

Thanks,

tglx