This series is extracted out from the NUMA aware page table series[1].
MMU shrinker changes were in patches 1 to 9 in the old series.
This series is changing KVM MMU shrinker behaviour by emptying MMU page
caches which are used during page fault and MMU load operations. It also
incorporates feedback from the NUMA aware page table series[1] regarding
MMU shrinker.
KVM MMU shrinker has not been very effective in alleviating pain under
memory pressure. It frees up the pages actively being used which results
in VM degradation. VM will take fault and bring them again in page
tables. More discussions happened at [2]. Overall, consensus was to
reprupose it into the code which frees pages from KVM MMU page caches.
Recently [3], there was a discussion to disable shrinker for TDP MMU.
Revival of this series is result of that discussion.
There are two major differences from the old series.
1. There is no global accounting of cache pages. It is dynamically
calculated in mmu_shrink_count(). This has two effects; i) counting will
be inaccurate but code is much simpler, and ii) kvm_lock being used
here, this should be fine as mmu_shrink_scan() also holds the lock
for its operation.
2. Only empty mmu_shadow_page_cache and mmu_shadowed_info_cache. This
version doesn't empty split_shadow_page_cache as it is used only
during dirty logging operation and is one per VM unlike other two
which are per vCPU. I am not fully convinced that adding it is needed
as it will add the cost of adding one more mutex and synchronizing it
in shrinker. Also, if a VM is being dirty tracked most likely it will
be migrated (memory pressure might be the reason in the first place)
so better to not hinder migration effort and let vCPUs free up their
caches. If someone convinces me to add split cache as well then I can
send a separate patch to add that as well.
[1] https://lore.kernel.org/kvm/20230306224127.1689967-1-vipinsh@google.com/
[2] https://lore.kernel.org/lkml/Y45dldZnI6OIf+a5@google.com/
[3] https://lore.kernel.org/kvm/20240819214014.GA2313467.vipinsh@google.com/#t
Note to maintainers: scripts/checkpatch.pl is complaining about few
things on selftest (patch 3). These are just false positives.
1. Prefer strscpy() over strcpy().
This kernel API and not general libc userspace API.
2. Unnecessary whitespace before a quoted new line.
Just the way help string is written for selftests to align output of
help.
3. Prefer using '"%s...", __func__'
Because I wrote "help" word in the printf().
v2:
- Add a new selftest, mmu_shrinker_test.
v1: https://lore.kernel.org/kvm/20240913214316.1945951-1-vipinsh@google.com/
- No global counting of pages in cache. As this number might not remain
same between calls of mmu_shrink_count() and mmu_shrink_scan().
- Count cache pages in mmu_shrink_count(). KVM can tolerate inaccuracy
here.
- Empty mmu_shadow_page_cache and mmu_shadowed_info_cache only. Don't
empty split_shadow_page_cache.
v0: Patches 1-9 from NUMA aware page table series.
https://lore.kernel.org/kvm/20230306224127.1689967-1-vipinsh@google.com/
Vipin Sharma (3):
KVM: x86/mmu: Change KVM mmu shrinker to no-op
KVM: x86/mmu: Use MMU shrinker to shrink KVM MMU memory caches
KVM: selftests: Add a test to invoke MMU shrinker on KVM VMs
arch/x86/include/asm/kvm_host.h | 7 +-
arch/x86/kvm/mmu/mmu.c | 139 ++++-----
arch/x86/kvm/mmu/paging_tmpl.h | 14 +-
include/linux/kvm_host.h | 1 +
tools/testing/selftests/kvm/Makefile | 1 +
.../testing/selftests/kvm/include/test_util.h | 5 +
tools/testing/selftests/kvm/lib/test_util.c | 51 ++++
.../selftests/kvm/x86_64/mmu_shrinker_test.c | 269 ++++++++++++++++++
virt/kvm/kvm_main.c | 8 +-
9 files changed, 404 insertions(+), 91 deletions(-)
create mode 100644 tools/testing/selftests/kvm/x86_64/mmu_shrinker_test.c
base-commit: 12680d7b8ac4db2eba6237a21a93d2b0e78a52a6
--
2.47.0.rc0.187.ge670bccf7e-goog