WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-ppc-devel

[XenPPC] [ppc/xen-unstable.hg] [POWERPC][XEN] Enable in-guest performanc

Changeset 3867217d3155 : 
http://xenbits.xensource.com/ext/ppc/xen-unstable.hg?cmd=changeset;node=3867217d3155

        [POWERPC][XEN] Enable in-guest performance monitoring.
        - Lazily save and restore the performance monitor counters when 
switching
          domains.
        - Control with the H_PERFMON PAPR hypercall.
        - Ignore guest perfmon exceptions that land in Xen.
        Signed-off-by: Christian Ehrhardt <ehrhardt@xxxxxxxxxxxxxxxxxx>
        Signed-off-by: Hollis Blanchard <hollisb@xxxxxxxxxx>

diffstat:

11 files changed, 490 insertions(+), 8 deletions(-)
xen/arch/powerpc/exceptions.h           |    3 
xen/arch/powerpc/of_handler/papr.S      |    2 
xen/arch/powerpc/papr/Makefile          |    1 
xen/arch/powerpc/papr/h_perfmon.c       |  158 +++++++++++++++++++++++++++++++
xen/arch/powerpc/powerpc64/domain.c     |   46 ++++++++-
xen/arch/powerpc/powerpc64/exceptions.S |   25 ++++
xen/include/asm-powerpc/domain.h        |   21 +++-
xen/include/asm-powerpc/papr.h          |    1 
xen/include/asm-powerpc/processor.h     |  138 ++++++++++++++++++++++++++-
xen/include/asm-powerpc/reg_defs.h      |   27 +++++
xen/include/asm-powerpc/xenoprof.h      |   76 ++++++++++++++

diffs (truncated from 697 to 300 lines):

diff -r a69843c46641 -r 3867217d3155 xen/arch/powerpc/exceptions.h
--- a/xen/arch/powerpc/exceptions.h     Fri Jul 13 15:23:24 2007 -0500
+++ b/xen/arch/powerpc/exceptions.h     Fri Jul 13 17:28:15 2007 -0500
@@ -13,7 +13,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  *
- * Copyright (C) IBM Corp. 2005
+ * Copyright IBM Corp. 2005, 2007
  *
  * Authors: Hollis Blanchard <hollisb@xxxxxxxxxx>
  */
