ia64/xen-unstable

view xen/drivers/acpi/pmstat.c @ 18896:f7f8f44b9292

tools: Fix a few error-path memory leaks.

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Dec 09 12:53:19 2008 +0000 (2008-12-09)
parents 27eec3c54d08
children 605ef79ee46c
line source
1 /*****************************************************************************
2 # pmstat.c - Power Management statistic information (Px/Cx/Tx, etc.)
3 #
4 # Copyright (c) 2008, Liu Jinsong <jinsong.liu@intel.com>
5 #
6 # This program is free software; you can redistribute it and/or modify it
7 # under the terms of the GNU General Public License as published by the Free
8 # Software Foundation; either version 2 of the License, or (at your option)
9 # any later version.
10 #
11 # This program is distributed in the hope that it will be useful, but WITHOUT
12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 # more details.
15 #
16 # You should have received a copy of the GNU General Public License along with
17 # this program; if not, write to the Free Software Foundation, Inc., 59
18 # Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 #
20 # The full GNU General Public License is included in this distribution in the
21 # file called LICENSE.
22 #
23 *****************************************************************************/
25 #include <xen/config.h>
26 #include <xen/lib.h>
27 #include <xen/errno.h>
28 #include <xen/sched.h>
29 #include <xen/event.h>
30 #include <xen/irq.h>
31 #include <xen/iocap.h>
32 #include <xen/compat.h>
33 #include <xen/guest_access.h>
34 #include <asm/current.h>
35 #include <public/xen.h>
36 #include <xen/cpumask.h>
37 #include <asm/processor.h>
38 #include <xen/percpu.h>
39 #include <xen/domain.h>
41 #include <public/sysctl.h>
42 #include <acpi/cpufreq/cpufreq.h>
44 struct pm_px *__read_mostly cpufreq_statistic_data[NR_CPUS];
46 extern uint32_t pmstat_get_cx_nr(uint32_t cpuid);
47 extern int pmstat_get_cx_stat(uint32_t cpuid, struct pm_cx_stat *stat);
48 extern int pmstat_reset_cx_stat(uint32_t cpuid);
50 int do_get_pm_info(struct xen_sysctl_get_pmstat *op)
51 {
52 int ret = 0;
53 const struct processor_pminfo *pmpt;
55 if ( !op || (op->cpuid >= NR_CPUS) || !cpu_online(op->cpuid) )
56 return -EINVAL;
57 pmpt = processor_pminfo[op->cpuid];
59 switch ( op->type & PMSTAT_CATEGORY_MASK )
60 {
61 case PMSTAT_CX:
62 if ( !(xen_processor_pmbits & XEN_PROCESSOR_PM_CX) )
63 return -ENODEV;
64 break;
65 case PMSTAT_PX:
66 if ( !(xen_processor_pmbits & XEN_PROCESSOR_PM_PX) )
67 return -ENODEV;
68 if ( !pmpt || !(pmpt->perf.init & XEN_PX_INIT) )
69 return -EINVAL;
70 break;
71 default:
72 return -ENODEV;
73 }
75 switch ( op->type )
76 {
77 case PMSTAT_get_max_px:
78 {
79 op->u.getpx.total = pmpt->perf.state_count;
80 break;
81 }
83 case PMSTAT_get_pxstat:
84 {
85 uint64_t now, ct;
86 uint64_t total_idle_ns;
87 uint64_t tmp_idle_ns;
88 struct pm_px *pxpt = cpufreq_statistic_data[op->cpuid];
90 if ( !pxpt || !pxpt->u.pt || !pxpt->u.trans_pt )
91 return -ENODATA;
93 total_idle_ns = get_cpu_idle_time(op->cpuid);
94 tmp_idle_ns = total_idle_ns - pxpt->prev_idle_wall;
96 now = NOW();
97 pxpt->u.usable = pmpt->perf.state_count - pmpt->perf.platform_limit;
98 pxpt->u.pt[pxpt->u.cur].residency += now - pxpt->prev_state_wall;
99 pxpt->u.pt[pxpt->u.cur].residency -= tmp_idle_ns;
100 pxpt->prev_state_wall = now;
101 pxpt->prev_idle_wall = total_idle_ns;
103 ct = pmpt->perf.state_count;
104 if ( copy_to_guest(op->u.getpx.trans_pt, pxpt->u.trans_pt, ct*ct) )
105 {
106 ret = -EFAULT;
107 break;
108 }
110 if ( copy_to_guest(op->u.getpx.pt, pxpt->u.pt, ct) )
111 {
112 ret = -EFAULT;
113 break;
114 }
116 op->u.getpx.total = pxpt->u.total;
117 op->u.getpx.usable = pxpt->u.usable;
118 op->u.getpx.last = pxpt->u.last;
119 op->u.getpx.cur = pxpt->u.cur;
121 break;
122 }
124 case PMSTAT_reset_pxstat:
125 {
126 cpufreq_statistic_reset(op->cpuid);
127 break;
128 }
130 #ifdef CONFIG_X86
131 case PMSTAT_get_max_cx:
132 {
133 op->u.getcx.nr = pmstat_get_cx_nr(op->cpuid);
134 ret = 0;
135 break;
136 }
138 case PMSTAT_get_cxstat:
139 {
140 ret = pmstat_get_cx_stat(op->cpuid, &op->u.getcx);
141 break;
142 }
144 case PMSTAT_reset_cxstat:
145 {
146 ret = pmstat_reset_cx_stat(op->cpuid);
147 break;
148 }
149 #endif
151 default:
152 printk("not defined sub-hypercall @ do_get_pm_info\n");
153 ret = -ENOSYS;
154 break;
155 }
157 return ret;
158 }