Skip to content

Commit c3235e2

Browse files
Nico Boehrfrankjaa
authored andcommitted
KVM: s390: add stat counter for shadow gmap events
The shadow gmap tracks memory of nested guests (guest-3). In certain scenarios, the shadow gmap needs to be rebuilt, which is a costly operation since it involves a SIE exit into guest-1 for every entry in the respective shadow level. Add kvm stat counters when new shadow structures are created at various levels. Also add a counter gmap_shadow_create when a completely fresh shadow gmap is created as well as a counter gmap_shadow_reuse when an existing gmap is being reused. Note that when several levels are shadowed at once, counters on all affected levels will be increased. Also note that not all page table levels need to be present and a ASCE can directly point to e.g. a segment table. In this case, a new segment table will always be equivalent to a new shadow gmap and hence will be counted as gmap_shadow_create and not as gmap_shadow_segment. Signed-off-by: Nico Boehr <[email protected]> Reviewed-by: David Hildenbrand <[email protected]> Reviewed-by: Claudio Imbrenda <[email protected]> Reviewed-by: Janosch Frank <[email protected]> Signed-off-by: Janosch Frank <[email protected]> Link: https://lore.kernel.org/r/[email protected] Message-Id: <[email protected]>
1 parent ce9ecca commit c3235e2

File tree

4 files changed

+26
-2
lines changed

4 files changed

+26
-2
lines changed

arch/s390/include/asm/kvm_host.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -777,6 +777,13 @@ struct kvm_vm_stat {
777777
u64 inject_service_signal;
778778
u64 inject_virtio;
779779
u64 aen_forward;
780+
u64 gmap_shadow_create;
781+
u64 gmap_shadow_reuse;
782+
u64 gmap_shadow_r1_entry;
783+
u64 gmap_shadow_r2_entry;
784+
u64 gmap_shadow_r3_entry;
785+
u64 gmap_shadow_sg_entry;
786+
u64 gmap_shadow_pg_entry;
780787
};
781788

782789
struct kvm_arch_memory_slot {

arch/s390/kvm/gaccess.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1382,6 +1382,7 @@ static int kvm_s390_shadow_tables(struct gmap *sg, unsigned long saddr,
13821382
unsigned long *pgt, int *dat_protection,
13831383
int *fake)
13841384
{
1385+
struct kvm *kvm;
13851386
struct gmap *parent;
13861387
union asce asce;
13871388
union vaddress vaddr;
@@ -1390,6 +1391,7 @@ static int kvm_s390_shadow_tables(struct gmap *sg, unsigned long saddr,
13901391

13911392
*fake = 0;
13921393
*dat_protection = 0;
1394+
kvm = sg->private;
13931395
parent = sg->parent;
13941396
vaddr.addr = saddr;
13951397
asce.val = sg->orig_asce;
@@ -1450,6 +1452,7 @@ static int kvm_s390_shadow_tables(struct gmap *sg, unsigned long saddr,
14501452
rc = gmap_shadow_r2t(sg, saddr, rfte.val, *fake);
14511453
if (rc)
14521454
return rc;
1455+
kvm->stat.gmap_shadow_r1_entry++;
14531456
}
14541457
fallthrough;
14551458
case ASCE_TYPE_REGION2: {
@@ -1478,6 +1481,7 @@ static int kvm_s390_shadow_tables(struct gmap *sg, unsigned long saddr,
14781481
rc = gmap_shadow_r3t(sg, saddr, rste.val, *fake);
14791482
if (rc)
14801483
return rc;
1484+
kvm->stat.gmap_shadow_r2_entry++;
14811485
}
14821486
fallthrough;
14831487
case ASCE_TYPE_REGION3: {
@@ -1515,6 +1519,7 @@ static int kvm_s390_shadow_tables(struct gmap *sg, unsigned long saddr,
15151519
rc = gmap_shadow_sgt(sg, saddr, rtte.val, *fake);
15161520
if (rc)
15171521
return rc;
1522+
kvm->stat.gmap_shadow_r3_entry++;
15181523
}
15191524
fallthrough;
15201525
case ASCE_TYPE_SEGMENT: {
@@ -1548,6 +1553,7 @@ static int kvm_s390_shadow_tables(struct gmap *sg, unsigned long saddr,
15481553
rc = gmap_shadow_pgt(sg, saddr, ste.val, *fake);
15491554
if (rc)
15501555
return rc;
1556+
kvm->stat.gmap_shadow_sg_entry++;
15511557
}
15521558
}
15531559
/* Return the parent address of the page table */
@@ -1618,6 +1624,7 @@ int kvm_s390_shadow_fault(struct kvm_vcpu *vcpu, struct gmap *sg,
16181624
pte.p |= dat_protection;
16191625
if (!rc)
16201626
rc = gmap_shadow_page(sg, saddr, __pte(pte.val));
1627+
vcpu->kvm->stat.gmap_shadow_pg_entry++;
16211628
ipte_unlock(vcpu->kvm);
16221629
mmap_read_unlock(sg->mm);
16231630
return rc;

arch/s390/kvm/kvm-s390.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,14 @@ const struct _kvm_stats_desc kvm_vm_stats_desc[] = {
6666
STATS_DESC_COUNTER(VM, inject_pfault_done),
6767
STATS_DESC_COUNTER(VM, inject_service_signal),
6868
STATS_DESC_COUNTER(VM, inject_virtio),
69-
STATS_DESC_COUNTER(VM, aen_forward)
69+
STATS_DESC_COUNTER(VM, aen_forward),
70+
STATS_DESC_COUNTER(VM, gmap_shadow_reuse),
71+
STATS_DESC_COUNTER(VM, gmap_shadow_create),
72+
STATS_DESC_COUNTER(VM, gmap_shadow_r1_entry),
73+
STATS_DESC_COUNTER(VM, gmap_shadow_r2_entry),
74+
STATS_DESC_COUNTER(VM, gmap_shadow_r3_entry),
75+
STATS_DESC_COUNTER(VM, gmap_shadow_sg_entry),
76+
STATS_DESC_COUNTER(VM, gmap_shadow_pg_entry),
7077
};
7178

7279
const struct kvm_stats_header kvm_vm_stats_header = {

arch/s390/kvm/vsie.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1214,15 +1214,18 @@ static int acquire_gmap_shadow(struct kvm_vcpu *vcpu,
12141214
* we're holding has been unshadowed. If the gmap is still valid,
12151215
* we can safely reuse it.
12161216
*/
1217-
if (vsie_page->gmap && gmap_shadow_valid(vsie_page->gmap, asce, edat))
1217+
if (vsie_page->gmap && gmap_shadow_valid(vsie_page->gmap, asce, edat)) {
1218+
vcpu->kvm->stat.gmap_shadow_reuse++;
12181219
return 0;
1220+
}
12191221

12201222
/* release the old shadow - if any, and mark the prefix as unmapped */
12211223
release_gmap_shadow(vsie_page);
12221224
gmap = gmap_shadow(vcpu->arch.gmap, asce, edat);
12231225
if (IS_ERR(gmap))
12241226
return PTR_ERR(gmap);
12251227
gmap->private = vcpu->kvm;
1228+
vcpu->kvm->stat.gmap_shadow_create++;
12261229
WRITE_ONCE(vsie_page->gmap, gmap);
12271230
return 0;
12281231
}

0 commit comments

Comments
 (0)