[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 9/9] x86/intel_pstate: enable xenpm to control the intel_pstate driver



The intel_pstate driver receives percentage values to set the
performance limits. This patch adds interfaces to support the
input of percentage values to control the intel_pstate driver.
Also, the "get-cpufreq-para" is modified to show percentage
based feedback info.

Signed-off-by: Wei Wang <wei.w.wang@xxxxxxxxx>
---
 tools/libxc/include/xenctrl.h |  20 +++++++--
 tools/libxc/xc_pm.c           |  26 ++++++-----
 tools/misc/xenpm.c            | 101 ++++++++++++++++++++++++++++++++----------
 3 files changed, 110 insertions(+), 37 deletions(-)

diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index 02d0db8..e390a77 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -2200,9 +2200,13 @@ typedef xen_ondemand_t xc_ondemand_t;
 struct xc_get_cpufreq_para {
     /* IN/OUT variable */
     uint32_t cpu_num;
-    uint32_t freq_num;
     uint32_t gov_num;
 
+    union {
+        uint32_t freq_num;
+        uint32_t pstates_num;
+    } num;
+
     /* for all governors */
     /* OUT variable */
     uint32_t *affected_cpus;
@@ -2216,8 +2220,18 @@ struct xc_get_cpufreq_para {
     uint32_t scaling_cur_freq;
 
     char scaling_governor[CPUFREQ_NAME_LEN];
-    uint32_t scaling_max_freq;
-    uint32_t scaling_min_freq;
+
+    union {
+        uint32_t max_freq;
+        int32_t  max_perf_pct;
+    } scaling_max;
+
+    union {
+        uint32_t min_freq;
+        int32_t  min_perf_pct;
+    } scaling_min;
+
+    int32_t scaling_turbo_pct;
 
     /* for specific governor */
     union {
diff --git a/tools/libxc/xc_pm.c b/tools/libxc/xc_pm.c
index d116c36..24e8779 100644
--- a/tools/libxc/xc_pm.c
+++ b/tools/libxc/xc_pm.c
@@ -207,13 +207,13 @@ int xc_get_cpufreq_para(xc_interface *xch, int cpuid,
                         user_para->cpu_num * sizeof(uint32_t), 
XC_HYPERCALL_BUFFER_BOUNCE_BOTH);
     DECLARE_NAMED_HYPERCALL_BOUNCE(scaling_available_frequencies,
                         user_para->scaling_available_frequencies,
-                        user_para->freq_num * sizeof(uint32_t), 
XC_HYPERCALL_BUFFER_BOUNCE_BOTH);
+                        user_para->num.freq_num * sizeof(uint32_t), 
XC_HYPERCALL_BUFFER_BOUNCE_BOTH);
     DECLARE_NAMED_HYPERCALL_BOUNCE(scaling_available_governors,
                         user_para->scaling_available_governors,
                         user_para->gov_num * CPUFREQ_NAME_LEN * sizeof(char), 
XC_HYPERCALL_BUFFER_BOUNCE_BOTH);
 
     bool has_num = user_para->cpu_num &&
-                     user_para->freq_num &&
+                     user_para->num.freq_num &&
                      user_para->gov_num;
 
     if ( has_num )
@@ -241,7 +241,7 @@ int xc_get_cpufreq_para(xc_interface *xch, int cpuid,
     sysctl.u.pm_op.cmd = GET_CPUFREQ_PARA;
     sysctl.u.pm_op.cpuid = cpuid;
     sys_para->cpu_num  = user_para->cpu_num;
-    sys_para->num.freq_num = user_para->freq_num;
+    sys_para->num.freq_num = user_para->num.freq_num;
     sys_para->gov_num  = user_para->gov_num;
 
     ret = xc_sysctl(xch, &sysctl);
@@ -250,7 +250,7 @@ int xc_get_cpufreq_para(xc_interface *xch, int cpuid,
         if ( errno == EAGAIN )
         {
             user_para->cpu_num  = sys_para->cpu_num;
-            user_para->freq_num = sys_para->num.freq_num;
+            user_para->num.freq_num = sys_para->num.freq_num;
             user_para->gov_num  = sys_para->gov_num;
             ret = -errno;
         }
@@ -261,13 +261,17 @@ int xc_get_cpufreq_para(xc_interface *xch, int cpuid,
     }
     else
     {
-        user_para->cpuinfo_cur_freq = sys_para->cpuinfo_cur_freq;
-        user_para->cpuinfo_max_freq = sys_para->cpuinfo_max_freq;
-        user_para->cpuinfo_min_freq = sys_para->cpuinfo_min_freq;
-        user_para->scaling_cur_freq = sys_para->scaling_cur_freq;
-        user_para->scaling_max_freq = sys_para->scaling_max.max_freq;
-        user_para->scaling_min_freq = sys_para->scaling_min.min_freq;
-        user_para->turbo_enabled    = sys_para->turbo_enabled;
+        user_para->cpuinfo_cur_freq             = sys_para->cpuinfo_cur_freq;
+        user_para->cpuinfo_max_freq             = sys_para->cpuinfo_max_freq;
+        user_para->cpuinfo_min_freq             = sys_para->cpuinfo_min_freq;
+        user_para->scaling_cur_freq             = sys_para->scaling_cur_freq;
+        user_para->scaling_max.max_freq         = 
sys_para->scaling_max.max_freq;
+        user_para->scaling_min.min_freq         = 
sys_para->scaling_min.min_freq;
+        user_para->scaling_max.max_perf_pct     = 
sys_para->scaling_max.max_perf_pct;
+        user_para->scaling_min.min_perf_pct     = 
sys_para->scaling_min.min_perf_pct;
+        user_para->num.pstates_num              = sys_para->num.pstates_num;
+        user_para->scaling_turbo_pct            = sys_para->scaling_turbo_pct;
+        user_para->turbo_enabled                = sys_para->turbo_enabled;
 
         memcpy(user_para->scaling_driver,
                 sys_para->scaling_driver, CPUFREQ_NAME_LEN);
diff --git a/tools/misc/xenpm.c b/tools/misc/xenpm.c
index a5d07de..58c1b16 100644
--- a/tools/misc/xenpm.c
+++ b/tools/misc/xenpm.c
@@ -47,6 +47,8 @@ void show_help(void)
             " get-cpuidle-states    [cpuid]       list cpu idle info of CPU 
<cpuid> or all\n"
             " get-cpufreq-states    [cpuid]       list cpu freq info of CPU 
<cpuid> or all\n"
             " get-cpufreq-para      [cpuid]       list cpu freq parameter of 
CPU <cpuid> or all\n"
+            " set-scaling-max-pct   [cpuid] <num> set max performance limit in 
percentage\n"
+            " set-scaling-min-pct   [cpuid] <num> set min performance limit in 
percentage\n"
             " set-scaling-maxfreq   [cpuid] <HZ>  set max cpu frequency <HZ> 
on CPU <cpuid>\n"
             "                                     or all CPUs\n"
             " set-scaling-minfreq   [cpuid] <HZ>  set min cpu frequency <HZ> 
on CPU <cpuid>\n"
@@ -60,10 +62,10 @@ void show_help(void)
             " set-up-threshold      [cpuid] <num> set up threshold on CPU 
<cpuid> or all\n"
             "                                     it is used in ondemand 
governor.\n"
             " get-cpu-topology                    get thread/core/socket 
topology info\n"
-            " set-sched-smt           enable|disable enable/disable scheduler 
smt power saving\n"
+            " set-sched-smt                       enable|disable 
enable/disable scheduler smt power saving\n"
             " set-vcpu-migration-delay      <num> set scheduler vcpu migration 
delay in us\n"
             " get-vcpu-migration-delay            get scheduler vcpu migration 
delay\n"
-            " set-max-cstate        <num>         set the C-State limitation 
(<num> >= 0)\n"
+            " set-max-cstate                <num> set the C-State limitation 
(<num> >= 0)\n"
             " start [seconds]                     start collect Cx/Px 
statistics,\n"
             "                                     output after CTRL-C or 
SIGINT or several seconds.\n"
             " enable-turbo-mode     [cpuid]       enable Turbo Mode for 
processors that support it.\n"
@@ -685,36 +687,42 @@ static void print_cpufreq_para(int cpuid, struct 
xc_get_cpufreq_para *p_cpufreq)
     if ( !strncmp(p_cpufreq->scaling_governor,
                   "userspace", CPUFREQ_NAME_LEN) )
     {
-        printf("  userspace specific :\n");
-        printf("    scaling_setspeed : %u\n",
+        printf("userspace specific   :\n");
+        printf("scaling_setspeed     : %u\n",
                p_cpufreq->u.userspace.scaling_setspeed);
     }
     else if ( !strncmp(p_cpufreq->scaling_governor,
                        "ondemand", CPUFREQ_NAME_LEN) )
     {
-        printf("  ondemand specific  :\n");
-        printf("    sampling_rate    : max [%u] min [%u] cur [%u]\n",
+        printf("ondemand specific    :\n");
+        printf("sampling_rate        : max [%u] min [%u] cur [%u]\n",
                p_cpufreq->u.ondemand.sampling_rate_max,
                p_cpufreq->u.ondemand.sampling_rate_min,
                p_cpufreq->u.ondemand.sampling_rate);
-        printf("    up_threshold     : %u\n",
+        printf("up_threshold         : %u\n",
                p_cpufreq->u.ondemand.up_threshold);
     }
 
-    printf("scaling_avail_freq   :");
-    for ( i = 0; i < p_cpufreq->freq_num; i++ )
-        if ( p_cpufreq->scaling_available_frequencies[i] ==
-             p_cpufreq->scaling_cur_freq )
-            printf(" *%d", p_cpufreq->scaling_available_frequencies[i]);
-        else
-            printf(" %d", p_cpufreq->scaling_available_frequencies[i]);
-    printf("\n");
-
-    printf("scaling frequency    : max [%u] min [%u] cur [%u]\n",
-           p_cpufreq->scaling_max_freq,
-           p_cpufreq->scaling_min_freq,
-           p_cpufreq->scaling_cur_freq);
-
+    if (!strncmp(p_cpufreq->scaling_driver,
+                  "intel_pstate", CPUFREQ_NAME_LEN) ) {
+        printf("num_pstates          : %d\n", p_cpufreq->num.pstates_num);
+        printf("max_perf_pct         : %d\n", 
p_cpufreq->scaling_max.max_perf_pct);
+        printf("min_perf_pct         : %d\n", 
p_cpufreq->scaling_min.min_perf_pct);
+        printf("turbo_pct            : %d\n", p_cpufreq->scaling_turbo_pct);
+    } else {
+        printf("scaling_avail_freq       :");
+        for ( i = 0; i < p_cpufreq->num.freq_num; i++ )
+            if ( p_cpufreq->scaling_available_frequencies[i] ==
+                 p_cpufreq->scaling_cur_freq )
+                printf(" *%d", p_cpufreq->scaling_available_frequencies[i]);
+            else
+                printf(" %d", p_cpufreq->scaling_available_frequencies[i]);
+        printf("\n");
+        printf("scaling frequency    : max [%u] min [%u] cur [%u]\n",
+               p_cpufreq->scaling_max.max_freq,
+               p_cpufreq->scaling_min.min_freq,
+               p_cpufreq->scaling_cur_freq);
+   }
     printf("turbo mode           : %s\n",
            p_cpufreq->turbo_enabled ? "enabled" : "disabled or n/a");
     printf("\n");
@@ -727,7 +735,8 @@ static int show_cpufreq_para_by_cpuid(xc_interface 
*xc_handle, int cpuid)
     struct xc_get_cpufreq_para cpufreq_para, *p_cpufreq = &cpufreq_para;
 
     p_cpufreq->cpu_num = 0;
-    p_cpufreq->freq_num = 0;
+    p_cpufreq->num.freq_num = 0;
+    p_cpufreq->num.pstates_num = 0;
     p_cpufreq->gov_num = 0;
     p_cpufreq->affected_cpus = NULL;
     p_cpufreq->scaling_available_frequencies = NULL;
@@ -754,7 +763,7 @@ static int show_cpufreq_para_by_cpuid(xc_interface 
*xc_handle, int cpuid)
             goto out;
         }
         if (!(p_cpufreq->scaling_available_frequencies =
-              malloc(p_cpufreq->freq_num * sizeof(uint32_t))))
+              malloc(p_cpufreq->num.freq_num * sizeof(uint32_t))))
         {
             fprintf(stderr,
                     "[CPU%d] failed to malloc for 
scaling_available_frequencies\n",
@@ -860,6 +869,50 @@ void scaling_min_freq_func(int argc, char *argv[])
     }
 }
 
+void scaling_max_pct_func(int argc, char *argv[]) {
+    int cpuid = -1, pct = -1;
+
+    parse_cpuid_and_int(argc, argv, &cpuid, &pct, "percentage");
+
+    if ( cpuid < 0 )
+    {
+        int i;
+        for ( i = 0; i < max_cpu_nr; i++ )
+            if ( xc_set_cpufreq_para(xc_handle, i, SCALING_MAX_PCT, pct) )
+                fprintf(stderr,
+                        "[CPU%d] failed to set scaling max freq (%d - %s)\n",
+                        i, errno, strerror(errno));
+    }
+    else
+    {
+        if ( xc_set_cpufreq_para(xc_handle, cpuid, SCALING_MAX_PCT, pct) )
+            fprintf(stderr, "failed to set scaling max freq (%d - %s)\n",
+                    errno, strerror(errno));
+    }
+}
+
+void scaling_min_pct_func(int argc, char *argv[]) {
+    int cpuid = -1, pct = -1;
+
+    parse_cpuid_and_int(argc, argv, &cpuid, &pct, "percentage");
+
+    if ( cpuid < 0 )
+    {
+        int i;
+        for ( i = 0; i < max_cpu_nr; i++ )
+            if ( xc_set_cpufreq_para(xc_handle, i, SCALING_MIN_PCT, pct) )
+                fprintf(stderr,
+                        "[CPU%d] failed to set scaling max pct (%d - %s)\n",
+                        i, errno, strerror(errno));
+    }
+    else
+    {
+        if ( xc_set_cpufreq_para(xc_handle, cpuid, SCALING_MIN_PCT, pct) )
+            fprintf(stderr, "failed to set scaling min pct (%d - %s)\n",
+                    errno, strerror(errno));
+    }
+}
+
 void scaling_speed_func(int argc, char *argv[])
 {
     int cpuid = -1, speed = -1;
@@ -1141,6 +1194,8 @@ struct {
     { "get-cpufreq-para", cpufreq_para_func },
     { "set-scaling-maxfreq", scaling_max_freq_func },
     { "set-scaling-minfreq", scaling_min_freq_func },
+    { "set-scaling-max-pct", scaling_max_pct_func},
+    { "set-scaling-min-pct", scaling_min_pct_func},
     { "set-scaling-governor", scaling_governor_func },
     { "set-scaling-speed", scaling_speed_func },
     { "set-sampling-rate", scaling_sampling_rate_func },
-- 
1.9.1


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.