This addresses several issues of the cell statistics on ARM:

- only the first interrupt reason after a related vmexit is counted,
  instead of every loop iteration (could have lead to over-accounting)
- SGI submissions are not accounted as VSGI but left up to MMIO or CP15
  exits
- SGI exits are differentiated between management and VSGI events
- PSCI exits are separated counted
- coprocessor accesses are separated counted

Signed-off-by: Jan Kiszka <jan.kis...@siemens.com>
---
 driver/sysfs.c                                        |  4 ++++
 hypervisor/arch/arm/control.c                         | 19 +++++++++++--------
 hypervisor/arch/arm/gic-common.c                      |  9 +++++----
 hypervisor/arch/arm/include/asm/control.h             |  6 ++++--
 hypervisor/arch/arm/include/asm/jailhouse_hypercall.h |  4 +++-
 hypervisor/arch/arm/psci.c                            |  2 ++
 hypervisor/arch/arm/traps.c                           |  4 ++++
 7 files changed, 33 insertions(+), 15 deletions(-)

diff --git a/driver/sysfs.c b/driver/sysfs.c
index ce4dba7..4ee5d00 100644
--- a/driver/sysfs.c
+++ b/driver/sysfs.c
@@ -111,6 +111,8 @@ JAILHOUSE_CPU_STATS_ATTR(vmexits_exception,
 JAILHOUSE_CPU_STATS_ATTR(vmexits_maintenance, 
JAILHOUSE_CPU_STAT_VMEXITS_MAINTENANCE);
 JAILHOUSE_CPU_STATS_ATTR(vmexits_virt_irq, JAILHOUSE_CPU_STAT_VMEXITS_VIRQ);
 JAILHOUSE_CPU_STATS_ATTR(vmexits_virt_sgi, JAILHOUSE_CPU_STAT_VMEXITS_VSGI);
+JAILHOUSE_CPU_STATS_ATTR(vmexits_psci, JAILHOUSE_CPU_STAT_VMEXITS_PSCI);
+JAILHOUSE_CPU_STATS_ATTR(vmexits_cp15, JAILHOUSE_CPU_STAT_VMEXITS_CP15);
 #endif
 
 static struct attribute *no_attrs[] = {
@@ -130,6 +132,8 @@ static struct attribute *no_attrs[] = {
        &vmexits_maintenance_attr.kattr.attr,
        &vmexits_virt_irq_attr.kattr.attr,
        &vmexits_virt_sgi_attr.kattr.attr,
+       &vmexits_psci_attr.kattr.attr,
+       &vmexits_cp15_attr.kattr.attr,
 #endif
        NULL
 };
diff --git a/hypervisor/arch/arm/control.c b/hypervisor/arch/arm/control.c
index b01288d..17ba172 100644
--- a/hypervisor/arch/arm/control.c
+++ b/hypervisor/arch/arm/control.c
@@ -299,15 +299,17 @@ static void check_events(struct per_cpu *cpu_data)
                cpu_reset();
 }
 
-void arch_handle_sgi(struct per_cpu *cpu_data, u32 irqn)
+void arch_handle_sgi(struct per_cpu *cpu_data, u32 irqn,
+                    unsigned int count_event)
 {
-       cpu_data->stats[JAILHOUSE_CPU_STAT_VMEXITS_MANAGEMENT]++;
-
        switch (irqn) {
        case SGI_INJECT:
+               cpu_data->stats[JAILHOUSE_CPU_STAT_VMEXITS_VSGI] += count_event;
                irqchip_inject_pending(cpu_data);
                break;
        case SGI_EVENT:
+               cpu_data->stats[JAILHOUSE_CPU_STAT_VMEXITS_MANAGEMENT] +=
+                       count_event;
                check_events(cpu_data);
                break;
        default:
@@ -331,17 +333,18 @@ unsigned int arm_cpu_virt2phys(struct cell *cell, 
unsigned int virt_id)
  * Handle the maintenance interrupt, the rest is injected into the cell.
  * Return true when the IRQ has been handled by the hyp.
  */
-bool arch_handle_phys_irq(struct per_cpu *cpu_data, u32 irqn)
+bool arch_handle_phys_irq(struct per_cpu *cpu_data, u32 irqn,
+                         unsigned int count_event)
 {
        if (irqn == MAINTENANCE_IRQ) {
-               cpu_data->stats[JAILHOUSE_CPU_STAT_VMEXITS_MAINTENANCE]++;
-
+               cpu_data->stats[JAILHOUSE_CPU_STAT_VMEXITS_MAINTENANCE] +=
+                       count_event;
                irqchip_inject_pending(cpu_data);
+
                return true;
        }
 
-       cpu_data->stats[JAILHOUSE_CPU_STAT_VMEXITS_VIRQ]++;
-
+       cpu_data->stats[JAILHOUSE_CPU_STAT_VMEXITS_VIRQ] += count_event;
        irqchip_set_pending(cpu_data, irqn);
 
        return false;
diff --git a/hypervisor/arch/arm/gic-common.c b/hypervisor/arch/arm/gic-common.c
index c74f30a..fec878b 100644
--- a/hypervisor/arch/arm/gic-common.c
+++ b/hypervisor/arch/arm/gic-common.c
@@ -226,8 +226,6 @@ void gic_handle_sgir_write(struct sgi *sgi, bool virt_input)
        struct cell *cell = cpu_data->cell;
        bool is_target = false;
 
-       cpu_data->stats[JAILHOUSE_CPU_STAT_VMEXITS_VSGI]++;
-
        targets = sgi->targets;
        sgi->targets = 0;
 
@@ -316,6 +314,7 @@ enum mmio_result gic_handle_dist_access(void *arg, struct 
mmio_access *mmio)
 
 void gic_handle_irq(struct per_cpu *cpu_data)
 {
+       unsigned int count_event = 1;
        bool handled = false;
        u32 irq_id;
 
@@ -328,11 +327,13 @@ void gic_handle_irq(struct per_cpu *cpu_data)
 
                /* Handle IRQ */
                if (is_sgi(irq_id)) {
-                       arch_handle_sgi(cpu_data, irq_id);
+                       arch_handle_sgi(cpu_data, irq_id, count_event);
                        handled = true;
                } else {
-                       handled = arch_handle_phys_irq(cpu_data, irq_id);
+                       handled = arch_handle_phys_irq(cpu_data, irq_id,
+                                                      count_event);
                }
+               count_event = 0;
 
                /*
                 * Write EOIR1: drop priority, but stay active if handled is
diff --git a/hypervisor/arch/arm/include/asm/control.h 
b/hypervisor/arch/arm/include/asm/control.h
index d5d51a9..1e405d1 100644
--- a/hypervisor/arch/arm/include/asm/control.h
+++ b/hypervisor/arch/arm/include/asm/control.h
@@ -24,11 +24,13 @@
 
 extern struct paging_structures parking_mm;
 
-void arch_handle_sgi(struct per_cpu *cpu_data, u32 irqn);
+void arch_handle_sgi(struct per_cpu *cpu_data, u32 irqn,
+                    unsigned int count_event);
 void arch_handle_trap(struct per_cpu *cpu_data, struct registers *guest_regs);
 struct registers* arch_handle_exit(struct per_cpu *cpu_data,
                                   struct registers *regs);
-bool arch_handle_phys_irq(struct per_cpu *cpu_data, u32 irqn);
+bool arch_handle_phys_irq(struct per_cpu *cpu_data, u32 irqn,
+                         unsigned int count_event);
 
 void arch_shutdown_self(struct per_cpu *cpu_data);
 
diff --git a/hypervisor/arch/arm/include/asm/jailhouse_hypercall.h 
b/hypervisor/arch/arm/include/asm/jailhouse_hypercall.h
index 45e7a3d..ddc42d0 100644
--- a/hypervisor/arch/arm/include/asm/jailhouse_hypercall.h
+++ b/hypervisor/arch/arm/include/asm/jailhouse_hypercall.h
@@ -49,7 +49,9 @@
 #define JAILHOUSE_CPU_STAT_VMEXITS_MAINTENANCE JAILHOUSE_GENERIC_CPU_STATS
 #define JAILHOUSE_CPU_STAT_VMEXITS_VIRQ                
JAILHOUSE_GENERIC_CPU_STATS + 1
 #define JAILHOUSE_CPU_STAT_VMEXITS_VSGI                
JAILHOUSE_GENERIC_CPU_STATS + 2
-#define JAILHOUSE_NUM_CPU_STATS                        
JAILHOUSE_GENERIC_CPU_STATS + 3
+#define JAILHOUSE_CPU_STAT_VMEXITS_PSCI                
JAILHOUSE_GENERIC_CPU_STATS + 3
+#define JAILHOUSE_CPU_STAT_VMEXITS_CP15                
JAILHOUSE_GENERIC_CPU_STATS + 4
+#define JAILHOUSE_NUM_CPU_STATS                        
JAILHOUSE_GENERIC_CPU_STATS + 5
 
 #ifndef __ASSEMBLY__
 
diff --git a/hypervisor/arch/arm/psci.c b/hypervisor/arch/arm/psci.c
index 118729a..3117c5c 100644
--- a/hypervisor/arch/arm/psci.c
+++ b/hypervisor/arch/arm/psci.c
@@ -71,6 +71,8 @@ long psci_dispatch(struct trap_context *ctx)
        struct per_cpu *cpu_data = this_cpu_data();
        u32 function_id = ctx->regs[0];
 
+       this_cpu_data()->stats[JAILHOUSE_CPU_STAT_VMEXITS_PSCI]++;
+
        switch (function_id) {
        case PSCI_VERSION:
                /* Major[31:16], minor[15:0] */
diff --git a/hypervisor/arch/arm/traps.c b/hypervisor/arch/arm/traps.c
index d1dfc92..ab5b3a0 100644
--- a/hypervisor/arch/arm/traps.c
+++ b/hypervisor/arch/arm/traps.c
@@ -293,6 +293,8 @@ static int arch_handle_cp15_32(struct trap_context *ctx)
        match;                                                          \
 })
 
+       this_cpu_data()->stats[JAILHOUSE_CPU_STAT_VMEXITS_CP15]++;
+
        if (!read)
                access_cell_reg(ctx, rt, &val, true);
 
@@ -374,6 +376,8 @@ static int arch_handle_cp15_64(struct trap_context *ctx)
        match;                                          \
 })
 
+       this_cpu_data()->stats[JAILHOUSE_CPU_STAT_VMEXITS_CP15]++;
+
        /* all regs are write-only / only trapped on writes */
        if (read)
                return TRAP_UNHANDLED;
-- 
Siemens AG, Corporate Technology, CT RDA ITP SES-DE
Corporate Competence Center Embedded Linux

-- 
You received this message because you are subscribed to the Google Groups 
"Jailhouse" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to jailhouse-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to