powerpc/perf: Add per-task/process monitoring to vpa_pmu driver
authorKajol Jain <kjain@linux.ibm.com>
Mon, 18 Nov 2024 11:41:14 +0000 (17:11 +0530)
committerMichael Ellerman <mpe@ellerman.id.au>
Tue, 19 Nov 2024 03:11:30 +0000 (14:11 +1100)
Enhance the vpa_pmu driver with a feature to observe context switch
latency event for both per-task (tid) and per-pid (pid) option.
Couple of new helper functions are added to hide the abstraction of
reading the context switch latency counter from kvm_vcpu_arch struct
and these helper functions are defined in the "kvm/book3s_hv.c".

"PERF_ATTACH_TASK" flag is used to decide whether to read the counter
values from lppaca or kvm_vcpu_arch struct.

Signed-off-by: Kajol Jain <kjain@linux.ibm.com>
Co-developed-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://patch.msgid.link/20241118114114.208964-4-kjain@linux.ibm.com
arch/powerpc/include/asm/kvm_book3s_64.h
arch/powerpc/kvm/book3s_hv.c
arch/powerpc/perf/vpa-pmu.c

index f620e31..b936e17 100644 (file)
@@ -691,6 +691,9 @@ void kvmhv_set_l2_counters_status(int cpu, bool status);
 u64 kvmhv_get_l1_to_l2_cs_time(void);
 u64 kvmhv_get_l2_to_l1_cs_time(void);
 u64 kvmhv_get_l2_runtime_agg(void);
+u64 kvmhv_get_l1_to_l2_cs_time_vcpu(void);
+u64 kvmhv_get_l2_to_l1_cs_time_vcpu(void);
+u64 kvmhv_get_l2_runtime_agg_vcpu(void);
 
 #endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */
 
index 613231c..d8938fd 100644 (file)
@@ -4190,6 +4190,51 @@ u64 kvmhv_get_l2_runtime_agg(void)
 }
 EXPORT_SYMBOL(kvmhv_get_l2_runtime_agg);
 
+u64 kvmhv_get_l1_to_l2_cs_time_vcpu(void)
+{
+       struct kvm_vcpu *vcpu;
+       struct kvm_vcpu_arch *arch;
+
+       vcpu = local_paca->kvm_hstate.kvm_vcpu;
+       if (vcpu) {
+               arch = &vcpu->arch;
+               return arch->l1_to_l2_cs;
+       } else {
+               return 0;
+       }
+}
+EXPORT_SYMBOL(kvmhv_get_l1_to_l2_cs_time_vcpu);
+
+u64 kvmhv_get_l2_to_l1_cs_time_vcpu(void)
+{
+       struct kvm_vcpu *vcpu;
+       struct kvm_vcpu_arch *arch;
+
+       vcpu = local_paca->kvm_hstate.kvm_vcpu;
+       if (vcpu) {
+               arch = &vcpu->arch;
+               return arch->l2_to_l1_cs;
+       } else {
+               return 0;
+       }
+}
+EXPORT_SYMBOL(kvmhv_get_l2_to_l1_cs_time_vcpu);
+
+u64 kvmhv_get_l2_runtime_agg_vcpu(void)
+{
+       struct kvm_vcpu *vcpu;
+       struct kvm_vcpu_arch *arch;
+
+       vcpu = local_paca->kvm_hstate.kvm_vcpu;
+       if (vcpu) {
+               arch = &vcpu->arch;
+               return arch->l2_runtime_agg;
+       } else {
+               return 0;
+       }
+}
+EXPORT_SYMBOL(kvmhv_get_l2_runtime_agg_vcpu);
+
 #else
 int kvmhv_get_l2_counters_status(void)
 {
index c143c62..6a5bfd2 100644 (file)
@@ -97,13 +97,22 @@ static unsigned long get_counter_data(struct perf_event *event)
 
        switch (config) {
        case L1_TO_L2_CS_LAT:
-               data = kvmhv_get_l1_to_l2_cs_time();
+               if (event->attach_state & PERF_ATTACH_TASK)
+                       data = kvmhv_get_l1_to_l2_cs_time_vcpu();
+               else
+                       data = kvmhv_get_l1_to_l2_cs_time();
                break;
        case L2_TO_L1_CS_LAT:
-               data = kvmhv_get_l2_to_l1_cs_time();
+               if (event->attach_state & PERF_ATTACH_TASK)
+                       data = kvmhv_get_l2_to_l1_cs_time_vcpu();
+               else
+                       data = kvmhv_get_l2_to_l1_cs_time();
                break;
        case L2_RUNTIME_AGG:
-               data = kvmhv_get_l2_runtime_agg();
+               if (event->attach_state & PERF_ATTACH_TASK)
+                       data = kvmhv_get_l2_runtime_agg_vcpu();
+               else
+                       data = kvmhv_get_l2_runtime_agg();
                break;
        default:
                data = 0;