KVM: arm64: Do not transfer page refcount for THP adjustment
authorVincent Donnefort <vdonnefort@google.com>
Thu, 28 Sep 2023 17:32:03 +0000 (18:32 +0100)
committerOliver Upton <oliver.upton@linux.dev>
Sat, 30 Sep 2023 17:17:45 +0000 (17:17 +0000)
GUP affects a refcount common to all pages forming the THP. There is
therefore no need to move the refcount from a tail to the head page.
Under the hood it decrements and increments the same counter.

Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
Reviewed-by: Gavin Shan <gshan@redhat.com>
Reviewed-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20230928173205.2826598-2-vdonnefort@google.com
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
arch/arm64/kvm/mmu.c

index 587a104..de5e514 100644 (file)
@@ -1295,28 +1295,8 @@ transparent_hugepage_adjust(struct kvm *kvm, struct kvm_memory_slot *memslot,
                if (sz < PMD_SIZE)
                        return PAGE_SIZE;
 
-               /*
-                * The address we faulted on is backed by a transparent huge
-                * page.  However, because we map the compound huge page and
-                * not the individual tail page, we need to transfer the
-                * refcount to the head page.  We have to be careful that the
-                * THP doesn't start to split while we are adjusting the
-                * refcounts.
-                *
-                * We are sure this doesn't happen, because mmu_invalidate_retry
-                * was successful and we are holding the mmu_lock, so if this
-                * THP is trying to split, it will be blocked in the mmu
-                * notifier before touching any of the pages, specifically
-                * before being able to call __split_huge_page_refcount().
-                *
-                * We can therefore safely transfer the refcount from PG_tail
-                * to PG_head and switch the pfn from a tail page to the head
-                * page accordingly.
-                */
                *ipap &= PMD_MASK;
-               kvm_release_pfn_clean(pfn);
                pfn &= ~(PTRS_PER_PMD - 1);
-               get_page(pfn_to_page(pfn));
                *pfnp = pfn;
 
                return PMD_SIZE;