aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2013-01-23 12:31:01 -0500
committerTejun Heo <tj@kernel.org>2013-01-23 12:31:01 -0500
commitc14afb82ffff5903a701a9fb737ac20f36d1f755 (patch)
tree304dcc7b1d7b9a5f564f7e978228e61ef41fbef2 /tools
parent0fdff3ec6d87856cdcc99e69cf42143fdd6c56b4 (diff)
parent1d8549085377674224bf30a368284c391a3ce40e (diff)
Merge branch 'master' into for-3.9-async
To receive f56c3196f251012de9b3ebaff55732a9074fdaae ("async: fix __lowest_in_progress()"). Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'tools')
-rw-r--r--tools/lguest/lguest.c84
-rw-r--r--tools/perf/MANIFEST10
-rw-r--r--tools/power/x86/turbostat/Makefile21
-rw-r--r--tools/power/x86/turbostat/turbostat.8103
-rw-r--r--tools/power/x86/turbostat/turbostat.c677
-rw-r--r--tools/power/x86/x86_energy_perf_policy/Makefile6
-rw-r--r--tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c2
-rw-r--r--tools/testing/selftests/ipc/Makefile25
-rw-r--r--tools/testing/selftests/ipc/msgque.c246
-rw-r--r--tools/virtio/virtio_test.c4
10 files changed, 1046 insertions, 132 deletions
diff --git a/tools/lguest/lguest.c b/tools/lguest/lguest.c
index fd2f9221b241..07a03452c227 100644
--- a/tools/lguest/lguest.c
+++ b/tools/lguest/lguest.c
@@ -179,29 +179,6 @@ static struct termios orig_term;
179#define wmb() __asm__ __volatile__("" : : : "memory") 179#define wmb() __asm__ __volatile__("" : : : "memory")
180#define mb() __asm__ __volatile__("" : : : "memory") 180#define mb() __asm__ __volatile__("" : : : "memory")
181 181
182/*
183 * Convert an iovec element to the given type.
184 *
185 * This is a fairly ugly trick: we need to know the size of the type and
186 * alignment requirement to check the pointer is kosher. It's also nice to
187 * have the name of the type in case we report failure.
188 *
189 * Typing those three things all the time is cumbersome and error prone, so we
190 * have a macro which sets them all up and passes to the real function.
191 */
192#define convert(iov, type) \
193 ((type *)_convert((iov), sizeof(type), __alignof__(type), #type))
194
195static void *_convert(struct iovec *iov, size_t size, size_t align,
196 const char *name)
197{
198 if (iov->iov_len != size)
199 errx(1, "Bad iovec size %zu for %s", iov->iov_len, name);
200 if ((unsigned long)iov->iov_base % align != 0)
201 errx(1, "Bad alignment %p for %s", iov->iov_base, name);
202 return iov->iov_base;
203}
204
205/* Wrapper for the last available index. Makes it easier to change. */ 182/* Wrapper for the last available index. Makes it easier to change. */
206#define lg_last_avail(vq) ((vq)->last_avail_idx) 183#define lg_last_avail(vq) ((vq)->last_avail_idx)
207 184
@@ -228,7 +205,8 @@ static bool iov_empty(const struct iovec iov[], unsigned int num_iov)
228} 205}
229 206
230/* Take len bytes from the front of this iovec. */ 207/* Take len bytes from the front of this iovec. */
231static void iov_consume(struct iovec iov[], unsigned num_iov, unsigned len) 208static void iov_consume(struct iovec iov[], unsigned num_iov,
209 void *dest, unsigned len)
232{ 210{
233 unsigned int i; 211 unsigned int i;
234 212
@@ -236,11 +214,16 @@ static void iov_consume(struct iovec iov[], unsigned num_iov, unsigned len)
236 unsigned int used; 214 unsigned int used;
237 215
238 used = iov[i].iov_len < len ? iov[i].iov_len : len; 216 used = iov[i].iov_len < len ? iov[i].iov_len : len;
217 if (dest) {
218 memcpy(dest, iov[i].iov_base, used);
219 dest += used;
220 }
239 iov[i].iov_base += used; 221 iov[i].iov_base += used;
240 iov[i].iov_len -= used; 222 iov[i].iov_len -= used;
241 len -= used; 223 len -= used;
242 } 224 }
243 assert(len == 0); 225 if (len != 0)
226 errx(1, "iovec too short!");
244} 227}
245 228
246/* The device virtqueue descriptors are followed by feature bitmasks. */ 229/* The device virtqueue descriptors are followed by feature bitmasks. */
@@ -864,7 +847,7 @@ static void console_output(struct virtqueue *vq)
864 warn("Write to stdout gave %i (%d)", len, errno); 847 warn("Write to stdout gave %i (%d)", len, errno);
865 break; 848 break;
866 } 849 }
867 iov_consume(iov, out, len); 850 iov_consume(iov, out, NULL, len);
868 } 851 }
869 852
870 /* 853 /*
@@ -1591,9 +1574,9 @@ static void blk_request(struct virtqueue *vq)
1591{ 1574{
1592 struct vblk_info *vblk = vq->dev->priv; 1575 struct vblk_info *vblk = vq->dev->priv;
1593 unsigned int head, out_num, in_num, wlen; 1576 unsigned int head, out_num, in_num, wlen;
1594 int ret; 1577 int ret, i;
1595 u8 *in; 1578 u8 *in;
1596 struct virtio_blk_outhdr *out; 1579 struct virtio_blk_outhdr out;
1597 struct iovec iov[vq->vring.num]; 1580 struct iovec iov[vq->vring.num];
1598 off64_t off; 1581 off64_t off;
1599 1582
@@ -1603,32 +1586,36 @@ static void blk_request(struct virtqueue *vq)
1603 */ 1586 */
1604 head = wait_for_vq_desc(vq, iov, &out_num, &in_num); 1587 head = wait_for_vq_desc(vq, iov, &out_num, &in_num);
1605 1588
1606 /* 1589 /* Copy the output header from the front of the iov (adjusts iov) */
1607 * Every block request should contain at least one output buffer 1590 iov_consume(iov, out_num, &out, sizeof(out));
1608 * (detailing the location on disk and the type of request) and one 1591
1609 * input buffer (to hold the result). 1592 /* Find and trim end of iov input array, for our status byte. */
1610 */ 1593 in = NULL;
1611 if (out_num == 0 || in_num == 0) 1594 for (i = out_num + in_num - 1; i >= out_num; i--) {
1612 errx(1, "Bad virtblk cmd %u out=%u in=%u", 1595 if (iov[i].iov_len > 0) {
1613 head, out_num, in_num); 1596 in = iov[i].iov_base + iov[i].iov_len - 1;
1597 iov[i].iov_len--;
1598 break;
1599 }
1600 }
1601 if (!in)
1602 errx(1, "Bad virtblk cmd with no room for status");
1614 1603
1615 out = convert(&iov[0], struct virtio_blk_outhdr);
1616 in = convert(&iov[out_num+in_num-1], u8);
1617 /* 1604 /*
1618 * For historical reasons, block operations are expressed in 512 byte 1605 * For historical reasons, block operations are expressed in 512 byte
1619 * "sectors". 1606 * "sectors".
1620 */ 1607 */
1621 off = out->sector * 512; 1608 off = out.sector * 512;
1622 1609
1623 /* 1610 /*
1624 * In general the virtio block driver is allowed to try SCSI commands. 1611 * In general the virtio block driver is allowed to try SCSI commands.
1625 * It'd be nice if we supported eject, for example, but we don't. 1612 * It'd be nice if we supported eject, for example, but we don't.
1626 */ 1613 */
1627 if (out->type & VIRTIO_BLK_T_SCSI_CMD) { 1614 if (out.type & VIRTIO_BLK_T_SCSI_CMD) {
1628 fprintf(stderr, "Scsi commands unsupported\n"); 1615 fprintf(stderr, "Scsi commands unsupported\n");
1629 *in = VIRTIO_BLK_S_UNSUPP; 1616 *in = VIRTIO_BLK_S_UNSUPP;
1630 wlen = sizeof(*in); 1617 wlen = sizeof(*in);
1631 } else if (out->type & VIRTIO_BLK_T_OUT) { 1618 } else if (out.type & VIRTIO_BLK_T_OUT) {
1632 /* 1619 /*
1633 * Write 1620 * Write
1634 * 1621 *
@@ -1636,10 +1623,10 @@ static void blk_request(struct virtqueue *vq)
1636 * if they try to write past end. 1623 * if they try to write past end.
1637 */ 1624 */
1638 if (lseek64(vblk->fd, off, SEEK_SET) != off) 1625 if (lseek64(vblk->fd, off, SEEK_SET) != off)
1639 err(1, "Bad seek to sector %llu", out->sector); 1626 err(1, "Bad seek to sector %llu", out.sector);
1640 1627
1641 ret = writev(vblk->fd, iov+1, out_num-1); 1628 ret = writev(vblk->fd, iov, out_num);
1642 verbose("WRITE to sector %llu: %i\n", out->sector, ret); 1629 verbose("WRITE to sector %llu: %i\n", out.sector, ret);
1643 1630
1644 /* 1631 /*
1645 * Grr... Now we know how long the descriptor they sent was, we 1632 * Grr... Now we know how long the descriptor they sent was, we
@@ -1655,7 +1642,7 @@ static void blk_request(struct virtqueue *vq)
1655 1642
1656 wlen = sizeof(*in); 1643 wlen = sizeof(*in);
1657 *in = (ret >= 0 ? VIRTIO_BLK_S_OK : VIRTIO_BLK_S_IOERR); 1644 *in = (ret >= 0 ? VIRTIO_BLK_S_OK : VIRTIO_BLK_S_IOERR);
1658 } else if (out->type & VIRTIO_BLK_T_FLUSH) { 1645 } else if (out.type & VIRTIO_BLK_T_FLUSH) {
1659 /* Flush */ 1646 /* Flush */
1660 ret = fdatasync(vblk->fd); 1647 ret = fdatasync(vblk->fd);
1661 verbose("FLUSH fdatasync: %i\n", ret); 1648 verbose("FLUSH fdatasync: %i\n", ret);
@@ -1669,10 +1656,9 @@ static void blk_request(struct virtqueue *vq)
1669 * if they try to read past end. 1656 * if they try to read past end.
1670 */ 1657 */
1671 if (lseek64(vblk->fd, off, SEEK_SET) != off) 1658 if (lseek64(vblk->fd, off, SEEK_SET) != off)
1672 err(1, "Bad seek to sector %llu", out->sector); 1659 err(1, "Bad seek to sector %llu", out.sector);
1673 1660
1674 ret = readv(vblk->fd, iov+1, in_num-1); 1661 ret = readv(vblk->fd, iov + out_num, in_num);
1675 verbose("READ from sector %llu: %i\n", out->sector, ret);
1676 if (ret >= 0) { 1662 if (ret >= 0) {
1677 wlen = sizeof(*in) + ret; 1663 wlen = sizeof(*in) + ret;
1678 *in = VIRTIO_BLK_S_OK; 1664 *in = VIRTIO_BLK_S_OK;
@@ -1758,7 +1744,7 @@ static void rng_input(struct virtqueue *vq)
1758 len = readv(rng_info->rfd, iov, in_num); 1744 len = readv(rng_info->rfd, iov, in_num);
1759 if (len <= 0) 1745 if (len <= 0)
1760 err(1, "Read from /dev/random gave %i", len); 1746 err(1, "Read from /dev/random gave %i", len);
1761 iov_consume(iov, in_num, len); 1747 iov_consume(iov, in_num, NULL, len);
1762 totlen += len; 1748 totlen += len;
1763 } 1749 }
1764 1750
diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST
index 80db3f4bcf7a..39d41068484f 100644
--- a/tools/perf/MANIFEST
+++ b/tools/perf/MANIFEST
@@ -11,11 +11,21 @@ lib/rbtree.c
11include/linux/swab.h 11include/linux/swab.h
12arch/*/include/asm/unistd*.h 12arch/*/include/asm/unistd*.h
13arch/*/include/asm/perf_regs.h 13arch/*/include/asm/perf_regs.h
14arch/*/include/uapi/asm/unistd*.h
15arch/*/include/uapi/asm/perf_regs.h
14arch/*/lib/memcpy*.S 16arch/*/lib/memcpy*.S
15arch/*/lib/memset*.S 17arch/*/lib/memset*.S
16include/linux/poison.h 18include/linux/poison.h
17include/linux/magic.h 19include/linux/magic.h
18include/linux/hw_breakpoint.h 20include/linux/hw_breakpoint.h
21include/linux/rbtree_augmented.h
22include/uapi/linux/perf_event.h
23include/uapi/linux/const.h
24include/uapi/linux/swab.h
25include/uapi/linux/hw_breakpoint.h
19arch/x86/include/asm/svm.h 26arch/x86/include/asm/svm.h
20arch/x86/include/asm/vmx.h 27arch/x86/include/asm/vmx.h
21arch/x86/include/asm/kvm_host.h 28arch/x86/include/asm/kvm_host.h
29arch/x86/include/uapi/asm/svm.h
30arch/x86/include/uapi/asm/vmx.h
31arch/x86/include/uapi/asm/kvm.h
diff --git a/tools/power/x86/turbostat/Makefile b/tools/power/x86/turbostat/Makefile
index f85649554191..f09641da40d4 100644
--- a/tools/power/x86/turbostat/Makefile
+++ b/tools/power/x86/turbostat/Makefile
@@ -1,9 +1,22 @@
1CC = $(CROSS_COMPILE)gcc
2BUILD_OUTPUT := $(PWD)
3PREFIX := /usr
4DESTDIR :=
5
1turbostat : turbostat.c 6turbostat : turbostat.c
2CFLAGS += -Wall 7CFLAGS += -Wall
8CFLAGS += -I../../../../arch/x86/include/uapi/
9
10%: %.c
11 @mkdir -p $(BUILD_OUTPUT)
12 $(CC) $(CFLAGS) $< -o $(BUILD_OUTPUT)/$@
3 13
14.PHONY : clean
4clean : 15clean :
5 rm -f turbostat 16 @rm -f $(BUILD_OUTPUT)/turbostat
6 17
7install : 18install : turbostat
8 install turbostat /usr/bin/turbostat 19 install -d $(DESTDIR)$(PREFIX)/bin
9 install turbostat.8 /usr/share/man/man8 20 install $(BUILD_OUTPUT)/turbostat $(DESTDIR)$(PREFIX)/bin/turbostat
21 install -d $(DESTDIR)$(PREFIX)/share/man/man8
22 install turbostat.8 $(DESTDIR)$(PREFIX)/share/man/man8
diff --git a/tools/power/x86/turbostat/turbostat.8 b/tools/power/x86/turbostat/turbostat.8
index e4d0690cccf9..0d7dc2cfefb5 100644
--- a/tools/power/x86/turbostat/turbostat.8
+++ b/tools/power/x86/turbostat/turbostat.8
@@ -11,16 +11,16 @@ turbostat \- Report processor frequency and idle statistics
11.RB [ Options ] 11.RB [ Options ]
12.RB [ "\-i interval_sec" ] 12.RB [ "\-i interval_sec" ]
13.SH DESCRIPTION 13.SH DESCRIPTION
14\fBturbostat \fP reports processor topology, frequency 14\fBturbostat \fP reports processor topology, frequency,
15and idle power state statistics on modern X86 processors. 15idle power-state statistics, temperature and power on modern X86 processors.
16Either \fBcommand\fP is forked and statistics are printed 16Either \fBcommand\fP is forked and statistics are printed
17upon its completion, or statistics are printed periodically. 17upon its completion, or statistics are printed periodically.
18 18
19\fBturbostat \fP 19\fBturbostat \fP
20requires that the processor 20must be run on root, and
21minimally requires that the processor
21supports an "invariant" TSC, plus the APERF and MPERF MSRs. 22supports an "invariant" TSC, plus the APERF and MPERF MSRs.
22\fBturbostat \fP will report idle cpu power state residency 23Additional information is reported depending on hardware counter support.
23on processors that additionally support C-state residency counters.
24 24
25.SS Options 25.SS Options
26The \fB-p\fP option limits output to the 1st thread in 1st core of each package. 26The \fB-p\fP option limits output to the 1st thread in 1st core of each package.
@@ -57,7 +57,15 @@ Note that multiple CPUs per core indicate support for Intel(R) Hyper-Threading T
57\fBGHz\fP average clock rate while the CPU was in c0 state. 57\fBGHz\fP average clock rate while the CPU was in c0 state.
58\fBTSC\fP average GHz that the TSC ran during the entire interval. 58\fBTSC\fP average GHz that the TSC ran during the entire interval.
59\fB%c1, %c3, %c6, %c7\fP show the percentage residency in hardware core idle states. 59\fB%c1, %c3, %c6, %c7\fP show the percentage residency in hardware core idle states.
60\fBCTMP\fP Degrees Celsius reported by the per-core Digital Thermal Sensor.
61\fBPTMP\fP Degrees Celsius reported by the per-package Package Thermal Monitor.
60\fB%pc2, %pc3, %pc6, %pc7\fP percentage residency in hardware package idle states. 62\fB%pc2, %pc3, %pc6, %pc7\fP percentage residency in hardware package idle states.
63\fBPkg_W\fP Watts consumed by the whole package.
64\fBCor_W\fP Watts consumed by the core part of the package.
65\fBGFX_W\fP Watts consumed by the Graphics part of the package -- available only on client processors.
66\fBRAM_W\fP Watts consumed by the DRAM DIMMS -- available only on server processors.
67\fBPKG_%\fP percent of the interval that RAPL throttling was active on the Package.
68\fBRAM_%\fP percent of the interval that RAPL throttling was active on DRAM.
61.fi 69.fi
62.PP 70.PP
63.SH EXAMPLE 71.SH EXAMPLE
@@ -66,50 +74,73 @@ Without any parameters, turbostat prints out counters ever 5 seconds.
66for turbostat to fork). 74for turbostat to fork).
67 75
68The first row of statistics is a summary for the entire system. 76The first row of statistics is a summary for the entire system.
69Note that the summary is a weighted average. 77For residency % columns, the summary is a weighted average.
78For Temperature columns, the summary is the column maximum.
79For Watts columns, the summary is a system total.
70Subsequent rows show per-CPU statistics. 80Subsequent rows show per-CPU statistics.
71 81
72.nf 82.nf
73[root@x980]# ./turbostat 83[root@sandy]# ./turbostat
74cor CPU %c0 GHz TSC %c1 %c3 %c6 %pc3 %pc6 84cor CPU %c0 GHz TSC %c1 %c3 %c6 %c7 CTMP PTMP %pc2 %pc3 %pc6 %pc7 Pkg_W Cor_W GFX_W
75 0.09 1.62 3.38 1.83 0.32 97.76 1.26 83.61 85 0.06 0.80 2.29 0.11 0.00 0.00 99.83 47 40 0.26 0.01 0.44 98.78 3.49 0.12 0.14
76 0 0 0.15 1.62 3.38 10.23 0.05 89.56 1.26 83.61 86 0 0 0.07 0.80 2.29 0.07 0.00 0.00 99.86 40 40 0.26 0.01 0.44 98.78 3.49 0.12 0.14
77 0 6 0.05 1.62 3.38 10.34 87 0 4 0.03 0.80 2.29 0.12
78 1 2 0.03 1.62 3.38 0.07 0.05 99.86 88 1 1 0.04 0.80 2.29 0.25 0.01 0.00 99.71 40
79 1 8 0.03 1.62 3.38 0.06 89 1 5 0.16 0.80 2.29 0.13
80 2 4 0.21 1.62 3.38 0.10 1.49 98.21 90 2 2 0.05 0.80 2.29 0.06 0.01 0.00 99.88 40
81 2 10 0.02 1.62 3.38 0.29 91 2 6 0.03 0.80 2.29 0.08
82 8 1 0.04 1.62 3.38 0.04 0.08 99.84 92 3 3 0.05 0.80 2.29 0.08 0.00 0.00 99.87 47
83 8 7 0.01 1.62 3.38 0.06 93 3 7 0.04 0.84 2.29 0.09
84 9 3 0.53 1.62 3.38 0.10 0.20 99.17
85 9 9 0.02 1.62 3.38 0.60
86 10 5 0.01 1.62 3.38 0.02 0.04 99.92
87 10 11 0.02 1.62 3.38 0.02
88.fi 94.fi
89.SH SUMMARY EXAMPLE 95.SH SUMMARY EXAMPLE
90The "-s" option prints the column headers just once, 96The "-s" option prints the column headers just once,
91and then the one line system summary for each sample interval. 97and then the one line system summary for each sample interval.
92 98
93.nf 99.nf
94[root@x980]# ./turbostat -s 100[root@wsm]# turbostat -S
95 %c0 GHz TSC %c1 %c3 %c6 %pc3 %pc6 101 %c0 GHz TSC %c1 %c3 %c6 CTMP %pc3 %pc6
96 0.23 1.67 3.38 2.00 0.30 97.47 1.07 82.12 102 1.40 2.81 3.38 10.78 43.47 44.35 42 13.67 2.09
97 0.10 1.62 3.38 1.87 2.25 95.77 12.02 72.60 103 1.34 2.90 3.38 11.48 58.96 28.23 41 19.89 0.15
98 0.20 1.64 3.38 1.98 0.11 97.72 0.30 83.36 104 1.55 2.72 3.38 26.73 37.66 34.07 42 2.53 2.80
99 0.11 1.70 3.38 1.86 1.81 96.22 9.71 74.90 105 1.37 2.83 3.38 16.95 60.05 21.63 42 5.76 0.20
100.fi 106.fi
101.SH VERBOSE EXAMPLE 107.SH VERBOSE EXAMPLE
102The "-v" option adds verbosity to the output: 108The "-v" option adds verbosity to the output:
103 109
104.nf 110.nf
105GenuineIntel 11 CPUID levels; family:model:stepping 0x6:2c:2 (6:44:2) 111[root@ivy]# turbostat -v
10612 * 133 = 1600 MHz max efficiency 112turbostat v3.0 November 23, 2012 - Len Brown <lenb@kernel.org>
10725 * 133 = 3333 MHz TSC frequency 113CPUID(0): GenuineIntel 13 CPUID levels; family:model:stepping 0x6:3a:9 (6:58:9)
10826 * 133 = 3467 MHz max turbo 4 active cores 114CPUID(6): APERF, DTS, PTM, EPB
10926 * 133 = 3467 MHz max turbo 3 active cores 115RAPL: 851 sec. Joule Counter Range
11027 * 133 = 3600 MHz max turbo 2 active cores 116cpu0: MSR_NHM_PLATFORM_INFO: 0x81010f0012300
11127 * 133 = 3600 MHz max turbo 1 active cores 11716 * 100 = 1600 MHz max efficiency
112 11835 * 100 = 3500 MHz TSC frequency
119cpu0: MSR_NHM_SNB_PKG_CST_CFG_CTL: 0x1e008402 (UNdemote-C3, UNdemote-C1, demote-C3, demote-C1, locked: pkg-cstate-limit=2: pc6-noret)
120cpu0: MSR_NHM_TURBO_RATIO_LIMIT: 0x25262727
12137 * 100 = 3700 MHz max turbo 4 active cores
12238 * 100 = 3800 MHz max turbo 3 active cores
12339 * 100 = 3900 MHz max turbo 2 active cores
12439 * 100 = 3900 MHz max turbo 1 active cores
125cpu0: MSR_IA32_ENERGY_PERF_BIAS: 0x00000006 (balanced)
126cpu0: MSR_RAPL_POWER_UNIT: 0x000a1003 (0.125000 Watts, 0.000015 Joules, 0.000977 sec.)
127cpu0: MSR_PKG_POWER_INFO: 0x01e00268 (77 W TDP, RAPL 60 - 0 W, 0.000000 sec.)
128cpu0: MSR_PKG_POWER_LIMIT: 0x830000148268 (UNlocked)
129cpu0: PKG Limit #1: ENabled (77.000000 Watts, 1.000000 sec, clamp DISabled)
130cpu0: PKG Limit #2: ENabled (96.000000 Watts, 0.000977* sec, clamp DISabled)
131cpu0: MSR_PP0_POLICY: 0
132cpu0: MSR_PP0_POWER_LIMIT: 0x00000000 (UNlocked)
133cpu0: Cores Limit: DISabled (0.000000 Watts, 0.000977 sec, clamp DISabled)
134cpu0: MSR_PP1_POLICY: 0
135cpu0: MSR_PP1_POWER_LIMIT: 0x00000000 (UNlocked)
136cpu0: GFX Limit: DISabled (0.000000 Watts, 0.000977 sec, clamp DISabled)
137cpu0: MSR_IA32_TEMPERATURE_TARGET: 0x00691400 (105 C)
138cpu0: MSR_IA32_PACKAGE_THERM_STATUS: 0x884e0000 (27 C)
139cpu0: MSR_IA32_THERM_STATUS: 0x88560000 (19 C +/- 1)
140cpu1: MSR_IA32_THERM_STATUS: 0x88560000 (19 C +/- 1)
141cpu2: MSR_IA32_THERM_STATUS: 0x88540000 (21 C +/- 1)
142cpu3: MSR_IA32_THERM_STATUS: 0x884e0000 (27 C +/- 1)
143 ...
113.fi 144.fi
114The \fBmax efficiency\fP frequency, a.k.a. Low Frequency Mode, is the frequency 145The \fBmax efficiency\fP frequency, a.k.a. Low Frequency Mode, is the frequency
115available at the minimum package voltage. The \fBTSC frequency\fP is the nominal 146available at the minimum package voltage. The \fBTSC frequency\fP is the nominal
@@ -142,7 +173,7 @@ cor CPU %c0 GHz TSC %c1 %c3 %c6 %pc3 %pc6
142 10 5 1.42 3.43 3.38 2.14 30.99 65.44 173 10 5 1.42 3.43 3.38 2.14 30.99 65.44
143 10 11 0.16 2.88 3.38 3.40 174 10 11 0.16 2.88 3.38 3.40
144.fi 175.fi
145Above the cycle soaker drives cpu7 up its 3.6 Ghz turbo limit 176Above the cycle soaker drives cpu7 up its 3.6 GHz turbo limit
146while the other processors are generally in various states of idle. 177while the other processors are generally in various states of idle.
147 178
148Note that cpu1 and cpu7 are HT siblings within core8. 179Note that cpu1 and cpu7 are HT siblings within core8.
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index ea095abbe97e..ce6d46038f74 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -20,6 +20,7 @@
20 */ 20 */
21 21
22#define _GNU_SOURCE 22#define _GNU_SOURCE
23#include <asm/msr.h>
23#include <stdio.h> 24#include <stdio.h>
24#include <unistd.h> 25#include <unistd.h>
25#include <sys/types.h> 26#include <sys/types.h>
@@ -35,28 +36,18 @@
35#include <ctype.h> 36#include <ctype.h>
36#include <sched.h> 37#include <sched.h>
37 38
38#define MSR_NEHALEM_PLATFORM_INFO 0xCE
39#define MSR_NEHALEM_TURBO_RATIO_LIMIT 0x1AD
40#define MSR_IVT_TURBO_RATIO_LIMIT 0x1AE
41#define MSR_APERF 0xE8
42#define MSR_MPERF 0xE7
43#define MSR_PKG_C2_RESIDENCY 0x60D /* SNB only */
44#define MSR_PKG_C3_RESIDENCY 0x3F8
45#define MSR_PKG_C6_RESIDENCY 0x3F9
46#define MSR_PKG_C7_RESIDENCY 0x3FA /* SNB only */
47#define MSR_CORE_C3_RESIDENCY 0x3FC
48#define MSR_CORE_C6_RESIDENCY 0x3FD
49#define MSR_CORE_C7_RESIDENCY 0x3FE /* SNB only */
50
51char *proc_stat = "/proc/stat"; 39char *proc_stat = "/proc/stat";
52unsigned int interval_sec = 5; /* set with -i interval_sec */ 40unsigned int interval_sec = 5; /* set with -i interval_sec */
53unsigned int verbose; /* set with -v */ 41unsigned int verbose; /* set with -v */
42unsigned int rapl_verbose; /* set with -R */
43unsigned int thermal_verbose; /* set with -T */
54unsigned int summary_only; /* set with -s */ 44unsigned int summary_only; /* set with -s */
55unsigned int skip_c0; 45unsigned int skip_c0;
56unsigned int skip_c1; 46unsigned int skip_c1;
57unsigned int do_nhm_cstates; 47unsigned int do_nhm_cstates;
58unsigned int do_snb_cstates; 48unsigned int do_snb_cstates;
59unsigned int has_aperf; 49unsigned int has_aperf;
50unsigned int has_epb;
60unsigned int units = 1000000000; /* Ghz etc */ 51unsigned int units = 1000000000; /* Ghz etc */
61unsigned int genuine_intel; 52unsigned int genuine_intel;
62unsigned int has_invariant_tsc; 53unsigned int has_invariant_tsc;
@@ -74,6 +65,23 @@ unsigned int show_cpu;
74unsigned int show_pkg_only; 65unsigned int show_pkg_only;
75unsigned int show_core_only; 66unsigned int show_core_only;
76char *output_buffer, *outp; 67char *output_buffer, *outp;
68unsigned int do_rapl;
69unsigned int do_dts;
70unsigned int do_ptm;
71unsigned int tcc_activation_temp;
72unsigned int tcc_activation_temp_override;
73double rapl_power_units, rapl_energy_units, rapl_time_units;
74double rapl_joule_counter_range;
75
76#define RAPL_PKG (1 << 0)
77#define RAPL_CORES (1 << 1)
78#define RAPL_GFX (1 << 2)
79#define RAPL_DRAM (1 << 3)
80#define RAPL_PKG_PERF_STATUS (1 << 4)
81#define RAPL_DRAM_PERF_STATUS (1 << 5)
82#define TJMAX_DEFAULT 100
83
84#define MAX(a, b) ((a) > (b) ? (a) : (b))
77 85
78int aperf_mperf_unstable; 86int aperf_mperf_unstable;
79int backwards_count; 87int backwards_count;
@@ -101,6 +109,7 @@ struct core_data {
101 unsigned long long c3; 109 unsigned long long c3;
102 unsigned long long c6; 110 unsigned long long c6;
103 unsigned long long c7; 111 unsigned long long c7;
112 unsigned int core_temp_c;
104 unsigned int core_id; 113 unsigned int core_id;
105} *core_even, *core_odd; 114} *core_even, *core_odd;
106 115
@@ -110,6 +119,14 @@ struct pkg_data {
110 unsigned long long pc6; 119 unsigned long long pc6;
111 unsigned long long pc7; 120 unsigned long long pc7;
112 unsigned int package_id; 121 unsigned int package_id;
122 unsigned int energy_pkg; /* MSR_PKG_ENERGY_STATUS */
123 unsigned int energy_dram; /* MSR_DRAM_ENERGY_STATUS */
124 unsigned int energy_cores; /* MSR_PP0_ENERGY_STATUS */
125 unsigned int energy_gfx; /* MSR_PP1_ENERGY_STATUS */
126 unsigned int rapl_pkg_perf_status; /* MSR_PKG_PERF_STATUS */
127 unsigned int rapl_dram_perf_status; /* MSR_DRAM_PERF_STATUS */
128 unsigned int pkg_temp_c;
129
113} *package_even, *package_odd; 130} *package_even, *package_odd;
114 131
115#define ODD_COUNTERS thread_odd, core_odd, package_odd 132#define ODD_COUNTERS thread_odd, core_odd, package_odd
@@ -247,6 +264,12 @@ void print_header(void)
247 outp += sprintf(outp, " %%c6"); 264 outp += sprintf(outp, " %%c6");
248 if (do_snb_cstates) 265 if (do_snb_cstates)
249 outp += sprintf(outp, " %%c7"); 266 outp += sprintf(outp, " %%c7");
267
268 if (do_dts)
269 outp += sprintf(outp, " CTMP");
270 if (do_ptm)
271 outp += sprintf(outp, " PTMP");
272
250 if (do_snb_cstates) 273 if (do_snb_cstates)
251 outp += sprintf(outp, " %%pc2"); 274 outp += sprintf(outp, " %%pc2");
252 if (do_nhm_cstates) 275 if (do_nhm_cstates)
@@ -256,6 +279,19 @@ void print_header(void)
256 if (do_snb_cstates) 279 if (do_snb_cstates)
257 outp += sprintf(outp, " %%pc7"); 280 outp += sprintf(outp, " %%pc7");
258 281
282 if (do_rapl & RAPL_PKG)
283 outp += sprintf(outp, " Pkg_W");
284 if (do_rapl & RAPL_CORES)
285 outp += sprintf(outp, " Cor_W");
286 if (do_rapl & RAPL_GFX)
287 outp += sprintf(outp, " GFX_W");
288 if (do_rapl & RAPL_DRAM)
289 outp += sprintf(outp, " RAM_W");
290 if (do_rapl & RAPL_PKG_PERF_STATUS)
291 outp += sprintf(outp, " PKG_%%");
292 if (do_rapl & RAPL_DRAM_PERF_STATUS)
293 outp += sprintf(outp, " RAM_%%");
294
259 outp += sprintf(outp, "\n"); 295 outp += sprintf(outp, "\n");
260} 296}
261 297
@@ -285,6 +321,7 @@ int dump_counters(struct thread_data *t, struct core_data *c,
285 fprintf(stderr, "c3: %016llX\n", c->c3); 321 fprintf(stderr, "c3: %016llX\n", c->c3);
286 fprintf(stderr, "c6: %016llX\n", c->c6); 322 fprintf(stderr, "c6: %016llX\n", c->c6);
287 fprintf(stderr, "c7: %016llX\n", c->c7); 323 fprintf(stderr, "c7: %016llX\n", c->c7);
324 fprintf(stderr, "DTS: %dC\n", c->core_temp_c);
288 } 325 }
289 326
290 if (p) { 327 if (p) {
@@ -293,6 +330,13 @@ int dump_counters(struct thread_data *t, struct core_data *c,
293 fprintf(stderr, "pc3: %016llX\n", p->pc3); 330 fprintf(stderr, "pc3: %016llX\n", p->pc3);
294 fprintf(stderr, "pc6: %016llX\n", p->pc6); 331 fprintf(stderr, "pc6: %016llX\n", p->pc6);
295 fprintf(stderr, "pc7: %016llX\n", p->pc7); 332 fprintf(stderr, "pc7: %016llX\n", p->pc7);
333 fprintf(stderr, "Joules PKG: %0X\n", p->energy_pkg);
334 fprintf(stderr, "Joules COR: %0X\n", p->energy_cores);
335 fprintf(stderr, "Joules GFX: %0X\n", p->energy_gfx);
336 fprintf(stderr, "Joules RAM: %0X\n", p->energy_dram);
337 fprintf(stderr, "Throttle PKG: %0X\n", p->rapl_pkg_perf_status);
338 fprintf(stderr, "Throttle RAM: %0X\n", p->rapl_dram_perf_status);
339 fprintf(stderr, "PTM: %dC\n", p->pkg_temp_c);
296 } 340 }
297 return 0; 341 return 0;
298} 342}
@@ -302,14 +346,21 @@ int dump_counters(struct thread_data *t, struct core_data *c,
302 * package: "pk" 2 columns %2d 346 * package: "pk" 2 columns %2d
303 * core: "cor" 3 columns %3d 347 * core: "cor" 3 columns %3d
304 * CPU: "CPU" 3 columns %3d 348 * CPU: "CPU" 3 columns %3d
349 * Pkg_W: %6.2
350 * Cor_W: %6.2
351 * GFX_W: %5.2
352 * RAM_W: %5.2
305 * GHz: "GHz" 3 columns %3.2 353 * GHz: "GHz" 3 columns %3.2
306 * TSC: "TSC" 3 columns %3.2 354 * TSC: "TSC" 3 columns %3.2
307 * percentage " %pc3" %6.2 355 * percentage " %pc3" %6.2
356 * Perf Status percentage: %5.2
357 * "CTMP" 4 columns %4d
308 */ 358 */
309int format_counters(struct thread_data *t, struct core_data *c, 359int format_counters(struct thread_data *t, struct core_data *c,
310 struct pkg_data *p) 360 struct pkg_data *p)
311{ 361{
312 double interval_float; 362 double interval_float;
363 char *fmt5, *fmt6;
313 364
314 /* if showing only 1st thread in core and this isn't one, bail out */ 365 /* if showing only 1st thread in core and this isn't one, bail out */
315 if (show_core_only && !(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) 366 if (show_core_only && !(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
@@ -349,7 +400,6 @@ int format_counters(struct thread_data *t, struct core_data *c,
349 if (show_cpu) 400 if (show_cpu)
350 outp += sprintf(outp, " %3d", t->cpu_id); 401 outp += sprintf(outp, " %3d", t->cpu_id);
351 } 402 }
352
353 /* %c0 */ 403 /* %c0 */
354 if (do_nhm_cstates) { 404 if (do_nhm_cstates) {
355 if (show_pkg || show_core || show_cpu) 405 if (show_pkg || show_core || show_cpu)
@@ -414,10 +464,16 @@ int format_counters(struct thread_data *t, struct core_data *c,
414 if (do_snb_cstates) 464 if (do_snb_cstates)
415 outp += sprintf(outp, " %6.2f", 100.0 * c->c7/t->tsc); 465 outp += sprintf(outp, " %6.2f", 100.0 * c->c7/t->tsc);
416 466
467 if (do_dts)
468 outp += sprintf(outp, " %4d", c->core_temp_c);
469
417 /* print per-package data only for 1st core in package */ 470 /* print per-package data only for 1st core in package */
418 if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) 471 if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
419 goto done; 472 goto done;
420 473
474 if (do_ptm)
475 outp += sprintf(outp, " %4d", p->pkg_temp_c);
476
421 if (do_snb_cstates) 477 if (do_snb_cstates)
422 outp += sprintf(outp, " %6.2f", 100.0 * p->pc2/t->tsc); 478 outp += sprintf(outp, " %6.2f", 100.0 * p->pc2/t->tsc);
423 if (do_nhm_cstates) 479 if (do_nhm_cstates)
@@ -426,6 +482,32 @@ int format_counters(struct thread_data *t, struct core_data *c,
426 outp += sprintf(outp, " %6.2f", 100.0 * p->pc6/t->tsc); 482 outp += sprintf(outp, " %6.2f", 100.0 * p->pc6/t->tsc);
427 if (do_snb_cstates) 483 if (do_snb_cstates)
428 outp += sprintf(outp, " %6.2f", 100.0 * p->pc7/t->tsc); 484 outp += sprintf(outp, " %6.2f", 100.0 * p->pc7/t->tsc);
485
486 /*
487 * If measurement interval exceeds minimum RAPL Joule Counter range,
488 * indicate that results are suspect by printing "**" in fraction place.
489 */
490 if (interval_float < rapl_joule_counter_range) {
491 fmt5 = " %5.2f";
492 fmt6 = " %6.2f";
493 } else {
494 fmt5 = " %3.0f**";
495 fmt6 = " %4.0f**";
496 }
497
498 if (do_rapl & RAPL_PKG)
499 outp += sprintf(outp, fmt6, p->energy_pkg * rapl_energy_units / interval_float);
500 if (do_rapl & RAPL_CORES)
501 outp += sprintf(outp, fmt6, p->energy_cores * rapl_energy_units / interval_float);
502 if (do_rapl & RAPL_GFX)
503 outp += sprintf(outp, fmt5, p->energy_gfx * rapl_energy_units / interval_float);
504 if (do_rapl & RAPL_DRAM)
505 outp += sprintf(outp, fmt5, p->energy_dram * rapl_energy_units / interval_float);
506 if (do_rapl & RAPL_PKG_PERF_STATUS )
507 outp += sprintf(outp, fmt5, 100.0 * p->rapl_pkg_perf_status * rapl_time_units / interval_float);
508 if (do_rapl & RAPL_DRAM_PERF_STATUS )
509 outp += sprintf(outp, fmt5, 100.0 * p->rapl_dram_perf_status * rapl_time_units / interval_float);
510
429done: 511done:
430 outp += sprintf(outp, "\n"); 512 outp += sprintf(outp, "\n");
431 513
@@ -435,6 +517,7 @@ done:
435void flush_stdout() 517void flush_stdout()
436{ 518{
437 fputs(output_buffer, stdout); 519 fputs(output_buffer, stdout);
520 fflush(stdout);
438 outp = output_buffer; 521 outp = output_buffer;
439} 522}
440void flush_stderr() 523void flush_stderr()
@@ -461,6 +544,13 @@ void format_all_counters(struct thread_data *t, struct core_data *c, struct pkg_
461 for_all_cpus(format_counters, t, c, p); 544 for_all_cpus(format_counters, t, c, p);
462} 545}
463 546
547#define DELTA_WRAP32(new, old) \
548 if (new > old) { \
549 old = new - old; \
550 } else { \
551 old = 0x100000000 + new - old; \
552 }
553
464void 554void
465delta_package(struct pkg_data *new, struct pkg_data *old) 555delta_package(struct pkg_data *new, struct pkg_data *old)
466{ 556{
@@ -468,6 +558,14 @@ delta_package(struct pkg_data *new, struct pkg_data *old)
468 old->pc3 = new->pc3 - old->pc3; 558 old->pc3 = new->pc3 - old->pc3;
469 old->pc6 = new->pc6 - old->pc6; 559 old->pc6 = new->pc6 - old->pc6;
470 old->pc7 = new->pc7 - old->pc7; 560 old->pc7 = new->pc7 - old->pc7;
561 old->pkg_temp_c = new->pkg_temp_c;
562
563 DELTA_WRAP32(new->energy_pkg, old->energy_pkg);
564 DELTA_WRAP32(new->energy_cores, old->energy_cores);
565 DELTA_WRAP32(new->energy_gfx, old->energy_gfx);
566 DELTA_WRAP32(new->energy_dram, old->energy_dram);
567 DELTA_WRAP32(new->rapl_pkg_perf_status, old->rapl_pkg_perf_status);
568 DELTA_WRAP32(new->rapl_dram_perf_status, old->rapl_dram_perf_status);
471} 569}
472 570
473void 571void
@@ -476,6 +574,7 @@ delta_core(struct core_data *new, struct core_data *old)
476 old->c3 = new->c3 - old->c3; 574 old->c3 = new->c3 - old->c3;
477 old->c6 = new->c6 - old->c6; 575 old->c6 = new->c6 - old->c6;
478 old->c7 = new->c7 - old->c7; 576 old->c7 = new->c7 - old->c7;
577 old->core_temp_c = new->core_temp_c;
479} 578}
480 579
481/* 580/*
@@ -582,11 +681,20 @@ void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data
582 c->c3 = 0; 681 c->c3 = 0;
583 c->c6 = 0; 682 c->c6 = 0;
584 c->c7 = 0; 683 c->c7 = 0;
684 c->core_temp_c = 0;
585 685
586 p->pc2 = 0; 686 p->pc2 = 0;
587 p->pc3 = 0; 687 p->pc3 = 0;
588 p->pc6 = 0; 688 p->pc6 = 0;
589 p->pc7 = 0; 689 p->pc7 = 0;
690
691 p->energy_pkg = 0;
692 p->energy_dram = 0;
693 p->energy_cores = 0;
694 p->energy_gfx = 0;
695 p->rapl_pkg_perf_status = 0;
696 p->rapl_dram_perf_status = 0;
697 p->pkg_temp_c = 0;
590} 698}
591int sum_counters(struct thread_data *t, struct core_data *c, 699int sum_counters(struct thread_data *t, struct core_data *c,
592 struct pkg_data *p) 700 struct pkg_data *p)
@@ -607,6 +715,8 @@ int sum_counters(struct thread_data *t, struct core_data *c,
607 average.cores.c6 += c->c6; 715 average.cores.c6 += c->c6;
608 average.cores.c7 += c->c7; 716 average.cores.c7 += c->c7;
609 717
718 average.cores.core_temp_c = MAX(average.cores.core_temp_c, c->core_temp_c);
719
610 /* sum per-pkg values only for 1st core in pkg */ 720 /* sum per-pkg values only for 1st core in pkg */
611 if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) 721 if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
612 return 0; 722 return 0;
@@ -616,6 +726,15 @@ int sum_counters(struct thread_data *t, struct core_data *c,
616 average.packages.pc6 += p->pc6; 726 average.packages.pc6 += p->pc6;
617 average.packages.pc7 += p->pc7; 727 average.packages.pc7 += p->pc7;
618 728
729 average.packages.energy_pkg += p->energy_pkg;
730 average.packages.energy_dram += p->energy_dram;
731 average.packages.energy_cores += p->energy_cores;
732 average.packages.energy_gfx += p->energy_gfx;
733
734 average.packages.pkg_temp_c = MAX(average.packages.pkg_temp_c, p->pkg_temp_c);
735
736 average.packages.rapl_pkg_perf_status += p->rapl_pkg_perf_status;
737 average.packages.rapl_dram_perf_status += p->rapl_dram_perf_status;
619 return 0; 738 return 0;
620} 739}
621/* 740/*
@@ -667,23 +786,26 @@ static unsigned long long rdtsc(void)
667int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) 786int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
668{ 787{
669 int cpu = t->cpu_id; 788 int cpu = t->cpu_id;
789 unsigned long long msr;
670 790
671 if (cpu_migrate(cpu)) 791 if (cpu_migrate(cpu)) {
792 fprintf(stderr, "Could not migrate to CPU %d\n", cpu);
672 return -1; 793 return -1;
794 }
673 795
674 t->tsc = rdtsc(); /* we are running on local CPU of interest */ 796 t->tsc = rdtsc(); /* we are running on local CPU of interest */
675 797
676 if (has_aperf) { 798 if (has_aperf) {
677 if (get_msr(cpu, MSR_APERF, &t->aperf)) 799 if (get_msr(cpu, MSR_IA32_APERF, &t->aperf))
678 return -3; 800 return -3;
679 if (get_msr(cpu, MSR_MPERF, &t->mperf)) 801 if (get_msr(cpu, MSR_IA32_MPERF, &t->mperf))
680 return -4; 802 return -4;
681 } 803 }
682 804
683 if (extra_delta_offset32) { 805 if (extra_delta_offset32) {
684 if (get_msr(cpu, extra_delta_offset32, &t->extra_delta32)) 806 if (get_msr(cpu, extra_delta_offset32, &msr))
685 return -5; 807 return -5;
686 t->extra_delta32 &= 0xFFFFFFFF; 808 t->extra_delta32 = msr & 0xFFFFFFFF;
687 } 809 }
688 810
689 if (extra_delta_offset64) 811 if (extra_delta_offset64)
@@ -691,9 +813,9 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
691 return -5; 813 return -5;
692 814
693 if (extra_msr_offset32) { 815 if (extra_msr_offset32) {
694 if (get_msr(cpu, extra_msr_offset32, &t->extra_msr32)) 816 if (get_msr(cpu, extra_msr_offset32, &msr))
695 return -5; 817 return -5;
696 t->extra_msr32 &= 0xFFFFFFFF; 818 t->extra_msr32 = msr & 0xFFFFFFFF;
697 } 819 }
698 820
699 if (extra_msr_offset64) 821 if (extra_msr_offset64)
@@ -715,6 +837,13 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
715 if (get_msr(cpu, MSR_CORE_C7_RESIDENCY, &c->c7)) 837 if (get_msr(cpu, MSR_CORE_C7_RESIDENCY, &c->c7))
716 return -8; 838 return -8;
717 839
840 if (do_dts) {
841 if (get_msr(cpu, MSR_IA32_THERM_STATUS, &msr))
842 return -9;
843 c->core_temp_c = tcc_activation_temp - ((msr >> 16) & 0x7F);
844 }
845
846
718 /* collect package counters only for 1st core in package */ 847 /* collect package counters only for 1st core in package */
719 if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) 848 if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
720 return 0; 849 return 0;
@@ -731,6 +860,41 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
731 if (get_msr(cpu, MSR_PKG_C7_RESIDENCY, &p->pc7)) 860 if (get_msr(cpu, MSR_PKG_C7_RESIDENCY, &p->pc7))
732 return -12; 861 return -12;
733 } 862 }
863 if (do_rapl & RAPL_PKG) {
864 if (get_msr(cpu, MSR_PKG_ENERGY_STATUS, &msr))
865 return -13;
866 p->energy_pkg = msr & 0xFFFFFFFF;
867 }
868 if (do_rapl & RAPL_CORES) {
869 if (get_msr(cpu, MSR_PP0_ENERGY_STATUS, &msr))
870 return -14;
871 p->energy_cores = msr & 0xFFFFFFFF;
872 }
873 if (do_rapl & RAPL_DRAM) {
874 if (get_msr(cpu, MSR_DRAM_ENERGY_STATUS, &msr))
875 return -15;
876 p->energy_dram = msr & 0xFFFFFFFF;
877 }
878 if (do_rapl & RAPL_GFX) {
879 if (get_msr(cpu, MSR_PP1_ENERGY_STATUS, &msr))
880 return -16;
881 p->energy_gfx = msr & 0xFFFFFFFF;
882 }
883 if (do_rapl & RAPL_PKG_PERF_STATUS) {
884 if (get_msr(cpu, MSR_PKG_PERF_STATUS, &msr))
885 return -16;
886 p->rapl_pkg_perf_status = msr & 0xFFFFFFFF;
887 }
888 if (do_rapl & RAPL_DRAM_PERF_STATUS) {
889 if (get_msr(cpu, MSR_DRAM_PERF_STATUS, &msr))
890 return -16;
891 p->rapl_dram_perf_status = msr & 0xFFFFFFFF;
892 }
893 if (do_ptm) {
894 if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_STATUS, &msr))
895 return -17;
896 p->pkg_temp_c = tcc_activation_temp - ((msr >> 16) & 0x7F);
897 }
734 return 0; 898 return 0;
735} 899}
736 900
@@ -742,10 +906,10 @@ void print_verbose_header(void)
742 if (!do_nehalem_platform_info) 906 if (!do_nehalem_platform_info)
743 return; 907 return;
744 908
745 get_msr(0, MSR_NEHALEM_PLATFORM_INFO, &msr); 909 get_msr(0, MSR_NHM_PLATFORM_INFO, &msr);
746 910
747 if (verbose > 1) 911 if (verbose)
748 fprintf(stderr, "MSR_NEHALEM_PLATFORM_INFO: 0x%llx\n", msr); 912 fprintf(stderr, "cpu0: MSR_NHM_PLATFORM_INFO: 0x%08llx\n", msr);
749 913
750 ratio = (msr >> 40) & 0xFF; 914 ratio = (msr >> 40) & 0xFF;
751 fprintf(stderr, "%d * %.0f = %.0f MHz max efficiency\n", 915 fprintf(stderr, "%d * %.0f = %.0f MHz max efficiency\n",
@@ -760,8 +924,8 @@ void print_verbose_header(void)
760 924
761 get_msr(0, MSR_IVT_TURBO_RATIO_LIMIT, &msr); 925 get_msr(0, MSR_IVT_TURBO_RATIO_LIMIT, &msr);
762 926
763 if (verbose > 1) 927 if (verbose)
764 fprintf(stderr, "MSR_IVT_TURBO_RATIO_LIMIT: 0x%llx\n", msr); 928 fprintf(stderr, "cpu0: MSR_IVT_TURBO_RATIO_LIMIT: 0x%08llx\n", msr);
765 929
766 ratio = (msr >> 56) & 0xFF; 930 ratio = (msr >> 56) & 0xFF;
767 if (ratio) 931 if (ratio)
@@ -804,14 +968,56 @@ void print_verbose_header(void)
804 ratio, bclk, ratio * bclk); 968 ratio, bclk, ratio * bclk);
805 969
806print_nhm_turbo_ratio_limits: 970print_nhm_turbo_ratio_limits:
971 get_msr(0, MSR_NHM_SNB_PKG_CST_CFG_CTL, &msr);
972
973#define SNB_C1_AUTO_UNDEMOTE (1UL << 27)
974#define SNB_C3_AUTO_UNDEMOTE (1UL << 28)
975
976 fprintf(stderr, "cpu0: MSR_NHM_SNB_PKG_CST_CFG_CTL: 0x%08llx", msr);
977
978 fprintf(stderr, " (%s%s%s%s%slocked: pkg-cstate-limit=%d: ",
979 (msr & SNB_C3_AUTO_UNDEMOTE) ? "UNdemote-C3, " : "",
980 (msr & SNB_C1_AUTO_UNDEMOTE) ? "UNdemote-C1, " : "",
981 (msr & NHM_C3_AUTO_DEMOTE) ? "demote-C3, " : "",
982 (msr & NHM_C1_AUTO_DEMOTE) ? "demote-C1, " : "",
983 (msr & (1 << 15)) ? "" : "UN",
984 (unsigned int)msr & 7);
985
986
987 switch(msr & 0x7) {
988 case 0:
989 fprintf(stderr, "pc0");
990 break;
991 case 1:
992 fprintf(stderr, do_snb_cstates ? "pc2" : "pc0");
993 break;
994 case 2:
995 fprintf(stderr, do_snb_cstates ? "pc6-noret" : "pc3");
996 break;
997 case 3:
998 fprintf(stderr, "pc6");
999 break;
1000 case 4:
1001 fprintf(stderr, "pc7");
1002 break;
1003 case 5:
1004 fprintf(stderr, do_snb_cstates ? "pc7s" : "invalid");
1005 break;
1006 case 7:
1007 fprintf(stderr, "unlimited");
1008 break;
1009 default:
1010 fprintf(stderr, "invalid");
1011 }
1012 fprintf(stderr, ")\n");
807 1013
808 if (!do_nehalem_turbo_ratio_limit) 1014 if (!do_nehalem_turbo_ratio_limit)
809 return; 1015 return;
810 1016
811 get_msr(0, MSR_NEHALEM_TURBO_RATIO_LIMIT, &msr); 1017 get_msr(0, MSR_NHM_TURBO_RATIO_LIMIT, &msr);
812 1018
813 if (verbose > 1) 1019 if (verbose)
814 fprintf(stderr, "MSR_NEHALEM_TURBO_RATIO_LIMIT: 0x%llx\n", msr); 1020 fprintf(stderr, "cpu0: MSR_NHM_TURBO_RATIO_LIMIT: 0x%08llx\n", msr);
815 1021
816 ratio = (msr >> 56) & 0xFF; 1022 ratio = (msr >> 56) & 0xFF;
817 if (ratio) 1023 if (ratio)
@@ -1100,15 +1306,22 @@ int mark_cpu_present(int cpu)
1100void turbostat_loop() 1306void turbostat_loop()
1101{ 1307{
1102 int retval; 1308 int retval;
1309 int restarted = 0;
1103 1310
1104restart: 1311restart:
1312 restarted++;
1313
1105 retval = for_all_cpus(get_counters, EVEN_COUNTERS); 1314 retval = for_all_cpus(get_counters, EVEN_COUNTERS);
1106 if (retval < -1) { 1315 if (retval < -1) {
1107 exit(retval); 1316 exit(retval);
1108 } else if (retval == -1) { 1317 } else if (retval == -1) {
1318 if (restarted > 1) {
1319 exit(retval);
1320 }
1109 re_initialize(); 1321 re_initialize();
1110 goto restart; 1322 goto restart;
1111 } 1323 }
1324 restarted = 0;
1112 gettimeofday(&tv_even, (struct timezone *)NULL); 1325 gettimeofday(&tv_even, (struct timezone *)NULL);
1113 1326
1114 while (1) { 1327 while (1) {
@@ -1207,6 +1420,299 @@ int has_ivt_turbo_ratio_limit(unsigned int family, unsigned int model)
1207 } 1420 }
1208} 1421}
1209 1422
1423/*
1424 * print_epb()
1425 * Decode the ENERGY_PERF_BIAS MSR
1426 */
1427int print_epb(struct thread_data *t, struct core_data *c, struct pkg_data *p)
1428{
1429 unsigned long long msr;
1430 char *epb_string;
1431 int cpu;
1432
1433 if (!has_epb)
1434 return 0;
1435
1436 cpu = t->cpu_id;
1437
1438 /* EPB is per-package */
1439 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
1440 return 0;
1441
1442 if (cpu_migrate(cpu)) {
1443 fprintf(stderr, "Could not migrate to CPU %d\n", cpu);
1444 return -1;
1445 }
1446
1447 if (get_msr(cpu, MSR_IA32_ENERGY_PERF_BIAS, &msr))
1448 return 0;
1449
1450 switch (msr & 0x7) {
1451 case ENERGY_PERF_BIAS_PERFORMANCE:
1452 epb_string = "performance";
1453 break;
1454 case ENERGY_PERF_BIAS_NORMAL:
1455 epb_string = "balanced";
1456 break;
1457 case ENERGY_PERF_BIAS_POWERSAVE:
1458 epb_string = "powersave";
1459 break;
1460 default:
1461 epb_string = "custom";
1462 break;
1463 }
1464 fprintf(stderr, "cpu%d: MSR_IA32_ENERGY_PERF_BIAS: 0x%08llx (%s)\n", cpu, msr, epb_string);
1465
1466 return 0;
1467}
1468
1469#define RAPL_POWER_GRANULARITY 0x7FFF /* 15 bit power granularity */
1470#define RAPL_TIME_GRANULARITY 0x3F /* 6 bit time granularity */
1471
1472/*
1473 * rapl_probe()
1474 *
1475 * sets do_rapl
1476 */
1477void rapl_probe(unsigned int family, unsigned int model)
1478{
1479 unsigned long long msr;
1480 double tdp;
1481
1482 if (!genuine_intel)
1483 return;
1484
1485 if (family != 6)
1486 return;
1487
1488 switch (model) {
1489 case 0x2A:
1490 case 0x3A:
1491 do_rapl = RAPL_PKG | RAPL_CORES | RAPL_GFX;
1492 break;
1493 case 0x2D:
1494 case 0x3E:
1495 do_rapl = RAPL_PKG | RAPL_CORES | RAPL_DRAM | RAPL_PKG_PERF_STATUS | RAPL_DRAM_PERF_STATUS;
1496 break;
1497 default:
1498 return;
1499 }
1500
1501 /* units on package 0, verify later other packages match */
1502 if (get_msr(0, MSR_RAPL_POWER_UNIT, &msr))
1503 return;
1504
1505 rapl_power_units = 1.0 / (1 << (msr & 0xF));
1506 rapl_energy_units = 1.0 / (1 << (msr >> 8 & 0x1F));
1507 rapl_time_units = 1.0 / (1 << (msr >> 16 & 0xF));
1508
1509 /* get TDP to determine energy counter range */
1510 if (get_msr(0, MSR_PKG_POWER_INFO, &msr))
1511 return;
1512
1513 tdp = ((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units;
1514
1515 rapl_joule_counter_range = 0xFFFFFFFF * rapl_energy_units / tdp;
1516
1517 if (verbose)
1518 fprintf(stderr, "RAPL: %.0f sec. Joule Counter Range\n", rapl_joule_counter_range);
1519
1520 return;
1521}
1522
1523int print_thermal(struct thread_data *t, struct core_data *c, struct pkg_data *p)
1524{
1525 unsigned long long msr;
1526 unsigned int dts;
1527 int cpu;
1528
1529 if (!(do_dts || do_ptm))
1530 return 0;
1531
1532 cpu = t->cpu_id;
1533
1534 /* DTS is per-core, no need to print for each thread */
1535 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
1536 return 0;
1537
1538 if (cpu_migrate(cpu)) {
1539 fprintf(stderr, "Could not migrate to CPU %d\n", cpu);
1540 return -1;
1541 }
1542
1543 if (do_ptm && (t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) {
1544 if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_STATUS, &msr))
1545 return 0;
1546
1547 dts = (msr >> 16) & 0x7F;
1548 fprintf(stderr, "cpu%d: MSR_IA32_PACKAGE_THERM_STATUS: 0x%08llx (%d C)\n",
1549 cpu, msr, tcc_activation_temp - dts);
1550
1551#ifdef THERM_DEBUG
1552 if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT, &msr))
1553 return 0;
1554
1555 dts = (msr >> 16) & 0x7F;
1556 dts2 = (msr >> 8) & 0x7F;
1557 fprintf(stderr, "cpu%d: MSR_IA32_PACKAGE_THERM_INTERRUPT: 0x%08llx (%d C, %d C)\n",
1558 cpu, msr, tcc_activation_temp - dts, tcc_activation_temp - dts2);
1559#endif
1560 }
1561
1562
1563 if (do_dts) {
1564 unsigned int resolution;
1565
1566 if (get_msr(cpu, MSR_IA32_THERM_STATUS, &msr))
1567 return 0;
1568
1569 dts = (msr >> 16) & 0x7F;
1570 resolution = (msr >> 27) & 0xF;
1571 fprintf(stderr, "cpu%d: MSR_IA32_THERM_STATUS: 0x%08llx (%d C +/- %d)\n",
1572 cpu, msr, tcc_activation_temp - dts, resolution);
1573
1574#ifdef THERM_DEBUG
1575 if (get_msr(cpu, MSR_IA32_THERM_INTERRUPT, &msr))
1576 return 0;
1577
1578 dts = (msr >> 16) & 0x7F;
1579 dts2 = (msr >> 8) & 0x7F;
1580 fprintf(stderr, "cpu%d: MSR_IA32_THERM_INTERRUPT: 0x%08llx (%d C, %d C)\n",
1581 cpu, msr, tcc_activation_temp - dts, tcc_activation_temp - dts2);
1582#endif
1583 }
1584
1585 return 0;
1586}
1587
1588void print_power_limit_msr(int cpu, unsigned long long msr, char *label)
1589{
1590 fprintf(stderr, "cpu%d: %s: %sabled (%f Watts, %f sec, clamp %sabled)\n",
1591 cpu, label,
1592 ((msr >> 15) & 1) ? "EN" : "DIS",
1593 ((msr >> 0) & 0x7FFF) * rapl_power_units,
1594 (1.0 + (((msr >> 22) & 0x3)/4.0)) * (1 << ((msr >> 17) & 0x1F)) * rapl_time_units,
1595 (((msr >> 16) & 1) ? "EN" : "DIS"));
1596
1597 return;
1598}
1599
1600int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p)
1601{
1602 unsigned long long msr;
1603 int cpu;
1604 double local_rapl_power_units, local_rapl_energy_units, local_rapl_time_units;
1605
1606 if (!do_rapl)
1607 return 0;
1608
1609 /* RAPL counters are per package, so print only for 1st thread/package */
1610 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
1611 return 0;
1612
1613 cpu = t->cpu_id;
1614 if (cpu_migrate(cpu)) {
1615 fprintf(stderr, "Could not migrate to CPU %d\n", cpu);
1616 return -1;
1617 }
1618
1619 if (get_msr(cpu, MSR_RAPL_POWER_UNIT, &msr))
1620 return -1;
1621
1622 local_rapl_power_units = 1.0 / (1 << (msr & 0xF));
1623 local_rapl_energy_units = 1.0 / (1 << (msr >> 8 & 0x1F));
1624 local_rapl_time_units = 1.0 / (1 << (msr >> 16 & 0xF));
1625
1626 if (local_rapl_power_units != rapl_power_units)
1627 fprintf(stderr, "cpu%d, ERROR: Power units mis-match\n", cpu);
1628 if (local_rapl_energy_units != rapl_energy_units)
1629 fprintf(stderr, "cpu%d, ERROR: Energy units mis-match\n", cpu);
1630 if (local_rapl_time_units != rapl_time_units)
1631 fprintf(stderr, "cpu%d, ERROR: Time units mis-match\n", cpu);
1632
1633 if (verbose) {
1634 fprintf(stderr, "cpu%d: MSR_RAPL_POWER_UNIT: 0x%08llx "
1635 "(%f Watts, %f Joules, %f sec.)\n", cpu, msr,
1636 local_rapl_power_units, local_rapl_energy_units, local_rapl_time_units);
1637 }
1638 if (do_rapl & RAPL_PKG) {
1639 if (get_msr(cpu, MSR_PKG_POWER_INFO, &msr))
1640 return -5;
1641
1642
1643 fprintf(stderr, "cpu%d: MSR_PKG_POWER_INFO: 0x%08llx (%.0f W TDP, RAPL %.0f - %.0f W, %f sec.)\n",
1644 cpu, msr,
1645 ((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units,
1646 ((msr >> 16) & RAPL_POWER_GRANULARITY) * rapl_power_units,
1647 ((msr >> 32) & RAPL_POWER_GRANULARITY) * rapl_power_units,
1648 ((msr >> 48) & RAPL_TIME_GRANULARITY) * rapl_time_units);
1649
1650 if (get_msr(cpu, MSR_PKG_POWER_LIMIT, &msr))
1651 return -9;
1652
1653 fprintf(stderr, "cpu%d: MSR_PKG_POWER_LIMIT: 0x%08llx (%slocked)\n",
1654 cpu, msr, (msr >> 63) & 1 ? "": "UN");
1655
1656 print_power_limit_msr(cpu, msr, "PKG Limit #1");
1657 fprintf(stderr, "cpu%d: PKG Limit #2: %sabled (%f Watts, %f* sec, clamp %sabled)\n",
1658 cpu,
1659 ((msr >> 47) & 1) ? "EN" : "DIS",
1660 ((msr >> 32) & 0x7FFF) * rapl_power_units,
1661 (1.0 + (((msr >> 54) & 0x3)/4.0)) * (1 << ((msr >> 49) & 0x1F)) * rapl_time_units,
1662 ((msr >> 48) & 1) ? "EN" : "DIS");
1663 }
1664
1665 if (do_rapl & RAPL_DRAM) {
1666 if (get_msr(cpu, MSR_DRAM_POWER_INFO, &msr))
1667 return -6;
1668
1669
1670 fprintf(stderr, "cpu%d: MSR_DRAM_POWER_INFO,: 0x%08llx (%.0f W TDP, RAPL %.0f - %.0f W, %f sec.)\n",
1671 cpu, msr,
1672 ((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units,
1673 ((msr >> 16) & RAPL_POWER_GRANULARITY) * rapl_power_units,
1674 ((msr >> 32) & RAPL_POWER_GRANULARITY) * rapl_power_units,
1675 ((msr >> 48) & RAPL_TIME_GRANULARITY) * rapl_time_units);
1676
1677
1678 if (get_msr(cpu, MSR_DRAM_POWER_LIMIT, &msr))
1679 return -9;
1680 fprintf(stderr, "cpu%d: MSR_DRAM_POWER_LIMIT: 0x%08llx (%slocked)\n",
1681 cpu, msr, (msr >> 31) & 1 ? "": "UN");
1682
1683 print_power_limit_msr(cpu, msr, "DRAM Limit");
1684 }
1685 if (do_rapl & RAPL_CORES) {
1686 if (verbose) {
1687 if (get_msr(cpu, MSR_PP0_POLICY, &msr))
1688 return -7;
1689
1690 fprintf(stderr, "cpu%d: MSR_PP0_POLICY: %lld\n", cpu, msr & 0xF);
1691
1692 if (get_msr(cpu, MSR_PP0_POWER_LIMIT, &msr))
1693 return -9;
1694 fprintf(stderr, "cpu%d: MSR_PP0_POWER_LIMIT: 0x%08llx (%slocked)\n",
1695 cpu, msr, (msr >> 31) & 1 ? "": "UN");
1696 print_power_limit_msr(cpu, msr, "Cores Limit");
1697 }
1698 }
1699 if (do_rapl & RAPL_GFX) {
1700 if (verbose) {
1701 if (get_msr(cpu, MSR_PP1_POLICY, &msr))
1702 return -8;
1703
1704 fprintf(stderr, "cpu%d: MSR_PP1_POLICY: %lld\n", cpu, msr & 0xF);
1705
1706 if (get_msr(cpu, MSR_PP1_POWER_LIMIT, &msr))
1707 return -9;
1708 fprintf(stderr, "cpu%d: MSR_PP1_POWER_LIMIT: 0x%08llx (%slocked)\n",
1709 cpu, msr, (msr >> 31) & 1 ? "": "UN");
1710 print_power_limit_msr(cpu, msr, "GFX Limit");
1711 }
1712 }
1713 return 0;
1714}
1715
1210 1716
1211int is_snb(unsigned int family, unsigned int model) 1717int is_snb(unsigned int family, unsigned int model)
1212{ 1718{
@@ -1231,6 +1737,72 @@ double discover_bclk(unsigned int family, unsigned int model)
1231 return 133.33; 1737 return 133.33;
1232} 1738}
1233 1739
1740/*
1741 * MSR_IA32_TEMPERATURE_TARGET indicates the temperature where
1742 * the Thermal Control Circuit (TCC) activates.
1743 * This is usually equal to tjMax.
1744 *
1745 * Older processors do not have this MSR, so there we guess,
1746 * but also allow cmdline over-ride with -T.
1747 *
1748 * Several MSR temperature values are in units of degrees-C
1749 * below this value, including the Digital Thermal Sensor (DTS),
1750 * Package Thermal Management Sensor (PTM), and thermal event thresholds.
1751 */
1752int set_temperature_target(struct thread_data *t, struct core_data *c, struct pkg_data *p)
1753{
1754 unsigned long long msr;
1755 unsigned int target_c_local;
1756 int cpu;
1757
1758 /* tcc_activation_temp is used only for dts or ptm */
1759 if (!(do_dts || do_ptm))
1760 return 0;
1761
1762 /* this is a per-package concept */
1763 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
1764 return 0;
1765
1766 cpu = t->cpu_id;
1767 if (cpu_migrate(cpu)) {
1768 fprintf(stderr, "Could not migrate to CPU %d\n", cpu);
1769 return -1;
1770 }
1771
1772 if (tcc_activation_temp_override != 0) {
1773 tcc_activation_temp = tcc_activation_temp_override;
1774 fprintf(stderr, "cpu%d: Using cmdline TCC Target (%d C)\n",
1775 cpu, tcc_activation_temp);
1776 return 0;
1777 }
1778
1779 /* Temperature Target MSR is Nehalem and newer only */
1780 if (!do_nehalem_platform_info)
1781 goto guess;
1782
1783 if (get_msr(0, MSR_IA32_TEMPERATURE_TARGET, &msr))
1784 goto guess;
1785
1786 target_c_local = (msr >> 16) & 0x7F;
1787
1788 if (verbose)
1789 fprintf(stderr, "cpu%d: MSR_IA32_TEMPERATURE_TARGET: 0x%08llx (%d C)\n",
1790 cpu, msr, target_c_local);
1791
1792 if (target_c_local < 85 || target_c_local > 120)
1793 goto guess;
1794
1795 tcc_activation_temp = target_c_local;
1796
1797 return 0;
1798
1799guess:
1800 tcc_activation_temp = TJMAX_DEFAULT;
1801 fprintf(stderr, "cpu%d: Guessing tjMax %d C, Please use -T to specify\n",
1802 cpu, tcc_activation_temp);
1803
1804 return 0;
1805}
1234void check_cpuid() 1806void check_cpuid()
1235{ 1807{
1236 unsigned int eax, ebx, ecx, edx, max_level; 1808 unsigned int eax, ebx, ecx, edx, max_level;
@@ -1244,7 +1816,7 @@ void check_cpuid()
1244 genuine_intel = 1; 1816 genuine_intel = 1;
1245 1817
1246 if (verbose) 1818 if (verbose)
1247 fprintf(stderr, "%.4s%.4s%.4s ", 1819 fprintf(stderr, "CPUID(0): %.4s%.4s%.4s ",
1248 (char *)&ebx, (char *)&edx, (char *)&ecx); 1820 (char *)&ebx, (char *)&edx, (char *)&ecx);
1249 1821
1250 asm("cpuid" : "=a" (fms), "=c" (ecx), "=d" (edx) : "a" (1) : "ebx"); 1822 asm("cpuid" : "=a" (fms), "=c" (ecx), "=d" (edx) : "a" (1) : "ebx");
@@ -1295,10 +1867,19 @@ void check_cpuid()
1295 1867
1296 asm("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (0x6)); 1868 asm("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (0x6));
1297 has_aperf = ecx & (1 << 0); 1869 has_aperf = ecx & (1 << 0);
1298 if (!has_aperf) { 1870 do_dts = eax & (1 << 0);
1299 fprintf(stderr, "No APERF MSR\n"); 1871 do_ptm = eax & (1 << 6);
1300 exit(1); 1872 has_epb = ecx & (1 << 3);
1301 } 1873
1874 if (verbose)
1875 fprintf(stderr, "CPUID(6): %s%s%s%s\n",
1876 has_aperf ? "APERF" : "No APERF!",
1877 do_dts ? ", DTS" : "",
1878 do_ptm ? ", PTM": "",
1879 has_epb ? ", EPB": "");
1880
1881 if (!has_aperf)
1882 exit(-1);
1302 1883
1303 do_nehalem_platform_info = genuine_intel && has_invariant_tsc; 1884 do_nehalem_platform_info = genuine_intel && has_invariant_tsc;
1304 do_nhm_cstates = genuine_intel; /* all Intel w/ non-stop TSC have NHM counters */ 1885 do_nhm_cstates = genuine_intel; /* all Intel w/ non-stop TSC have NHM counters */
@@ -1307,12 +1888,15 @@ void check_cpuid()
1307 1888
1308 do_nehalem_turbo_ratio_limit = has_nehalem_turbo_ratio_limit(family, model); 1889 do_nehalem_turbo_ratio_limit = has_nehalem_turbo_ratio_limit(family, model);
1309 do_ivt_turbo_ratio_limit = has_ivt_turbo_ratio_limit(family, model); 1890 do_ivt_turbo_ratio_limit = has_ivt_turbo_ratio_limit(family, model);
1891 rapl_probe(family, model);
1892
1893 return;
1310} 1894}
1311 1895
1312 1896
1313void usage() 1897void usage()
1314{ 1898{
1315 fprintf(stderr, "%s: [-v][-p|-P|-S][-c MSR# | -s]][-C MSR#][-m MSR#][-M MSR#][-i interval_sec | command ...]\n", 1899 fprintf(stderr, "%s: [-v][-R][-T][-p|-P|-S][-c MSR# | -s]][-C MSR#][-m MSR#][-M MSR#][-i interval_sec | command ...]\n",
1316 progname); 1900 progname);
1317 exit(1); 1901 exit(1);
1318} 1902}
@@ -1548,6 +2132,17 @@ void turbostat_init()
1548 2132
1549 if (verbose) 2133 if (verbose)
1550 print_verbose_header(); 2134 print_verbose_header();
2135
2136 if (verbose)
2137 for_all_cpus(print_epb, ODD_COUNTERS);
2138
2139 if (verbose)
2140 for_all_cpus(print_rapl, ODD_COUNTERS);
2141
2142 for_all_cpus(set_temperature_target, ODD_COUNTERS);
2143
2144 if (verbose)
2145 for_all_cpus(print_thermal, ODD_COUNTERS);
1551} 2146}
1552 2147
1553int fork_it(char **argv) 2148int fork_it(char **argv)
@@ -1604,7 +2199,7 @@ void cmdline(int argc, char **argv)
1604 2199
1605 progname = argv[0]; 2200 progname = argv[0];
1606 2201
1607 while ((opt = getopt(argc, argv, "+pPSvi:sc:sC:m:M:")) != -1) { 2202 while ((opt = getopt(argc, argv, "+pPSvi:sc:sC:m:M:RT:")) != -1) {
1608 switch (opt) { 2203 switch (opt) {
1609 case 'p': 2204 case 'p':
1610 show_core_only++; 2205 show_core_only++;
@@ -1636,6 +2231,12 @@ void cmdline(int argc, char **argv)
1636 case 'M': 2231 case 'M':
1637 sscanf(optarg, "%x", &extra_msr_offset64); 2232 sscanf(optarg, "%x", &extra_msr_offset64);
1638 break; 2233 break;
2234 case 'R':
2235 rapl_verbose++;
2236 break;
2237 case 'T':
2238 tcc_activation_temp_override = atoi(optarg);
2239 break;
1639 default: 2240 default:
1640 usage(); 2241 usage();
1641 } 2242 }
@@ -1646,8 +2247,8 @@ int main(int argc, char **argv)
1646{ 2247{
1647 cmdline(argc, argv); 2248 cmdline(argc, argv);
1648 2249
1649 if (verbose > 1) 2250 if (verbose)
1650 fprintf(stderr, "turbostat v2.1 October 6, 2012" 2251 fprintf(stderr, "turbostat v3.0 November 23, 2012"
1651 " - Len Brown <lenb@kernel.org>\n"); 2252 " - Len Brown <lenb@kernel.org>\n");
1652 2253
1653 turbostat_init(); 2254 turbostat_init();
diff --git a/tools/power/x86/x86_energy_perf_policy/Makefile b/tools/power/x86/x86_energy_perf_policy/Makefile
index f458237fdd79..971c9ffdcb50 100644
--- a/tools/power/x86/x86_energy_perf_policy/Makefile
+++ b/tools/power/x86/x86_energy_perf_policy/Makefile
@@ -1,8 +1,10 @@
1DESTDIR ?=
2
1x86_energy_perf_policy : x86_energy_perf_policy.c 3x86_energy_perf_policy : x86_energy_perf_policy.c
2 4
3clean : 5clean :
4 rm -f x86_energy_perf_policy 6 rm -f x86_energy_perf_policy
5 7
6install : 8install :
7 install x86_energy_perf_policy /usr/bin/ 9 install x86_energy_perf_policy ${DESTDIR}/usr/bin/
8 install x86_energy_perf_policy.8 /usr/share/man/man8/ 10 install x86_energy_perf_policy.8 ${DESTDIR}/usr/share/man/man8/
diff --git a/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c b/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c
index 33c5c7ee148f..40b3e5482f8a 100644
--- a/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c
+++ b/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c
@@ -289,7 +289,7 @@ void for_every_cpu(void (func)(int))
289 "cpu%u %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n", 289 "cpu%u %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n",
290 &cpu); 290 &cpu);
291 if (retval != 1) 291 if (retval != 1)
292 return; 292 break;
293 293
294 func(cpu); 294 func(cpu);
295 } 295 }
diff --git a/tools/testing/selftests/ipc/Makefile b/tools/testing/selftests/ipc/Makefile
new file mode 100644
index 000000000000..5386fd7c43ae
--- /dev/null
+++ b/tools/testing/selftests/ipc/Makefile
@@ -0,0 +1,25 @@
1uname_M := $(shell uname -m 2>/dev/null || echo not)
2ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/)
3ifeq ($(ARCH),i386)
4 ARCH := X86
5 CFLAGS := -DCONFIG_X86_32 -D__i386__
6endif
7ifeq ($(ARCH),x86_64)
8 ARCH := X86
9 CFLAGS := -DCONFIG_X86_64 -D__x86_64__
10endif
11
12CFLAGS += -I../../../../usr/include/
13
14all:
15ifeq ($(ARCH),X86)
16 gcc $(CFLAGS) msgque.c -o msgque_test
17else
18 echo "Not an x86 target, can't build msgque selftest"
19endif
20
21run_tests: all
22 ./msgque_test
23
24clean:
25 rm -fr ./msgque_test
diff --git a/tools/testing/selftests/ipc/msgque.c b/tools/testing/selftests/ipc/msgque.c
new file mode 100644
index 000000000000..d66418237d21
--- /dev/null
+++ b/tools/testing/selftests/ipc/msgque.c
@@ -0,0 +1,246 @@
1#include <stdlib.h>
2#include <stdio.h>
3#include <string.h>
4#include <errno.h>
5#include <linux/msg.h>
6#include <fcntl.h>
7
8#define MAX_MSG_SIZE 32
9
10struct msg1 {
11 int msize;
12 long mtype;
13 char mtext[MAX_MSG_SIZE];
14};
15
16#define TEST_STRING "Test sysv5 msg"
17#define MSG_TYPE 1
18
19#define ANOTHER_TEST_STRING "Yet another test sysv5 msg"
20#define ANOTHER_MSG_TYPE 26538
21
22struct msgque_data {
23 key_t key;
24 int msq_id;
25 int qbytes;
26 int qnum;
27 int mode;
28 struct msg1 *messages;
29};
30
31int restore_queue(struct msgque_data *msgque)
32{
33 int fd, ret, id, i;
34 char buf[32];
35
36 fd = open("/proc/sys/kernel/msg_next_id", O_WRONLY);
37 if (fd == -1) {
38 printf("Failed to open /proc/sys/kernel/msg_next_id\n");
39 return -errno;
40 }
41 sprintf(buf, "%d", msgque->msq_id);
42
43 ret = write(fd, buf, strlen(buf));
44 if (ret != strlen(buf)) {
45 printf("Failed to write to /proc/sys/kernel/msg_next_id\n");
46 return -errno;
47 }
48
49 id = msgget(msgque->key, msgque->mode | IPC_CREAT | IPC_EXCL);
50 if (id == -1) {
51 printf("Failed to create queue\n");
52 return -errno;
53 }
54
55 if (id != msgque->msq_id) {
56 printf("Restored queue has wrong id (%d instead of %d)\n",
57 id, msgque->msq_id);
58 ret = -EFAULT;
59 goto destroy;
60 }
61
62 for (i = 0; i < msgque->qnum; i++) {
63 if (msgsnd(msgque->msq_id, &msgque->messages[i].mtype,
64 msgque->messages[i].msize, IPC_NOWAIT) != 0) {
65 printf("msgsnd failed (%m)\n");
66 ret = -errno;
67 goto destroy;
68 };
69 }
70 return 0;
71
72destroy:
73 if (msgctl(id, IPC_RMID, 0))
74 printf("Failed to destroy queue: %d\n", -errno);
75 return ret;
76}
77
78int check_and_destroy_queue(struct msgque_data *msgque)
79{
80 struct msg1 message;
81 int cnt = 0, ret;
82
83 while (1) {
84 ret = msgrcv(msgque->msq_id, &message.mtype, MAX_MSG_SIZE,
85 0, IPC_NOWAIT);
86 if (ret < 0) {
87 if (errno == ENOMSG)
88 break;
89 printf("Failed to read IPC message: %m\n");
90 ret = -errno;
91 goto err;
92 }
93 if (ret != msgque->messages[cnt].msize) {
94 printf("Wrong message size: %d (expected %d)\n", ret,
95 msgque->messages[cnt].msize);
96 ret = -EINVAL;
97 goto err;
98 }
99 if (message.mtype != msgque->messages[cnt].mtype) {
100 printf("Wrong message type\n");
101 ret = -EINVAL;
102 goto err;
103 }
104 if (memcmp(message.mtext, msgque->messages[cnt].mtext, ret)) {
105 printf("Wrong message content\n");
106 ret = -EINVAL;
107 goto err;
108 }
109 cnt++;
110 }
111
112 if (cnt != msgque->qnum) {
113 printf("Wrong message number\n");
114 ret = -EINVAL;
115 goto err;
116 }
117
118 ret = 0;
119err:
120 if (msgctl(msgque->msq_id, IPC_RMID, 0)) {
121 printf("Failed to destroy queue: %d\n", -errno);
122 return -errno;
123 }
124 return ret;
125}
126
127int dump_queue(struct msgque_data *msgque)
128{
129 struct msqid64_ds ds;
130 int kern_id;
131 int i, ret;
132
133 for (kern_id = 0; kern_id < 256; kern_id++) {
134 ret = msgctl(kern_id, MSG_STAT, &ds);
135 if (ret < 0) {
136 if (errno == -EINVAL)
137 continue;
138 printf("Failed to get stats for IPC queue with id %d\n",
139 kern_id);
140 return -errno;
141 }
142
143 if (ret == msgque->msq_id)
144 break;
145 }
146
147 msgque->messages = malloc(sizeof(struct msg1) * ds.msg_qnum);
148 if (msgque->messages == NULL) {
149 printf("Failed to get stats for IPC queue\n");
150 return -ENOMEM;
151 }
152
153 msgque->qnum = ds.msg_qnum;
154 msgque->mode = ds.msg_perm.mode;
155 msgque->qbytes = ds.msg_qbytes;
156
157 for (i = 0; i < msgque->qnum; i++) {
158 ret = msgrcv(msgque->msq_id, &msgque->messages[i].mtype,
159 MAX_MSG_SIZE, i, IPC_NOWAIT | MSG_COPY);
160 if (ret < 0) {
161 printf("Failed to copy IPC message: %m (%d)\n", errno);
162 return -errno;
163 }
164 msgque->messages[i].msize = ret;
165 }
166 return 0;
167}
168
169int fill_msgque(struct msgque_data *msgque)
170{
171 struct msg1 msgbuf;
172
173 msgbuf.mtype = MSG_TYPE;
174 memcpy(msgbuf.mtext, TEST_STRING, sizeof(TEST_STRING));
175 if (msgsnd(msgque->msq_id, &msgbuf.mtype, sizeof(TEST_STRING),
176 IPC_NOWAIT) != 0) {
177 printf("First message send failed (%m)\n");
178 return -errno;
179 };
180
181 msgbuf.mtype = ANOTHER_MSG_TYPE;
182 memcpy(msgbuf.mtext, ANOTHER_TEST_STRING, sizeof(ANOTHER_TEST_STRING));
183 if (msgsnd(msgque->msq_id, &msgbuf.mtype, sizeof(ANOTHER_TEST_STRING),
184 IPC_NOWAIT) != 0) {
185 printf("Second message send failed (%m)\n");
186 return -errno;
187 };
188 return 0;
189}
190
191int main(int argc, char **argv)
192{
193 int msg, pid, err;
194 struct msgque_data msgque;
195
196 msgque.key = ftok(argv[0], 822155650);
197 if (msgque.key == -1) {
198 printf("Can't make key\n");
199 return -errno;
200 }
201
202 msgque.msq_id = msgget(msgque.key, IPC_CREAT | IPC_EXCL | 0666);
203 if (msgque.msq_id == -1) {
204 printf("Can't create queue\n");
205 goto err_out;
206 }
207
208 err = fill_msgque(&msgque);
209 if (err) {
210 printf("Failed to fill queue\n");
211 goto err_destroy;
212 }
213
214 err = dump_queue(&msgque);
215 if (err) {
216 printf("Failed to dump queue\n");
217 goto err_destroy;
218 }
219
220 err = check_and_destroy_queue(&msgque);
221 if (err) {
222 printf("Failed to check and destroy queue\n");
223 goto err_out;
224 }
225
226 err = restore_queue(&msgque);
227 if (err) {
228 printf("Failed to restore queue\n");
229 goto err_destroy;
230 }
231
232 err = check_and_destroy_queue(&msgque);
233 if (err) {
234 printf("Failed to test queue\n");
235 goto err_out;
236 }
237 return 0;
238
239err_destroy:
240 if (msgctl(msgque.msq_id, IPC_RMID, 0)) {
241 printf("Failed to destroy queue: %d\n", -errno);
242 return -errno;
243 }
244err_out:
245 return err;
246}
diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c
index 6d25dcd2e97a..fcc9aa25fd08 100644
--- a/tools/virtio/virtio_test.c
+++ b/tools/virtio/virtio_test.c
@@ -164,7 +164,7 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq,
164 r = virtqueue_add_buf(vq->vq, &sl, 1, 0, 164 r = virtqueue_add_buf(vq->vq, &sl, 1, 0,
165 dev->buf + started, 165 dev->buf + started,
166 GFP_ATOMIC); 166 GFP_ATOMIC);
167 if (likely(r >= 0)) { 167 if (likely(r == 0)) {
168 ++started; 168 ++started;
169 virtqueue_kick(vq->vq); 169 virtqueue_kick(vq->vq);
170 } 170 }
@@ -177,7 +177,7 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq,
177 r = 0; 177 r = 0;
178 } 178 }
179 179
180 } while (r >= 0); 180 } while (r == 0);
181 if (completed == completed_before) 181 if (completed == completed_before)
182 ++spurious; 182 ++spurious;
183 assert(completed <= bufs); 183 assert(completed <= bufs);