On Sat, Oct 22, 2022, Marc Zyngier wrote: > On Fri, 21 Oct 2022 17:05:26 +0100, Sean Christopherson <seanjc@xxxxxxxxxx> wrote: > > > > On Fri, Oct 21, 2022, Marc Zyngier wrote: > > > Because dirtying memory outside of a vcpu context makes it > > > incredibly awkward to handle a "ring full" condition? > > > > Kicking all vCPUs with the soft-full request isn't _that_ awkward. > > It's certainly sub-optimal, but if inserting into the per-VM ring is > > relatively rare, then in practice it's unlikely to impact guest > > performance. > > But there is *nothing* to kick here. The kernel is dirtying pages, > devices are dirtying pages (DMA), and there is no context associated > with that. Which is why a finite ring is the wrong abstraction. I don't follow. If there's a VM, KVM can always kick all vCPUs. Again, might be far from optimal, but it's an option. If there's literally no VM, then KVM isn't involved at all and there's no "ring vs. bitmap" decision. > > Would it be possible to require a dirty bitmap when an ITS is > > created? That would allow treating the above condition as a KVM > > bug. > > No. This should be optional. Everything about migration should be > absolutely optional (I run plenty of concurrent VMs on sub-2GB > systems). You want to migrate a VM that has an ITS or will collect > dirty bits originating from a SMMU with HTTU, you enable the dirty > bitmap. You want to have *vcpu* based dirty rings, you enable them. > > In short, there shouldn't be any reason for the two are either > mandatory or conflated. Both should be optional, independent, because > they cover completely disjoined use cases. *userspace* should be in > charge of deciding this. I agree about userspace being in control, what I want to avoid is letting userspace put KVM into a bad state without any indication from KVM that the setup is wrong until something actually dirties a page. Specifically, if mark_page_dirty_in_slot() is invoked without a running vCPU, on a memslot with dirty tracking enabled but without a dirty bitmap, then the migration is doomed. Dropping the dirty page isn't a sane response as that'd all but guaranatee memory corruption in the guest. At best, KVM could kick all vCPUs out to userspace with a new exit reason, but that's not a very good experience for userspace as either the VM is unexpectedly unmigratable or the VM ends up being killed (or I suppose userspace could treat the exit as a per-VM dirty ring of size '1'). That's why I asked if it's possible for KVM to require a dirty_bitmap when KVM might end up collecting dirty information without a vCPU. KVM is still technically prescribing a solution to userspace, but only because there's only one solution. > > > > The acquire-release thing is irrelevant for x86, and no other > > > > architecture supports the dirty ring until this series, i.e. there's > > > > no need for KVM to detect that userspace has been updated to gain > > > > acquire-release semantics, because the fact that userspace is > > > > enabling the dirty ring on arm64 means userspace has been updated. > > > > > > Do we really need to make the API more awkward? There is an > > > established pattern of "enable what is advertised". Some level of > > > uniformity wouldn't hurt, really. > > > > I agree that uniformity would be nice, but for capabilities I don't > > think that's ever going to happen. I'm pretty sure supporting > > enabling is actually in the minority. E.g. of the 20 capabilities > > handled in kvm_vm_ioctl_check_extension_generic(), I believe only 3 > > support enabling (KVM_CAP_HALT_POLL, KVM_CAP_DIRTY_LOG_RING, and > > KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2). > > I understood that you were advocating that a check for KVM_CAP_FOO > could result in enabling KVM_CAP_BAR. That I definitely object to. I was hoping KVM could make the ACQ_REL capability an extension of DIRTY_LOG_RING, i.e. userspace would DIRTY_LOG_RING _and_ DIRTY_LOG_RING_ACQ_REL for ARM and other architectures, e.g. int enable_dirty_ring(void) { if (!kvm_check(KVM_CAP_DIRTY_LOG_RING)) return -EINVAL; if (!tso && !kvm_check(KVM_CAP_DIRTY_LOG_RING_ACQ_REL)) return -EINVAL; return kvm_enable(KVM_CAP_DIRTY_LOG_RING); } But I failed to consider that userspace might try to enable DIRTY_LOG_RING on all architectures, i.e. wouldn't arbitrarily restrict DIRTY_LOG_RING to x86.