All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sean Christopherson <seanjc@google.com>
To: David Matlack <dmatlack@google.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>,
	kvm@vger.kernel.org, linux-kernel@vger.kernel.org,
	Jeremi Piotrowski <jpiotrowski@linux.microsoft.com>,
	Ben Gardon <bgardon@google.com>
Subject: Re: [PATCH v2] KVM: x86: Preserve TDP MMU roots until they are explicitly invalidated
Date: Fri, 21 Apr 2023 18:56:35 -0700	[thread overview]
Message-ID: <ZEM+09p7QBJR7DoI@google.com> (raw)
In-Reply-To: <CALzav=f=TFoqpR5tPDPOujoO6Gix-+zL-sZyyZK27qJvGPP9dg@mail.gmail.com>

On Fri, Apr 21, 2023, David Matlack wrote:
> On Fri, Apr 21, 2023 at 2:49 PM Sean Christopherson <seanjc@google.com> wrote:
> >
> >  void kvm_tdp_mmu_invalidate_all_roots(struct kvm *kvm)
> >  {
> >         struct kvm_mmu_page *root;
> >
> > -       lockdep_assert_held_write(&kvm->mmu_lock);
> > -       list_for_each_entry(root, &kvm->arch.tdp_mmu_roots, link) {
> > -               if (!root->role.invalid &&
> > -                   !WARN_ON_ONCE(!kvm_tdp_mmu_get_root(root))) {
> > +       /*
> > +        * Note!  mmu_lock isn't held when destroying the VM!  There can't be
> > +        * other references to @kvm, i.e. nothing else can invalidate roots,
> > +        * but walking the list of roots does need to be guarded against roots
> > +        * being deleted by the asynchronous zap worker.
> > +        */
> > +       rcu_read_lock();
> > +
> > +       list_for_each_entry_rcu(root, &kvm->arch.tdp_mmu_roots, link) {
> 
> I see that roots are removed from the list with list_del_rcu(), so I
> agree this should be safe.
> 
> KVM could, alternatively, acquire the mmu_lock in
> kvm_mmu_uninit_tdp_mmu(), which would let us keep the lockdep
> assertion and drop the rcu_read_lock() + comment. That might be worth
> it in case someone accidentally adds a call to
> kvm_tdp_mmu_invalidate_all_roots() without mmu_lock outside of VM
> teardown. kvm_mmu_uninit_tdp_mmu() is not a particularly performance
> sensitive path and adding the mmu_lock wouldn't add much overhead
> anyway (it would block for at most a few milliseconds waiting for the
> async work to reschedule).

Heh, I actually started to ping you off-list to specifically discuss this option,
but then decided that not waiting those few milliseconds might be worthwhile for
some use cases.  I also couldn't quite convince myself that it would only be a few
milliseconds, e.g. if the worker is zapping a fully populated 5-level root, there
are no other tasks scheduled on _its_ CPU, and CONFIG_PREEMPTION=n (which neuters
rwlock_needbreak()).

The other reason I opted for not taking mmu_lock is that, with the persistent roots
approach, I don't think it's actually strictly necessary for kvm_mmu_zap_all_fast()
to invaliate roots while holding mmu_lock for write.  Holding slots_lock ensures
that only a single task can be doing invalidations, versus the old model where
putting the last reference to a root could happen just about anywhere.  And
allocating a new root and zapping from mmu_noitifiers requires holding mmu_lock for
write, so I _think_ we could getaway with holding mmu_lock for read.  Maybe.

It's largely a moot point since kvm_mmu_zap_all_fast() needs to hold mmu_lock for
write anyways to play nice with the shadow MMU, i.e. I don't expect us to ever
want to pursue a change in this area.  But at the same time I was struggling to
write a comment explaining why the VM destruction path "had" to take mmu_lock.

  reply	other threads:[~2023-04-22  1:56 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-04-21 21:49 [PATCH v2] KVM: x86: Preserve TDP MMU roots until they are explicitly invalidated Sean Christopherson
2023-04-21 21:56 ` Sean Christopherson
2023-04-21 23:12 ` David Matlack
2023-04-22  1:56   ` Sean Christopherson [this message]
2023-04-24 23:54     ` David Matlack
2023-04-25  0:36       ` Sean Christopherson
2023-04-25 22:01         ` David Matlack
2023-04-26  1:54           ` Sean Christopherson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZEM+09p7QBJR7DoI@google.com \
    --to=seanjc@google.com \
    --cc=bgardon@google.com \
    --cc=dmatlack@google.com \
    --cc=jpiotrowski@linux.microsoft.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.