On 02/15/2012 11:18 AM, Avi Kivity wrote:
> On 02/14/2012 09:43 PM, Marcelo Tosatti wrote:
> > Also it should not be necessary for these flushes to be inside mmu_lock
> > on EPT/NPT case (since there is no write protection there).
>
> We do write protect with TDP, if nested virt is active. The question is
> whether we have indirect pages or not, not whether TDP is active or not
> (even without TDP, if you don't enable paging in the guest, you don't
> have to write protect).
>
> > But it would
> > be awkward to differentiate the unlock position based on EPT/NPT.
> >
>
> I would really like to move the IPI back out of the lock.
>
> How about something like a sequence lock:
>
>
> spin_lock(mmu_lock)
> need_flush = write_protect_stuff();
> atomic_add(kvm->want_flush_counter, need_flush);
> spin_unlock(mmu_lock);
>
> while ((done = atomic_read(kvm->done_flush_counter)) < (want =
> atomic_read(kvm->want_flush_counter)) {
> kvm_make_request(flush)
> atomic_cmpxchg(kvm->done_flush_counter, done, want)
> }
>
> This (or maybe a corrected and optimized version) ensures that any
> need_flush cannot pass the while () barrier, no matter which thread
> encounters it first. However it violates the "do not invent new locking
> techniques" commandment. Can we map it to some existing method?
There is no need to advance 'want' in the loop. So we could do
/* must call with mmu_lock held */
void kvm_mmu_defer_remote_flush(kvm, need_flush)
{
if (need_flush)
++kvm->flush_counter.want;
}
/* may call without mmu_lock */
void kvm_mmu_commit_remote_flush(kvm)
{
want = ACCESS_ONCE(kvm->flush_counter.want)
while ((done = atomic_read(kvm->flush_counter.done) < want) {
kvm_make_request(flush)
atomic_cmpxchg(kvm->flush_counter.done, done, want)
}
}
--
error compiling committee.c: too many arguments to function
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html