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

[Xen-changelog] [xen-unstable] xenpm: Add CPU topology info (thread/core/socket)



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1236938965 0
# Node ID 0e1449d6f2315f375bce09341a6476146e151018
# Parent  4fd39881f9f185b49cd1e007b550b9ccab10d139
xenpm: Add CPU topology info (thread/core/socket)

CPU topology info is necessary for power management analysis. For
example, to analysis the effect of Px state coordination, Cx
package/core coordination,  the thread/core/socket topology
information is needed.

This patch add new command "get-cpu-topology" in xenpm to print the
CPU topology info:

Signed-off-by: Yu Ke <ke.yu@xxxxxxxxx>
---
 tools/libxc/xc_pm.c                            |   21 +++++++++
 tools/libxc/xenctrl.h                          |   17 +++++++
 tools/misc/xenpm.c                             |   36 ++++++++++++++++
 xen/common/sysctl.c                            |   11 ++---
 xen/drivers/acpi/pmstat.c                      |   54 ++++++++++++++++++++++++-
 xen/include/asm-ia64/linux-xen/asm/processor.h |    8 +++
 xen/include/asm-x86/processor.h                |    3 +
 xen/include/public/sysctl.h                    |   22 ++++++++++
 8 files changed, 164 insertions(+), 8 deletions(-)

diff -r 4fd39881f9f1 -r 0e1449d6f231 tools/libxc/xc_pm.c
--- a/tools/libxc/xc_pm.c       Fri Mar 13 07:45:11 2009 +0000
+++ b/tools/libxc/xc_pm.c       Fri Mar 13 10:09:25 2009 +0000
@@ -306,3 +306,24 @@ int xc_set_cpufreq_para(int xc_handle, i
 
     return xc_sysctl(xc_handle, &sysctl);
 }
+
+int xc_get_cputopo(int xc_handle, struct xc_get_cputopo *info)
+{
+    int rc;
+    DECLARE_SYSCTL;
+
+    sysctl.cmd = XEN_SYSCTL_pm_op;
+    sysctl.u.pm_op.cmd = XEN_SYSCTL_pm_op_get_cputopo;
+    sysctl.u.pm_op.cpuid = 0;
+    set_xen_guest_handle( sysctl.u.pm_op.get_topo.cpu_to_core,
+                         info->cpu_to_core );
+    set_xen_guest_handle( sysctl.u.pm_op.get_topo.cpu_to_socket,
+                         info->cpu_to_socket );
+    sysctl.u.pm_op.get_topo.max_cpus = info->max_cpus;
+
+    rc = do_sysctl(xc_handle, &sysctl);
+    info->nr_cpus = sysctl.u.pm_op.get_topo.nr_cpus;
+
+    return rc;
+}
+
diff -r 4fd39881f9f1 -r 0e1449d6f231 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h     Fri Mar 13 07:45:11 2009 +0000
+++ b/tools/libxc/xenctrl.h     Fri Mar 13 10:09:25 2009 +0000
@@ -1242,4 +1242,21 @@ int xc_set_cpufreq_gov(int xc_handle, in
 int xc_set_cpufreq_gov(int xc_handle, int cpuid, char *govname);
 int xc_set_cpufreq_para(int xc_handle, int cpuid,
                         int ctrl_type, int ctrl_value);
+
+struct xc_get_cputopo {
+     /* IN: maximum addressable entry in
+      * the caller-provided cpu_to_core/socket.
+      */
+    uint32_t max_cpus;
+    uint32_t *cpu_to_core;
+    uint32_t *cpu_to_socket;
+
+    /* OUT: number of cpus returned
+     * If OUT is greater than IN then the cpu_to_core/socket is truncated!
+     */
+    uint32_t nr_cpus;
+};
+
+int xc_get_cputopo(int xc_handle, struct xc_get_cputopo *info);
+
 #endif /* XENCTRL_H */
diff -r 4fd39881f9f1 -r 0e1449d6f231 tools/misc/xenpm.c
--- a/tools/misc/xenpm.c        Fri Mar 13 07:45:11 2009 +0000
+++ b/tools/misc/xenpm.c        Fri Mar 13 10:09:25 2009 +0000
@@ -58,6 +58,7 @@ void show_help(void)
             "                                     it is used in ondemand 
governor.\n"
             " 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"
             " start                               start collect Cx/Px 
statistics,\n"
             "                                     output after CTRL-C or 
SIGINT.\n"
             );
@@ -750,6 +751,40 @@ out:
     fprintf(stderr, "failed to set governor name\n");
 }
 
