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

[Xen-changelog] [xen-unstable] tools/misc/xenpm: provide core/package cstate residencies



# HG changeset patch
# User Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>
# Date 1279121442 -3600
# Node ID 6f264f32f046bff5b1258a235bd0dc199beb8016
# Parent  41c51b6cf5bcad9d0d4ac51bfdb0213326f89d41
tools/misc/xenpm: provide core/package cstate residencies

According to Intel 64 and IA32 Architectures SDM 3B Appendix B, Intel
Nehalem/Westmere processors provide h/w MSR to report the core/package
cstate residencies.Extend sysctl_get_pmstat interface to pass the
core/package cstate residencies, and modify xenpm to output those
information.

[tools part of the patch]

Signed-off-by: Wei Gang <gang.wei@xxxxxxxxx>
---
 tools/libxc/xc_pm.c   |    5 ++
 tools/libxc/xenctrl.h |    5 ++
 tools/misc/xenpm.c    |  103 ++++++++++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 110 insertions(+), 3 deletions(-)

diff -r 41c51b6cf5bc -r 6f264f32f046 tools/libxc/xc_pm.c
--- a/tools/libxc/xc_pm.c       Tue Jul 13 19:34:48 2010 +0100
+++ b/tools/libxc/xc_pm.c       Wed Jul 14 16:30:42 2010 +0100
@@ -152,6 +152,11 @@ int xc_pm_get_cxstat(xc_interface *xch, 
     cxpt->nr = sysctl.u.get_pmstat.u.getcx.nr;
     cxpt->last = sysctl.u.get_pmstat.u.getcx.last;
     cxpt->idle_time = sysctl.u.get_pmstat.u.getcx.idle_time;
+    cxpt->pc3 = sysctl.u.get_pmstat.u.getcx.pc3;
+    cxpt->pc6 = sysctl.u.get_pmstat.u.getcx.pc6;
+    cxpt->pc7 = sysctl.u.get_pmstat.u.getcx.pc7;
+    cxpt->cc3 = sysctl.u.get_pmstat.u.getcx.cc3;
+    cxpt->cc6 = sysctl.u.get_pmstat.u.getcx.cc6;
 
 unlock_3:
     unlock_pages(cxpt->residencies, max_cx * sizeof(uint64_t));
diff -r 41c51b6cf5bc -r 6f264f32f046 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h     Tue Jul 13 19:34:48 2010 +0100
+++ b/tools/libxc/xenctrl.h     Wed Jul 14 16:30:42 2010 +0100
@@ -1393,6 +1393,11 @@ struct xc_cx_stat {
     uint64_t idle_time;    /* idle time from boot */
     uint64_t *triggers;    /* Cx trigger counts */
     uint64_t *residencies; /* Cx residencies */
+    uint64_t pc3;
+    uint64_t pc6;
+    uint64_t pc7;
+    uint64_t cc3;
+    uint64_t cc6;
 };
 typedef struct xc_cx_stat xc_cx_stat_t;
 
diff -r 41c51b6cf5bc -r 6f264f32f046 tools/misc/xenpm.c
--- a/tools/misc/xenpm.c        Tue Jul 13 19:34:48 2010 +0100
+++ b/tools/misc/xenpm.c        Wed Jul 14 16:30:42 2010 +0100
@@ -15,6 +15,7 @@
  * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
  * Place - Suite 330, Boston, MA 02111-1307 USA.
  */
+#define MAX_NR_CPU 512
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -91,6 +92,13 @@ static void print_cxstat(int cpuid, stru
         printf("                       residency  [%020"PRIu64" ms]\n",
                cxstat->residencies[i]/1000000UL);
     }
+    printf("pc3                  : [%020"PRIu64" ms]\n"
+           "pc6                  : [%020"PRIu64" ms]\n"
+           "pc7                  : [%020"PRIu64" ms]\n",
+           cxstat->pc3/1000000UL, cxstat->pc6/1000000UL, 
cxstat->pc7/1000000UL);
+    printf("cc3                  : [%020"PRIu64" ms]\n"
+           "cc6                  : [%020"PRIu64" ms]\n",
+           cxstat->cc3/1000000UL, cxstat->cc6/1000000UL);
     printf("\n");
 }
 
