ia64/xen-unstable
changeset 18546:7592da5118ec
x86: Add xenpm utility to list CPU power info.
Signed-off-by: Lu Guanqun <guanqun.lu@intel.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
Signed-off-by: Lu Guanqun <guanqun.lu@intel.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Thu Sep 25 10:21:40 2008 +0100 (2008-09-25) |
parents | d4a093819310 |
children | 7a32c2325fdc |
files | .hgignore tools/misc/Makefile tools/misc/xenpm.c |
line diff
1.1 --- a/.hgignore Thu Sep 25 10:12:17 2008 +0100 1.2 +++ b/.hgignore Thu Sep 25 10:21:40 2008 +0100 1.3 @@ -183,6 +183,7 @@ 1.4 ^tools/misc/xen_cpuperf$ 1.5 ^tools/misc/xen-detect$ 1.6 ^tools/misc/xenperf$ 1.7 +^tools/misc/xenpm$ 1.8 ^tools/pygrub/build/.*$ 1.9 ^tools/python/build/.*$ 1.10 ^tools/security/secpol_tool$
2.1 --- a/tools/misc/Makefile Thu Sep 25 10:12:17 2008 +0100 2.2 +++ b/tools/misc/Makefile Thu Sep 25 10:21:40 2008 +0100 2.3 @@ -11,15 +11,20 @@ CFLAGS += $(INCLUDES) 2.4 HDRS = $(wildcard *.h) 2.5 2.6 TARGETS-y := xenperf 2.7 -TARGETS-$(CONFIG_X86) += xen-detect 2.8 +TARGETS-$(CONFIG_X86) += xen-detect xenpm 2.9 TARGETS := $(TARGETS-y) 2.10 2.11 SUBDIRS-$(CONFIG_LOMOUNT) += lomount 2.12 SUBDIRS-$(CONFIG_MINITERM) += miniterm 2.13 SUBDIRS := $(SUBDIRS-y) 2.14 2.15 -INSTALL_BIN = $(TARGETS) xencons 2.16 -INSTALL_SBIN = netfix xm xen-bugtool xen-python-path xend xenperf xsview 2.17 +INSTALL_BIN-y := xencons 2.18 +INSTALL_BIN-$(CONFIG_X86) += xen-detect 2.19 +INSTALL_BIN := $(INSTALL_BIN-y) 2.20 + 2.21 +INSTALL_SBIN-y := netfix xm xen-bugtool xen-python-path xend xenperf xsview 2.22 +INSTALL_SBIN-$(CONFIG_X86) += xenpm 2.23 +INSTALL_SBIN := $(INSTALL_SBIN-y) 2.24 2.25 DEFAULT_PYTHON_PATH := $(shell $(XEN_ROOT)/tools/python/get-path) 2.26 PYTHON_PATH ?= $(DEFAULT_PYTHON_PATH) 2.27 @@ -49,5 +54,5 @@ clean: 2.28 %.o: %.c $(HDRS) Makefile 2.29 $(CC) -c $(CFLAGS) -o $@ $< 2.30 2.31 -xenperf: %: %.o Makefile 2.32 +xenperf xenpm: %: %.o Makefile 2.33 $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) $(LDFLAGS_libxenctrl)
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/tools/misc/xenpm.c Thu Sep 25 10:21:40 2008 +0100 3.3 @@ -0,0 +1,197 @@ 3.4 +/* 3.5 + * xenpm.c: list the power information of the available processors 3.6 + * Copyright (c) 2008, Intel Corporation. 3.7 + * 3.8 + * This program is free software; you can redistribute it and/or modify it 3.9 + * under the terms and conditions of the GNU General Public License, 3.10 + * version 2, as published by the Free Software Foundation. 3.11 + * 3.12 + * This program is distributed in the hope it will be useful, but WITHOUT 3.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 3.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 3.15 + * more details. 3.16 + * 3.17 + * You should have received a copy of the GNU General Public License along with 3.18 + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple 3.19 + * Place - Suite 330, Boston, MA 02111-1307 USA. 3.20 + */ 3.21 + 3.22 +#include <stdio.h> 3.23 +#include <stdlib.h> 3.24 +#include <getopt.h> 3.25 +#include <errno.h> 3.26 + 3.27 +#include <xenctrl.h> 3.28 +#include <inttypes.h> 3.29 + 3.30 +int main(int argc, char **argv) 3.31 +{ 3.32 + int xc_fd; 3.33 + int i, j, ret = 0; 3.34 + int cinfo = 0, pinfo = 0; 3.35 + int ch; 3.36 + xc_physinfo_t physinfo = { 0 }; 3.37 + 3.38 + while ( (ch = getopt(argc, argv, "cp")) != -1 ) 3.39 + { 3.40 + switch ( ch ) 3.41 + { 3.42 + case 'c': 3.43 + cinfo = 1; 3.44 + break; 3.45 + case 'p': 3.46 + pinfo = 1; 3.47 + break; 3.48 + default: 3.49 + fprintf(stderr, "%s [-p] [-c]\n", argv[0]); 3.50 + return -1; 3.51 + } 3.52 + } 3.53 + 3.54 + if ( !cinfo && !pinfo ) 3.55 + { 3.56 + cinfo = 1; 3.57 + pinfo = 1; 3.58 + } 3.59 + 3.60 + xc_fd = xc_interface_open(); 3.61 + if ( xc_fd < 0 ) 3.62 + { 3.63 + fprintf(stderr, "failed to get the handler\n"); 3.64 + return xc_fd; 3.65 + } 3.66 + 3.67 + ret = xc_physinfo(xc_fd, &physinfo); 3.68 + if ( ret ) 3.69 + { 3.70 + fprintf(stderr, "failed to get the processor information\n"); 3.71 + xc_interface_close(xc_fd); 3.72 + return ret; 3.73 + } 3.74 + 3.75 + /* print out the C state information */ 3.76 + if ( cinfo ) 3.77 + { 3.78 + int max_cx_num = 0; 3.79 + struct xc_cx_stat cxstatinfo, *cxstat = &cxstatinfo; 3.80 + 3.81 + for ( i = 0; i < physinfo.nr_cpus; i++ ) 3.82 + { 3.83 + ret = xc_pm_get_max_cx(xc_fd, i, &max_cx_num); 3.84 + if ( ret ) 3.85 + { 3.86 + if ( errno == ENODEV ) 3.87 + fprintf(stderr, "Xen cpuidle is not enabled!\n"); 3.88 + else 3.89 + fprintf(stderr, "failed to get max C-state\n"); 3.90 + 3.91 + break; 3.92 + } 3.93 + 3.94 + cxstat->triggers = malloc(max_cx_num * sizeof(uint64_t)); 3.95 + if ( !cxstat->triggers ) 3.96 + { 3.97 + fprintf(stderr, "failed to malloc for C-states triggers\n"); 3.98 + break; 3.99 + } 3.100 + cxstat->residencies = malloc(max_cx_num * sizeof(uint64_t)); 3.101 + if ( !cxstat->residencies ) 3.102 + { 3.103 + fprintf(stderr, "failed to malloc for C-states residencies\n"); 3.104 + free(cxstat->triggers); 3.105 + break; 3.106 + } 3.107 + 3.108 + ret = xc_pm_get_cxstat(xc_fd, i, cxstat); 3.109 + if( ret ) 3.110 + { 3.111 + fprintf(stderr, "failed to get C-states statistics information\n"); 3.112 + free(cxstat->triggers); 3.113 + free(cxstat->residencies); 3.114 + break; 3.115 + } 3.116 + 3.117 + printf("cpu id : %d\n", i); 3.118 + printf("total C-states : %d\n", cxstat->nr); 3.119 + printf("idle time(ms) : %"PRIu64"\n", cxstat->idle_time/1000000UL); 3.120 + for ( j = 0; j < cxstat->nr; j++ ) 3.121 + { 3.122 + printf("C%d : transition [%020"PRIu64"]\n", 3.123 + j, cxstat->triggers[j]); 3.124 + printf(" residency [%020"PRIu64" ms]\n", 3.125 + cxstat->residencies[j]*1000000UL/3579/1000000UL); 3.126 + } 3.127 + 3.128 + free(cxstat->triggers); 3.129 + free(cxstat->residencies); 3.130 + 3.131 + printf("\n"); 3.132 + } 3.133 + } 3.134 + 3.135 + /* print out P state information */ 3.136 + if ( pinfo ) 3.137 + { 3.138 + int max_px_num = 0; 3.139 + struct xc_px_stat pxstatinfo, *pxstat = &pxstatinfo; 3.140 + 3.141 + for ( i = 0; i < physinfo.nr_cpus; i++ ) 3.142 + { 3.143 + ret = xc_pm_get_max_px(xc_fd, i, &max_px_num); 3.144 + if ( ret ) { 3.145 + if ( errno == ENODEV ) 3.146 + printf("Xen cpufreq is not enabled!\n"); 3.147 + else 3.148 + fprintf(stderr, "failed to get max P-state\n"); 3.149 + 3.150 + break; 3.151 + } 3.152 + 3.153 + pxstat->trans_pt = malloc(max_px_num * max_px_num * sizeof(uint64_t)); 3.154 + if ( !pxstat->trans_pt ) 3.155 + { 3.156 + fprintf(stderr, "failed to malloc for P-states transition table\n"); 3.157 + break; 3.158 + } 3.159 + pxstat->pt = malloc(max_px_num * sizeof(struct xc_px_val)); 3.160 + if ( !pxstat->pt ) 3.161 + { 3.162 + fprintf(stderr, "failed to malloc for P-states table\n"); 3.163 + free(pxstat->pt); 3.164 + break; 3.165 + } 3.166 + 3.167 + ret = xc_pm_get_pxstat(xc_fd, 0, pxstat); 3.168 + if( ret ) { 3.169 + fprintf(stderr, "failed to get P-states statistics information\n"); 3.170 + free(pxstat->trans_pt); 3.171 + free(pxstat->pt); 3.172 + break; 3.173 + } 3.174 + 3.175 + printf("cpu id : %d\n", i); 3.176 + printf("total P-states : %d\n", pxstat->total); 3.177 + printf("usable P-states : %d\n", pxstat->usable); 3.178 + printf("current frequency : %"PRIu64" MHz\n", pxstat->pt[pxstat->cur].freq); 3.179 + for ( j = 0; j < pxstat->total; j++ ) 3.180 + { 3.181 + if ( pxstat->cur == j ) 3.182 + printf("*P%d", j); 3.183 + else 3.184 + printf("P%d ", j); 3.185 + printf(" : freq [%04"PRIu64" MHz]\n", pxstat->pt[j].freq); 3.186 + printf(" transition [%020"PRIu64"]\n", pxstat->pt[j].count); 3.187 + printf(" residency [%020"PRIu64" ms]\n", pxstat->pt[j].residency/1000000UL); 3.188 + } 3.189 + 3.190 + free(pxstat->trans_pt); 3.191 + free(pxstat->pt); 3.192 + 3.193 + printf("\n"); 3.194 + } 3.195 + } 3.196 + 3.197 + xc_interface_close(xc_fd); 3.198 + return ret; 3.199 +} 3.200 +