+#define MAX_NR_CPU 512
+
+void cpu_topology_func(int argc, char *argv[])
+{
+    uint32_t cpu_to_core[MAX_NR_CPU];
+    uint32_t cpu_to_socket[MAX_NR_CPU];
+    struct xc_get_cputopo info;
+    int i, ret;
+
+    info.cpu_to_core = cpu_to_core;
+    info.cpu_to_socket = cpu_to_socket;
+    info.max_cpus = MAX_NR_CPU;
+    ret = xc_get_cputopo(xc_fd, &info);
+    if (!ret)
+    {
+        printf("CPU\tcore\tsocket\n");
+        for (i=0; i<info.nr_cpus; i++)
+        {
+            if ( info.cpu_to_core[i] != INVALID_TOPOLOGY_ID &&
+                    info.cpu_to_socket[i] != INVALID_TOPOLOGY_ID )
+            {
+            printf("CPU%d\t %d\t %d\n", i, info.cpu_to_core[i],
+                    info.cpu_to_socket[i]);
+            }
+        }
+    }
+    else
+    {
+        printf("Can not get Xen CPU topology!\n");
+    }
+
+    return ;
+}
+
 struct {
     const char *name;
     void (*function)(int argc, char *argv[]);
@@ -765,6 +800,7 @@ struct {
     { "set-scaling-speed", scaling_speed_func },
     { "set-sampling-rate", scaling_sampling_rate_func },
     { "set-up-threshold", scaling_up_threshold_func },
+    { "get-cpu-topology", cpu_topology_func},
 };
 
 int main(int argc, char *argv[])
diff -r 4fd39881f9f1 -r 0e1449d6f231 xen/common/sysctl.c
--- a/xen/common/sysctl.c       Fri Mar 13 07:45:11 2009 +0000
+++ b/xen/common/sysctl.c       Fri Mar 13 10:09:25 2009 +0000
@@ -224,12 +224,11 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysc
         if ( ret && (ret != -EAGAIN) )
             break;
 
-        if ( op->u.pm_op.cmd == GET_CPUFREQ_PARA )
-            if ( copy_to_guest(u_sysctl, op, 1) )
-            {
-                ret = -EFAULT;
-                break;
-            }
+        if ( copy_to_guest(u_sysctl, op, 1) )
+        {
+            ret = -EFAULT;
+            break;
+        }
     }
     break;
 
diff -r 4fd39881f9f1 -r 0e1449d6f231 xen/drivers/acpi/pmstat.c
--- a/xen/drivers/acpi/pmstat.c Fri Mar 13 07:45:11 2009 +0000
+++ b/xen/drivers/acpi/pmstat.c Fri Mar 13 10:09:25 2009 +0000
@@ -416,6 +416,52 @@ static int set_cpufreq_para(struct xen_s
     return ret;
 }
 