@@ -306,9 +314,13 @@ static uint64_t *sum, *sum_cx, *sum_px;
 
 static void signal_int_handler(int signo)
 {
-    int i, j;
+    int i, j, k, ret;
     struct timeval tv;
     int cx_cap = 0, px_cap = 0;
+    uint32_t cpu_to_core[MAX_NR_CPU];
+    uint32_t cpu_to_socket[MAX_NR_CPU];
+    uint32_t cpu_to_node[MAX_NR_CPU];
+    xc_topologyinfo_t info = { 0 };
 
     if ( gettimeofday(&tv, NULL) == -1 )
     {
@@ -369,6 +381,93 @@ static void signal_int_handler(int signo
                     pxstat_start[i].pt[j].residency;
                 printf("  P%d\t%"PRIu64"\t(%5.2f%%)\n", j,
                         res / 1000000UL, 100UL * res / (double)sum_px[i]);
+            }
+        }
+    }
+
+    set_xen_guest_handle(info.cpu_to_core, cpu_to_core);
+    set_xen_guest_handle(info.cpu_to_socket, cpu_to_socket);
+    set_xen_guest_handle(info.cpu_to_node, cpu_to_node);
+    info.max_cpu_index = MAX_NR_CPU - 1;
+
+    ret = xc_topologyinfo(xc_handle, &info);
+    if ( !ret )
+    {
+        uint32_t socket_ids[MAX_NR_CPU];
+        uint32_t core_ids[MAX_NR_CPU];
+        uint32_t socket_nr = 0;
+        uint32_t core_nr = 0;
+
+        if ( info.max_cpu_index > MAX_NR_CPU - 1 )
+            info.max_cpu_index = MAX_NR_CPU - 1;
+        /* check validity */
+        for ( i = 0; i <= info.max_cpu_index; i++ )
+        {
+            if ( cpu_to_core[i] == INVALID_TOPOLOGY_ID ||
+                 cpu_to_socket[i] == INVALID_TOPOLOGY_ID )
+                break;
+        }
+        if ( i > info.max_cpu_index )
+        {
+            /* find socket nr & core nr per socket */
+            for ( i = 0; i <= info.max_cpu_index; i++ )
+            {
+                for ( j = 0; j < socket_nr; j++ )
+                    if ( cpu_to_socket[i] == socket_ids[j] )
+                        break;
+                if ( j == socket_nr )
+                {
+                    socket_ids[j] = cpu_to_socket[i];
+                    socket_nr++;
+                }
+
+                for ( j = 0; j < core_nr; j++ )
+                    if ( cpu_to_core[i] == core_ids[j] )
+                        break;
+                if ( j == core_nr )
+                {
+                    core_ids[j] = cpu_to_core[i];
+                    core_nr++;
+                }
+            }
+
+            /* print out CC? and PC? */
+            for ( i = 0; i < socket_nr; i++ )
+            {
+                uint64_t res;
+                for ( j = 0; j <= info.max_cpu_index; j++ )
+                {
+                    if ( cpu_to_socket[j] == socket_ids[i] )
+                        break;
+                }
+                printf("Socket %d\n", socket_ids[i]);
+                res = cxstat_end[j].pc3 - cxstat_start[j].pc3;
+                printf("\tPC3\t%"PRIu64" ms\t%.2f%%\n",  res / 1000000UL, 
+                       100UL * res / (double)sum_cx[j]);
+                res = cxstat_end[j].pc6 - cxstat_start[j].pc6;
+                printf("\tPC6\t%"PRIu64" ms\t%.2f%%\n",  res / 1000000UL, 
+                       100UL * res / (double)sum_cx[j]);
+                res = cxstat_end[j].pc7 - cxstat_start[j].pc7;
+                printf("\tPC7\t%"PRIu64" ms\t%.2f%%\n",  res / 1000000UL, 
+                       100UL * res / (double)sum_cx[j]);
+                for ( k = 0; k < core_nr; k++ )
+                {
+                    for ( j = 0; j <= info.max_cpu_index; j++ )
+                    {
+                        if ( cpu_to_socket[j] == socket_ids[i] &&
+                             cpu_to_core[j] == core_ids[k] )
+                            break;
+                    }
+                    printf("\t Core %d CPU %d\n", core_ids[k], j);
+                    res = cxstat_end[j].cc3 - cxstat_start[j].cc3;
+                    printf("\t\tCC3\t%"PRIu64" ms\t%.2f%%\n",  res / 
1000000UL, 
+                           100UL * res / (double)sum_cx[j]);
+                    res = cxstat_end[j].cc6 - cxstat_start[j].cc6;
+                    printf("\t\tCC6\t%"PRIu64" ms\t%.2f%%\n",  res / 
1000000UL, 
+                           100UL * res / (double)sum_cx[j]);
+                    printf("\n");
+
+                }
             }
         }
         printf("  Avg freq\t%d\tKHz\n", avgfreq[i]);
@@ -833,8 +932,6 @@ 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];

_______________________________________________
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®.