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-devel

[Xen-devel] [PATCH][Retry 1] 3/4: cpufreq/PowerNow! in Xen: Linux time c

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH][Retry 1] 3/4: cpufreq/PowerNow! in Xen: Linux time changes
From: "Mark Langsdorf" <mark.langsdorf@xxxxxxx>
Date: Thu, 30 Aug 2007 12:01:20 -0500
Delivery-date: Thu, 30 Aug 2007 09:58:09 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: KMail/1.9.5
Enable cpufreq support in Xen for AMD Operton processors by:

1) Allowing the PowerNow! driver in dom0 to write to the PowerNow!
MSRs.
2) Adding the cpufreq notifier chain to time-xen.c in dom0.
On a frequency change, a platform hypercall is performed to
scale the frequency multiplier in the hypervisor.
3) Adding a platform hypercall to the hypervisor the scale
the frequency multiplier and reset the time stamps so that
next calibration remains reasonably correct.
4) Adding the cpufreq Xen option which pins the VCPUs to
the physical CPU cores.

Patch 1 covers the frequency scaling platform call in Xen.
Patch 2 allows MSR accesses from the PowerNow! driver.
Patch 3 covers the frequency scaling platform call in Linux.
Patch 4 covers the changes necessary to the PowerNow! driver
to make it correctly associate shared cores under Xen.

This code can be readily expanded to cover Intel or other
non-AMD processors by modifying xen/arch/x8/traps.c to
allow the appropriate MSR accesses.

Caveat: currently, this code does not support the in-kernel
ondemand cpufreq governor.  Dom0 must run a userspace 
daemon to monitor the utilization of the physical cpus
with the getcpuinfo sysctl hypercall.

Caveat 2: Even though the clock multipliers are being
scaled and recorded correctly in both dom0 and the
hypervisor, time errors appear immediately after a
frequency change.  They are not more likely when
the frequency is constant.


Signed-off-by: Mark Langsdorf <mark.langsdorf@xxxxxxx>
diff -r 05c22f282023 arch/i386/kernel/time-xen.c
--- a/arch/i386/kernel/time-xen.c       Tue Aug 14 16:20:55 2007 +0100
+++ b/arch/i386/kernel/time-xen.c       Thu Aug 30 12:21:35 2007 -0500
@@ -50,6 +50,7 @@
 #include <linux/percpu.h>
 #include <linux/kernel_stat.h>
 #include <linux/posix-timers.h>
+#include <linux/cpufreq.h>
 
 #include <asm/io.h>
 #include <asm/smp.h>
@@ -1118,6 +1119,65 @@ void local_teardown_timer(unsigned int c
        BUG_ON(cpu == 0);
        unbind_from_irqhandler(per_cpu(timer_irq, cpu), NULL);
 }
+#endif
+
+#if CONFIG_CPU_FREQ
+/* 
+ * cpufreq scaling handling
+ */
+static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, 
+                               void *data)
+{
+       struct cpufreq_freqs *freq = data;
+        struct vcpu_time_info *info = &vcpu_info(freq->cpu)->time;
+       struct xen_platform_op op;
+       cpumask_t oldmask;
+       unsigned int cpu;
+
+       if (cpu_has(&cpu_data[freq->cpu], X86_FEATURE_CONSTANT_TSC))
+               return 0;
+
+       if (val == CPUFREQ_PRECHANGE)
+               return 0;
+
+       /* change the frequency inside the hypervisor */
+       oldmask = current->cpus_allowed;
+       set_cpus_allowed(current, cpumask_of_cpu(freq->cpu));
+       schedule();
+       op.cmd = XENPF_change_freq;
+       op.u.change_freq.info = info;
+       op.u.change_freq.old = freq->old;
+       op.u.change_freq.new = freq->new;
+       op.u.change_freq.cpu_num = freq->cpu;
+       HYPERVISOR_platform_op(&op);
+
+       for_each_online_cpu(cpu) {
+               get_time_values_from_xen(cpu);
+               per_cpu(processed_system_time, cpu) =
+                        per_cpu(shadow_time, cpu).system_timestamp;
+       }
+
+       set_cpus_allowed(current, oldmask);
+       schedule();
+
+       return 0;
+}
+
+static struct notifier_block time_cpufreq_notifier_block = {
+       .notifier_call = time_cpufreq_notifier
+};
+
+static int __init cpufreq_time_setup(void)
+{
+       if (!cpufreq_register_notifier(&time_cpufreq_notifier_block,
+                       CPUFREQ_TRANSITION_NOTIFIER)) {
+               printk(KERN_ERR "failed to set up cpufreq notifier\n");
+               return -ENODEV;
+       }
+       return 0;
+}
+
+core_initcall(cpufreq_time_setup);
 #endif
 
 /*
diff -r 05c22f282023 include/xen/interface/platform.h
--- a/include/xen/interface/platform.h  Tue Aug 14 16:20:55 2007 +0100
+++ b/include/xen/interface/platform.h  Thu Aug 30 12:21:35 2007 -0500
@@ -153,6 +153,17 @@ typedef struct xenpf_firmware_info xenpf
 typedef struct xenpf_firmware_info xenpf_firmware_info_t;
 DEFINE_XEN_GUEST_HANDLE(xenpf_firmware_info_t);
 
+#define XENPF_change_freq       52
+struct xenpf_change_freq {
+    /* IN variables */
+    struct vcpu_time_info *info; /* vcpu time info for changing vcpu */
+    uint32_t old;  /* original frequency */
+    uint32_t new;  /* new frequency */
+    uint32_t cpu_num;
+};
+typedef struct xenpf_change_freq xenpf_change_freq_t;
+DEFINE_XEN_GUEST_HANDLE(xenpf_change_freq_t);
+
 #define XENPF_enter_acpi_sleep    51
 struct xenpf_enter_acpi_sleep {
     /* IN variables */
@@ -175,6 +186,7 @@ struct xen_platform_op {
         struct xenpf_microcode_update  microcode;
         struct xenpf_platform_quirk    platform_quirk;
         struct xenpf_firmware_info     firmware_info;
+        struct xenpf_change_freq       change_freq;
         struct xenpf_enter_acpi_sleep  enter_acpi_sleep;
         uint8_t                        pad[128];
     } u;



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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH][Retry 1] 3/4: cpufreq/PowerNow! in Xen: Linux time changes, Mark Langsdorf <=