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