Commit e46ad851 authored by Sean Christopherson's avatar Sean Christopherson
Browse files

KVM: Use mask of harvested dirty ring entries to coalesce dirty ring resets



Use "mask" instead of a dedicated boolean to track whether or not there
is at least one to-be-reset entry for the current slot+offset.  In the
body of the loop, mask is zero only on the first iteration, i.e. !mask is
equivalent to first_round.

Opportunistically combine the adjacent "if (mask)" statements into a single
if-statement.

No functional change intended.

Cc: Peter Xu <peterx@redhat.com>
Cc: Yan Zhao <yan.y.zhao@intel.com>
Cc: Maxim Levitsky <mlevitsk@redhat.com>
Reviewed-by: default avatarPankaj Gupta <pankaj.gupta@amd.com>
Reviewed-by: default avatarJames Houghton <jthoughton@google.com>
Reviewed-by: default avatarBinbin Wu <binbin.wu@linux.intel.com>
Reviewed-by: default avatarYan Zhao <yan.y.zhao@intel.com>
Reviewed-by: default avatarPeter Xu <peterx@redhat.com>
Link: https://lore.kernel.org/r/20250516213540.2546077-6-seanjc@google.com


Signed-off-by: default avatarSean Christopherson <seanjc@google.com>
parent ee188dea
Loading
Loading
Loading
Loading
+31 −33
Original line number Diff line number Diff line
@@ -121,7 +121,6 @@ int kvm_dirty_ring_reset(struct kvm *kvm, struct kvm_dirty_ring *ring,
	u64 cur_offset, next_offset;
	unsigned long mask = 0;
	struct kvm_dirty_gfn *entry;
	bool first_round = true;

	while (likely((*nr_entries_reset) < INT_MAX)) {
		if (signal_pending(current))
@@ -141,20 +140,20 @@ int kvm_dirty_ring_reset(struct kvm *kvm, struct kvm_dirty_ring *ring,
		ring->reset_index++;
		(*nr_entries_reset)++;

		if (mask) {
			/*
		 * While the size of each ring is fixed, it's possible for the
		 * ring to be constantly re-dirtied/harvested while the reset
		 * is in-progress (the hard limit exists only to guard against
		 * wrapping the count into negative space).
			 * While the size of each ring is fixed, it's possible
			 * for the ring to be constantly re-dirtied/harvested
			 * while the reset is in-progress (the hard limit exists
			 * only to guard against the count becoming negative).
			 */
		if (!first_round)
			cond_resched();

			/*
		 * Try to coalesce the reset operations when the guest is
		 * scanning pages in the same slot.
			 * Try to coalesce the reset operations when the guest
			 * is scanning pages in the same slot.
			 */
		if (!first_round && next_slot == cur_slot) {
			if (next_slot == cur_slot) {
				s64 delta = next_offset - cur_offset;

				if (delta >= 0 && delta < BITS_PER_LONG) {
@@ -172,11 +171,11 @@ int kvm_dirty_ring_reset(struct kvm *kvm, struct kvm_dirty_ring *ring,
			}

			/*
		 * Reset the slot for all the harvested entries that have been
		 * gathered, but not yet fully processed.
			 * Reset the slot for all the harvested entries that
			 * have been gathered, but not yet fully processed.
			 */
		if (mask)
			kvm_reset_dirty_gfn(kvm, cur_slot, cur_offset, mask);
		}

		/*
		 * The current slot was reset or this is the first harvested
@@ -185,7 +184,6 @@ int kvm_dirty_ring_reset(struct kvm *kvm, struct kvm_dirty_ring *ring,
		cur_slot = next_slot;
		cur_offset = next_offset;
		mask = 1;
		first_round = false;
	}

	/*