+static int get_cputopo (struct xen_sysctl_pm_op *op)
+{
+    uint32_t i, nr_cpus;
+    XEN_GUEST_HANDLE_64(uint32) cpu_to_core_arr;
+    XEN_GUEST_HANDLE_64(uint32) cpu_to_socket_arr;
+    int arr_size, ret=0;
+
+    cpu_to_core_arr = op->get_topo.cpu_to_core;
+    cpu_to_socket_arr = op->get_topo.cpu_to_socket;
+    arr_size= min_t(uint32_t, op->get_topo.max_cpus, NR_CPUS);
+
+    if ( guest_handle_is_null( cpu_to_core_arr ) ||
+            guest_handle_is_null(  cpu_to_socket_arr) )
+    {
+        ret = -EINVAL;
+        goto out;
+    }
+
+    nr_cpus = 0;
+    for ( i = 0; i < arr_size; i++ )
+    {
+        uint32_t core, socket;
+        if ( cpu_online(i) )
+        {
+            core = cpu_to_core(i);
+            socket = cpu_to_socket(i);
+            nr_cpus = i;
+        }
+        else
+        {
+            core = socket = INVALID_TOPOLOGY_ID;
+        }
+
+        if ( copy_to_guest_offset(cpu_to_core_arr, i, &core, 1) ||
+                copy_to_guest_offset(cpu_to_socket_arr, i, &socket, 1))
+        {
+            ret = -EFAULT;
+            goto out;
+        }
+    }
+
+    op->get_topo.nr_cpus = nr_cpus + 1;
+out:
+    return ret;
+}
+
 int do_pm_op(struct xen_sysctl_pm_op *op)
 {
     int ret = 0;
@@ -433,8 +479,6 @@ int do_pm_op(struct xen_sysctl_pm_op *op
         if ( !pmpt || !(pmpt->perf.init & XEN_PX_INIT) )
             return -EINVAL;
         break;
-    default:
-        return -ENODEV;
     }
 
     switch ( op->cmd )
@@ -454,6 +498,12 @@ int do_pm_op(struct xen_sysctl_pm_op *op
     case SET_CPUFREQ_PARA:
     {
         ret = set_cpufreq_para(op);
+        break;
+    }
+
+    case XEN_SYSCTL_pm_op_get_cputopo:
+    {
+        ret = get_cputopo(op);
         break;
     }
 
diff -r 4fd39881f9f1 -r 0e1449d6f231 
xen/include/asm-ia64/linux-xen/asm/processor.h
--- a/xen/include/asm-ia64/linux-xen/asm/processor.h    Fri Mar 13 07:45:11 
2009 +0000
+++ b/xen/include/asm-ia64/linux-xen/asm/processor.h    Fri Mar 13 10:09:25 
2009 +0000
@@ -198,6 +198,14 @@ DECLARE_PER_CPU(struct cpuinfo_ia64, cpu
 #define local_cpu_data         (&__ia64_per_cpu_var(cpu_info))
 #define cpu_data(cpu)          (&per_cpu(cpu_info, cpu))
 
+#ifdef CONFIG_SMP
+#define cpu_to_core(cpu)    (cpu_data(cpu)->core_id)
+#define cpu_to_socket(cpu)  (cpu_data(cpu)->socket_id)
+#else
+#define cpu_to_core(cpu)    0
+#define cpu_to_socket(cpu)  0
+#endif
+
 extern void identify_cpu (struct cpuinfo_ia64 *);
 extern void print_cpu_info (struct cpuinfo_ia64 *);
 
diff -r 4fd39881f9f1 -r 0e1449d6f231 xen/include/asm-x86/processor.h
--- a/xen/include/asm-x86/processor.h   Fri Mar 13 07:45:11 2009 +0000
+++ b/xen/include/asm-x86/processor.h   Fri Mar 13 10:09:25 2009 +0000
@@ -203,6 +203,9 @@ extern void detect_ht(struct cpuinfo_x86
 #else
 static always_inline void detect_ht(struct cpuinfo_x86 *c) {}
 #endif
+
+#define cpu_to_core(_cpu)   (cpu_core_id[_cpu])
+#define cpu_to_socket(_cpu) (phys_proc_id[_cpu])
 
 /*
  * Generic CPUID function
diff -r 4fd39881f9f1 -r 0e1449d6f231 xen/include/public/sysctl.h
--- a/xen/include/public/sysctl.h       Fri Mar 13 07:45:11 2009 +0000
+++ b/xen/include/public/sysctl.h       Fri Mar 13 10:09:25 2009 +0000
@@ -339,6 +339,24 @@ struct xen_set_cpufreq_para {
 
     uint32_t ctrl_type;
     uint32_t ctrl_value;
+}
+;
+/* Get physical CPU topology information. */
+
+
+#define INVALID_TOPOLOGY_ID  (~0U)
+struct xen_get_cputopo {
+     /* IN: maximum addressable entry in
+      * the caller-provided cpu_to_core/socket.
+      */
+    uint32_t max_cpus;
+    XEN_GUEST_HANDLE_64(uint32) cpu_to_core;
+    XEN_GUEST_HANDLE_64(uint32) cpu_to_socket;
+
+    /* OUT: number of cpus returned
+     * If OUT is greater than IN then the cpu_to_core/socket is truncated!
+     */
+    uint32_t nr_cpus;
 };
 
 struct xen_sysctl_pm_op {
@@ -349,6 +367,9 @@ struct xen_sysctl_pm_op {
     #define GET_CPUFREQ_PARA           (CPUFREQ_PARA | 0x01)
     #define SET_CPUFREQ_GOV            (CPUFREQ_PARA | 0x02)
     #define SET_CPUFREQ_PARA           (CPUFREQ_PARA | 0x03)
+
+    /* get CPU topology */
+    #define XEN_SYSCTL_pm_op_get_cputopo  0x20
 
     uint32_t cmd;
     uint32_t cpuid;
@@ -356,6 +377,7 @@ struct xen_sysctl_pm_op {
         struct xen_get_cpufreq_para get_para;
         struct xen_set_cpufreq_gov  set_gov;
         struct xen_set_cpufreq_para set_para;
+        struct xen_get_cputopo      get_topo;
     };
 };
 

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


 


Rackspace

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