@@ -39,6 +39,7 @@ extern  multiboot_info_t *boot_of_init(u
 
 extern void do_timer(struct cpu_user_regs *regs);
 extern void do_dec(struct cpu_user_regs *regs);
+extern void do_perfmon(struct cpu_user_regs *regs);
 extern void program_exception(
     struct cpu_user_regs *regs, unsigned long cookie);
 
diff -r a69843c46641 -r 3867217d3155 xen/arch/powerpc/of_handler/papr.S
--- a/xen/arch/powerpc/of_handler/papr.S        Fri Jul 13 15:23:24 2007 -0500
+++ b/xen/arch/powerpc/of_handler/papr.S        Fri Jul 13 17:28:15 2007 -0500
@@ -67,7 +67,7 @@ PAPR(5, 1,papr_pci_config_read, H_PCI_CO
 PAPR(5, 1,papr_pci_config_read, H_PCI_CONFIG_READ)
 PAPR(5, 0,papr_pci_config_write, H_PCI_CONFIG_WRITE)
 
-       PAPR(5, 1,papr_grant_logical, H_GRANT_LOGICAL)
+PAPR(5, 1,papr_grant_logical, H_GRANT_LOGICAL)
 PAPR(1, 1,papr_accept_logical, H_ACCEPT_LOGICAL)
 PAPR(0, 2,papr_rescind_logical, H_RESCIND_LOGICAL)
 PAPR(3, 0,papr_register_vterm, H_REGISTER_VTERM)
diff -r a69843c46641 -r 3867217d3155 xen/arch/powerpc/papr/Makefile
--- a/xen/arch/powerpc/papr/Makefile    Fri Jul 13 15:23:24 2007 -0500
+++ b/xen/arch/powerpc/papr/Makefile    Fri Jul 13 17:28:15 2007 -0500
@@ -8,3 +8,4 @@ obj-y += vtce.o
 obj-y += vtce.o
 obj-$(papr_vterm) += vterm.o
 obj-y += xlate.o
+obj-y += h_perfmon.o
diff -r a69843c46641 -r 3867217d3155 xen/arch/powerpc/papr/h_perfmon.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/powerpc/papr/h_perfmon.c Fri Jul 13 17:28:15 2007 -0500
@@ -0,0 +1,158 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Copyright IBM Corp. 2007
+ *
+ * Authors: Christian Ehrhardt <ehrhardt@xxxxxxxxxxxxxxxxxx>
+ */
+#undef DEBUG
+
+#include <xen/config.h>
+#include <xen/types.h>
+#include <xen/sched.h>
+#include <xen/init.h>
+#include <xen/domain.h>
+#include <public/xen.h>
+#include <asm/current.h>
+#include <asm/msr.h>
+#include <asm/papr.h>
+#include <asm/hcalls.h>
+#include <asm/xenoprof.h>
+
+#define H_PERFMON_ENABLE (1UL << 63)
+#define H_PERFMON_THRESHOLDGRANULARITY (1UL << 62)
+
+#ifdef DEBUG
+#define DBG(fmt...) printk(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+/* FIXME workaround - these are just the default values, need the values set to
+ * linux via sysfs up-to-date. */
+int pmc_reset_val[NUM_PMCS] = { (0x8000000-0x0),
+                                (0x8000000-0x100000),
+                                (0x8000000-0x0),
+                                (0x8000000-0x0),
+                                (0x8000000-0x0),
+                                (0x8000000-0x0),
+                                (0x8000000-0x0),
+                                (0x8000000-0x0)};
+int perf_count_active_vcpu;
+perf_sprs_t perf_clear_sprs;
+static DEFINE_SPINLOCK(perf_pmu_lock);
+
+static inline int has_pmu(void) { return 1; }
+
+void do_perfmon(struct cpu_user_regs *regs)
+{
+    ulong mmcra = mfmmcra();
+    ulong mmcr0 = mfmmcr0();
+    int pmc,i;
+    
+    if ((mmcra & MMCRA_SAMPHV) && !(mmcra & MMCRA_SAMPPR)) {
+        /* TODO Hypervisor sample - support to sample xen, 
+         * pass the sample to the primary sampling domain via an event channel.
+         */
+        printk("do_perfmon - called with sample of xen space\n");
+        print_perf_status();
+        BUG();
+    } 
+
+    /* Dom sample postponed into xen space
+     * Currently just ignored (decreases accuracy) 
+     * TODO pass the Dom samples to the appropriate domain via an event channel
+     * TODO get access to the real pmc_reset_val currently used by the domain
+     * to reset counter safe and valid
+     */
+
+    for (i = 0; i < NUM_PMCS; ++i) {
+        pmc = ctr_read(i);
+        if (pmc < 0) {
+            DBG("postponed perfmon exception - PMC%d < 0 - reset to default "
+                "'0x%0x'\n", i, pmc_reset_val[i]);
+            ctr_write(i,pmc_reset_val[i]);
+        }
+    }
+
+    mmcr0 |= MMCR0_PMAE;
+    mmcr0 &= ~MMCR0_FC;
+    mtmmcr0(mmcr0);
+}
+
+static void h_perfmon(struct cpu_user_regs *regs)
+{
+    ulong mode_set   = regs->gprs[4];
+    ulong mode_reset = regs->gprs[5];
+    struct vcpu *v = get_current();
+    struct domain *d = v->domain;
+
+    if (!has_pmu()) {
+        regs->gprs[3] = H_Function;
+        return;
+    }
+
+    /* only bits 0&1 are supported by H_PERFMON */
+    if (((mode_set | mode_reset) & ~(H_PERFMON_ENABLE |
+            H_PERFMON_THRESHOLDGRANULARITY)) != 0) {
+        regs->gprs[3] = H_Parameter;
+        return;
+    }
+    /* enable or disable it, not both */
+    if ((mode_set & mode_reset) != 0) {
+        regs->gprs[3] = H_Resource;
+        return;
+    }
+
+    spin_lock(&perf_pmu_lock);
+    if (mode_set & H_PERFMON_ENABLE) {
+        if (v->arch.pmu_enabled) {
+            DBG("H_PERFMON call on already enabled PMU for domain '%d' on "
+                "vcpu '%d'\n", d->domain_id, v->vcpu_id);
+            goto success;
+        }
+
+        if (!perf_count_active_vcpu) {
+           save_pmc_sprs(&perf_clear_sprs);
+#ifdef DEBUG
+           DBG("H_PERFMON Saved initial clear performance special purpose "
+               "registers\n");
+           print_perf_status();
+#endif
+        }
+        v->arch.pmu_enabled = 1;
+        perf_count_active_vcpu++;
+        printk("H_PERFMON call enabled PMU for domain '%d' on vcpu '%d'\n",
+                d->domain_id, v->vcpu_id);
+    } else if (mode_reset & H_PERFMON_ENABLE) {
+        if (!v->arch.pmu_enabled) {
+            DBG("H_PERFMON call on already disabled PMU for domain '%d' on "
+                "vcpu '%d'\n", d->domain_id, v->vcpu_id);
+            goto success;
+        }
+        v->arch.pmu_enabled = 0;
+        perf_count_active_vcpu--;
+        printk("H_PERFMON call disabled PMU for domain '%d' on vcpu '%d'\n",
+                d->domain_id, v->vcpu_id);
+    } else {
+        regs->gprs[3] = H_Parameter;
+    }
+
+success:
+    regs->gprs[3] = H_Success;
+    spin_unlock(&perf_pmu_lock);
+}
+
+__init_papr_hcall(H_PERFMON, h_perfmon);
diff -r a69843c46641 -r 3867217d3155 xen/arch/powerpc/powerpc64/domain.c
--- a/xen/arch/powerpc/powerpc64/domain.c       Fri Jul 13 15:23:24 2007 -0500
+++ b/xen/arch/powerpc/powerpc64/domain.c       Fri Jul 13 17:28:15 2007 -0500
@@ -13,16 +13,48 @@
  * along with this program; if not, write to the Free Software
  * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  *
- * Copyright (C) IBM Corp. 2005
+ * Copyright IBM Corp. 2005, 2007
  *
  * Authors: Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
+ *          Christian Ehrhardt <ehrhardt@xxxxxxxxxxxxxxxxxx>
  */
 
 #include <xen/config.h>
 #include <xen/lib.h>
 #include <xen/sched.h>
 #include <xen/mm.h>
+#include <xen/domain.h>
 #include <asm/current.h>
+
+void save_pmc_sprs(perf_sprs_t *p_sprs)
+{
+    p_sprs->mmcr0 = mfmmcr0();
+    p_sprs->mmcr1 = mfmmcr1();
+    p_sprs->mmcra = mfmmcra();
+    p_sprs->pmc[0] = mfpmc1();
+    p_sprs->pmc[1] = mfpmc2();
+    p_sprs->pmc[2] = mfpmc3();
+    p_sprs->pmc[3] = mfpmc4();
+    p_sprs->pmc[4] = mfpmc5();
+    p_sprs->pmc[5] = mfpmc6();
+    p_sprs->pmc[6] = mfpmc7();
+    p_sprs->pmc[7] = mfpmc8();
+}
+
+void load_pmc_sprs(perf_sprs_t *p_sprs)
+{
+    mtpmc1(p_sprs->pmc[0]);
+    mtpmc2(p_sprs->pmc[1]);
+    mtpmc3(p_sprs->pmc[2]);
+    mtpmc4(p_sprs->pmc[3]);
+    mtpmc5(p_sprs->pmc[4]);
+    mtpmc6(p_sprs->pmc[5]);
+    mtpmc7(p_sprs->pmc[6]);
+    mtpmc8(p_sprs->pmc[7]);
+    mtmmcra(p_sprs->mmcra);
+    mtmmcr1(p_sprs->mmcr1);
+    mtmmcr0(p_sprs->mmcr0);
+}
 
 void save_sprs(struct vcpu *v)
 {
@@ -35,6 +67,11 @@ void save_sprs(struct vcpu *v)
 
     v->arch.dar = mfdar();
     v->arch.dsisr = mfdsisr();
+
+    if (v->arch.pmu_enabled) {
+        save_pmc_sprs(&(v->arch.perf_sprs));
+        v->arch.perf_sprs_stored = 1;
+    }
 
     save_cpu_sprs(v);
 }
@@ -49,6 +86,13 @@ void load_sprs(struct vcpu *v)
     mtsprg3(v->arch.sprg[3]);
     mtdar(v->arch.dar);
     mtdsisr(v->arch.dsisr);
+
+    if (v->arch.pmu_enabled) {
+        if (v->arch.perf_sprs_stored)
+            load_pmc_sprs(&(v->arch.perf_sprs));
+        else
+            load_pmc_sprs(&perf_clear_sprs);
+    }
 
     load_cpu_sprs(v);
 
diff -r a69843c46641 -r 3867217d3155 xen/arch/powerpc/powerpc64/exceptions.S
--- a/xen/arch/powerpc/powerpc64/exceptions.S   Fri Jul 13 15:23:24 2007 -0500
+++ b/xen/arch/powerpc/powerpc64/exceptions.S   Fri Jul 13 17:28:15 2007 -0500
@@ -105,6 +105,12 @@ 1:
     nop
 .endm
 
+.macro PMU_SAVE_STATE scratch
+    mfspr \scratch,SPRN_MMCR0             /* ensure MMCR0[FCH] is 1 */
+    ori \scratch,\scratch,MMCR0_FCH
+    mtspr SPRN_MMCR0, \scratch
+.endm
+
 .macro EXCEPTION_HEAD parea continue
     /* make room for cpu_user_regs */
     subi r1, r1, STACK_VOLATILE_AREA + UREGS_sizeof
@@ -156,7 +162,7 @@ 1:
     ori r0, r0, MSR_RI@l
     mtmsrd r0

_______________________________________________
Xen-ppc-devel mailing list
Xen-ppc-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ppc-devel

<Prev in Thread] Current Thread [Next in Thread>
  • [XenPPC] [ppc/xen-unstable.hg] [POWERPC][XEN] Enable in-guest performance..., patchbot <=