[PATCH v1 06/11] KVM: s390: Introduce extended topup for struct kvm_s390_mmu_cache
Claudio Imbrenda <[email protected]>
| Newsgroups | org.kernel.vger.linux-s390,org.kernel.vger.kvm,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
In most cases the mmu caches should not blow up in size unnecessarily, since there is one for each vCPU, as it can add up to a quite big amount of memory. In some cases, though, it is necessary to have a particularly large mmu cache, to guarantee that specific operations can complete without needing to refill the cache. This patch refactors the existing kvm_s390_mmu_cache_topup() function to allow for an extended top-up. Two wrappers are also provided, one with the old name and old behaviour, and one that performs the extended top-up. Signed-off-by: Claudio Imbrenda <[email protected]> --- arch/s390/kvm/dat.c | 11 +++++++---- arch/s390/kvm/dat.h | 25 +++++++++++++++++++++---- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/arch/s390/kvm/dat.c b/arch/s390/kvm/dat.c index f4dd6f783417..47ff8af1b22f 100644 --- a/arch/s390/kvm/dat.c +++ b/arch/s390/kvm/dat.c @@ -28,23 +28,26 @@ #include <asm/tlb.h> #include "dat.h" -int kvm_s390_mmu_cache_topup(struct kvm_s390_mmu_cache *mc) +int _kvm_s390_mmu_cache_topup(struct kvm_s390_mmu_cache *mc, bool extended) { + size_t n_crsts = extended ? KVM_S390_MMU_CACHE_N_CRSTS_MAX : KVM_S390_MMU_CACHE_N_CRSTS; + size_t n_pts = extended ? KVM_S390_MMU_CACHE_N_PTS_MAX : KVM_S390_MMU_CACHE_N_PTS; + size_t n_rmaps = extended ? KVM_S390_MMU_CACHE_N_RMAPS_MAX : KVM_S390_MMU_CACHE_N_RMAPS; void *o; - for ( ; mc->n_crsts < KVM_S390_MMU_CACHE_N_CRSTS; mc->n_crsts++) { + for ( ; mc->n_crsts < n_crsts; mc->n_crsts++) { o = (void *)__get_free_pages(GFP_KERNEL_ACCOUNT | __GFP_COMP, CRST_ALLOC_ORDER); if (!o) return -ENOMEM; mc->crsts[mc->n_crsts] = o; } - for ( ; mc->n_pts < KVM_S390_MMU_CACHE_N_PTS; mc->n_pts++) { + for ( ; mc->n_pts < n_pts; mc->n_pts++) { o = (void *)__get_free_page(GFP_KERNEL_ACCOUNT); if (!o) return -ENOMEM; mc->pts[mc->n_pts] = o; } - for ( ; mc->n_rmaps < KVM_S390_MMU_CACHE_N_RMAPS; mc->n_rmaps++) { + for ( ; mc->n_rmaps < n_rmaps; mc->n_rmaps++) { o = kzalloc_obj(struct vsie_rmap, GFP_KERNEL_ACCOUNT); if (!o) return -ENOMEM; diff --git a/arch/s390/kvm/dat.h b/arch/s390/kvm/dat.h index 141ee7b9f019..461302f05e50 100644 --- a/arch/s390/kvm/dat.h +++ b/arch/s390/kvm/dat.h @@ -479,13 +479,20 @@ struct vsie_rmap { static_assert(sizeof(struct vsie_rmap) == 2 * sizeof(long)); +/* Used when performing normal top-ups */ #define KVM_S390_MMU_CACHE_N_CRSTS 6 #define KVM_S390_MMU_CACHE_N_PTS 2 #define KVM_S390_MMU_CACHE_N_RMAPS 16 + +/* Used to perform special extended top-ups */ +#define KVM_S390_MMU_CACHE_N_CRSTS_MAX 32 +#define KVM_S390_MMU_CACHE_N_PTS_MAX 8 +#define KVM_S390_MMU_CACHE_N_RMAPS_MAX 16 + struct kvm_s390_mmu_cache { - void *crsts[KVM_S390_MMU_CACHE_N_CRSTS]; - void *pts[KVM_S390_MMU_CACHE_N_PTS]; - void *rmaps[KVM_S390_MMU_CACHE_N_RMAPS]; + void *crsts[KVM_S390_MMU_CACHE_N_CRSTS_MAX]; + void *pts[KVM_S390_MMU_CACHE_N_PTS_MAX]; + void *rmaps[KVM_S390_MMU_CACHE_N_RMAPS_MAX]; short int n_crsts; short int n_pts; short int n_rmaps; @@ -555,7 +562,17 @@ int dat_get_cmma(union asce asce, gfn_t *start, unsigned int *count, u8 *values, int dat_set_cmma_bits(struct kvm_s390_mmu_cache *mc, union asce asce, gfn_t gfn, unsigned long count, unsigned long mask, const uint8_t *bits); -int kvm_s390_mmu_cache_topup(struct kvm_s390_mmu_cache *mc); +int _kvm_s390_mmu_cache_topup(struct kvm_s390_mmu_cache *mc, bool extended); + +static inline int kvm_s390_mmu_cache_topup(struct kvm_s390_mmu_cache *mc) +{ + return _kvm_s390_mmu_cache_topup(mc, false); +} + +static inline int kvm_s390_mmu_cache_extended_topup(struct kvm_s390_mmu_cache *mc) +{ + return _kvm_s390_mmu_cache_topup(mc, true); +} #define GFP_KVM_S390_MMU_CACHE (GFP_ATOMIC | __GFP_ACCOUNT | __GFP_NOWARN) -- 2.55.0