aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2013-07-23 05:48:17 -0400
committerIngo Molnar <mingo@kernel.org>2013-07-23 05:48:17 -0400
commitb59f2b4d30c187160df597bae41cabe497b6acf4 (patch)
treee29ed9e3cbaf777cc1a10c99c4542985002d2c88 /tools
parent1e40c2edef2537f87f94d0baf80aeaeb7d51cc23 (diff)
parent3b2f64d00c46e1e4e9bd0bb9bb12619adac27a4b (diff)
Merge tag 'v3.11-rc2' into core/locking
Merge in Linux 3.11-rc2 before moving on with new work. Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools')
-rw-r--r--tools/include/tools/be_byteshift.h34
-rw-r--r--tools/include/tools/le_byteshift.h34
-rw-r--r--tools/lguest/Makefile1
-rw-r--r--tools/lguest/lguest.c32
-rw-r--r--tools/lib/lk/Makefile17
-rw-r--r--tools/perf/Documentation/Makefile12
-rw-r--r--tools/perf/Documentation/examples.txt4
-rw-r--r--tools/perf/Documentation/perf-record.txt8
-rw-r--r--tools/perf/Makefile5
-rw-r--r--tools/perf/bench/mem-memcpy.c4
-rw-r--r--tools/perf/bench/mem-memset.c2
-rw-r--r--tools/perf/builtin-diff.c1
-rw-r--r--tools/perf/builtin-kmem.c2
-rw-r--r--tools/perf/builtin-lock.c2
-rw-r--r--tools/perf/builtin-record.c85
-rw-r--r--tools/perf/builtin-report.c3
-rw-r--r--tools/perf/builtin-sched.c1
-rw-r--r--tools/perf/builtin-stat.c30
-rw-r--r--tools/perf/builtin-timechart.c4
-rw-r--r--tools/perf/builtin-top.c2
-rw-r--r--tools/perf/config/Makefile6
-rw-r--r--tools/perf/config/utilities.mak4
-rw-r--r--tools/perf/scripts/perl/Perf-Trace-Util/Context.xs2
-rwxr-xr-xtools/perf/util/PERF-VERSION-GEN21
-rw-r--r--tools/perf/util/dso.c10
-rw-r--r--tools/perf/util/dso.h3
-rw-r--r--tools/perf/util/evlist.c10
-rw-r--r--tools/perf/util/evsel.c4
-rw-r--r--tools/perf/util/header.c15
-rw-r--r--tools/perf/util/parse-events.c4
-rw-r--r--tools/perf/util/symbol.c1
-rw-r--r--tools/perf/util/util.h2
-rw-r--r--tools/perf/util/vdso.c2
-rw-r--r--tools/power/cpupower/Makefile4
-rw-r--r--tools/power/cpupower/man/cpupower-monitor.110
-rw-r--r--tools/power/cpupower/utils/builtin.h1
-rw-r--r--tools/power/cpupower/utils/cpuidle-info.c24
-rw-r--r--tools/power/cpupower/utils/cpuidle-set.c118
-rw-r--r--tools/power/cpupower/utils/cpupower.c13
-rw-r--r--tools/power/cpupower/utils/helpers/sysfs.c118
-rw-r--r--tools/power/cpupower/utils/helpers/sysfs.h10
-rw-r--r--tools/power/cpupower/utils/idle_monitor/hsw_ext_idle.c196
-rw-r--r--tools/power/cpupower/utils/idle_monitor/idle_monitors.def1
-rw-r--r--tools/power/cpupower/utils/idle_monitor/snb_idle.c4
-rw-r--r--tools/scripts/Makefile.include2
-rw-r--r--tools/testing/selftests/net/psock_tpacket.c59
-rw-r--r--tools/virtio/linux/module.h5
-rw-r--r--tools/virtio/linux/virtio.h3
48 files changed, 673 insertions, 262 deletions
diff --git a/tools/include/tools/be_byteshift.h b/tools/include/tools/be_byteshift.h
index f4912e2668ba..84c17d836578 100644
--- a/tools/include/tools/be_byteshift.h
+++ b/tools/include/tools/be_byteshift.h
@@ -1,68 +1,68 @@
1#ifndef _TOOLS_BE_BYTESHIFT_H 1#ifndef _TOOLS_BE_BYTESHIFT_H
2#define _TOOLS_BE_BYTESHIFT_H 2#define _TOOLS_BE_BYTESHIFT_H
3 3
4#include <linux/types.h> 4#include <stdint.h>
5 5
6static inline __u16 __get_unaligned_be16(const __u8 *p) 6static inline uint16_t __get_unaligned_be16(const uint8_t *p)
7{ 7{
8 return p[0] << 8 | p[1]; 8 return p[0] << 8 | p[1];
9} 9}
10 10
11static inline __u32 __get_unaligned_be32(const __u8 *p) 11static inline uint32_t __get_unaligned_be32(const uint8_t *p)
12{ 12{
13 return p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]; 13 return p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
14} 14}
15 15
16static inline __u64 __get_unaligned_be64(const __u8 *p) 16static inline uint64_t __get_unaligned_be64(const uint8_t *p)
17{ 17{
18 return (__u64)__get_unaligned_be32(p) << 32 | 18 return (uint64_t)__get_unaligned_be32(p) << 32 |
19 __get_unaligned_be32(p + 4); 19 __get_unaligned_be32(p + 4);
20} 20}
21 21
22static inline void __put_unaligned_be16(__u16 val, __u8 *p) 22static inline void __put_unaligned_be16(uint16_t val, uint8_t *p)
23{ 23{
24 *p++ = val >> 8; 24 *p++ = val >> 8;
25 *p++ = val; 25 *p++ = val;
26} 26}
27 27
28static inline void __put_unaligned_be32(__u32 val, __u8 *p) 28static inline void __put_unaligned_be32(uint32_t val, uint8_t *p)
29{ 29{
30 __put_unaligned_be16(val >> 16, p); 30 __put_unaligned_be16(val >> 16, p);
31 __put_unaligned_be16(val, p + 2); 31 __put_unaligned_be16(val, p + 2);
32} 32}
33 33
34static inline void __put_unaligned_be64(__u64 val, __u8 *p) 34static inline void __put_unaligned_be64(uint64_t val, uint8_t *p)
35{ 35{
36 __put_unaligned_be32(val >> 32, p); 36 __put_unaligned_be32(val >> 32, p);
37 __put_unaligned_be32(val, p + 4); 37 __put_unaligned_be32(val, p + 4);
38} 38}
39 39
40static inline __u16 get_unaligned_be16(const void *p) 40static inline uint16_t get_unaligned_be16(const void *p)
41{ 41{
42 return __get_unaligned_be16((const __u8 *)p); 42 return __get_unaligned_be16((const uint8_t *)p);
43} 43}
44 44
45static inline __u32 get_unaligned_be32(const void *p) 45static inline uint32_t get_unaligned_be32(const void *p)
46{ 46{
47 return __get_unaligned_be32((const __u8 *)p); 47 return __get_unaligned_be32((const uint8_t *)p);
48} 48}
49 49
50static inline __u64 get_unaligned_be64(const void *p) 50static inline uint64_t get_unaligned_be64(const void *p)
51{ 51{
52 return __get_unaligned_be64((const __u8 *)p); 52 return __get_unaligned_be64((const uint8_t *)p);
53} 53}
54 54
55static inline void put_unaligned_be16(__u16 val, void *p) 55static inline void put_unaligned_be16(uint16_t val, void *p)
56{ 56{
57 __put_unaligned_be16(val, p); 57 __put_unaligned_be16(val, p);
58} 58}
59 59
60static inline void put_unaligned_be32(__u32 val, void *p) 60static inline void put_unaligned_be32(uint32_t val, void *p)
61{ 61{
62 __put_unaligned_be32(val, p); 62 __put_unaligned_be32(val, p);
63} 63}
64 64
65static inline void put_unaligned_be64(__u64 val, void *p) 65static inline void put_unaligned_be64(uint64_t val, void *p)
66{ 66{
67 __put_unaligned_be64(val, p); 67 __put_unaligned_be64(val, p);
68} 68}
diff --git a/tools/include/tools/le_byteshift.h b/tools/include/tools/le_byteshift.h
index c99d45a68bda..8fe9f2488ec7 100644
--- a/tools/include/tools/le_byteshift.h
+++ b/tools/include/tools/le_byteshift.h
@@ -1,68 +1,68 @@
1#ifndef _TOOLS_LE_BYTESHIFT_H 1#ifndef _TOOLS_LE_BYTESHIFT_H
2#define _TOOLS_LE_BYTESHIFT_H 2#define _TOOLS_LE_BYTESHIFT_H
3 3
4#include <linux/types.h> 4#include <stdint.h>
5 5
6static inline __u16 __get_unaligned_le16(const __u8 *p) 6static inline uint16_t __get_unaligned_le16(const uint8_t *p)
7{ 7{
8 return p[0] | p[1] << 8; 8 return p[0] | p[1] << 8;
9} 9}
10 10
11static inline __u32 __get_unaligned_le32(const __u8 *p) 11static inline uint32_t __get_unaligned_le32(const uint8_t *p)
12{ 12{
13 return p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24; 13 return p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24;
14} 14}
15 15
16static inline __u64 __get_unaligned_le64(const __u8 *p) 16static inline uint64_t __get_unaligned_le64(const uint8_t *p)
17{ 17{
18 return (__u64)__get_unaligned_le32(p + 4) << 32 | 18 return (uint64_t)__get_unaligned_le32(p + 4) << 32 |
19 __get_unaligned_le32(p); 19 __get_unaligned_le32(p);
20} 20}
21 21
22static inline void __put_unaligned_le16(__u16 val, __u8 *p) 22static inline void __put_unaligned_le16(uint16_t val, uint8_t *p)
23{ 23{
24 *p++ = val; 24 *p++ = val;
25 *p++ = val >> 8; 25 *p++ = val >> 8;
26} 26}
27 27
28static inline void __put_unaligned_le32(__u32 val, __u8 *p) 28static inline void __put_unaligned_le32(uint32_t val, uint8_t *p)
29{ 29{
30 __put_unaligned_le16(val >> 16, p + 2); 30 __put_unaligned_le16(val >> 16, p + 2);
31 __put_unaligned_le16(val, p); 31 __put_unaligned_le16(val, p);
32} 32}
33 33
34static inline void __put_unaligned_le64(__u64 val, __u8 *p) 34static inline void __put_unaligned_le64(uint64_t val, uint8_t *p)
35{ 35{
36 __put_unaligned_le32(val >> 32, p + 4); 36 __put_unaligned_le32(val >> 32, p + 4);
37 __put_unaligned_le32(val, p); 37 __put_unaligned_le32(val, p);
38} 38}
39 39
40static inline __u16 get_unaligned_le16(const void *p) 40static inline uint16_t get_unaligned_le16(const void *p)
41{ 41{
42 return __get_unaligned_le16((const __u8 *)p); 42 return __get_unaligned_le16((const uint8_t *)p);
43} 43}
44 44
45static inline __u32 get_unaligned_le32(const void *p) 45static inline uint32_t get_unaligned_le32(const void *p)
46{ 46{
47 return __get_unaligned_le32((const __u8 *)p); 47 return __get_unaligned_le32((const uint8_t *)p);
48} 48}
49 49
50static inline __u64 get_unaligned_le64(const void *p) 50static inline uint64_t get_unaligned_le64(const void *p)
51{ 51{
52 return __get_unaligned_le64((const __u8 *)p); 52 return __get_unaligned_le64((const uint8_t *)p);
53} 53}
54 54
55static inline void put_unaligned_le16(__u16 val, void *p) 55static inline void put_unaligned_le16(uint16_t val, void *p)
56{ 56{
57 __put_unaligned_le16(val, p); 57 __put_unaligned_le16(val, p);
58} 58}
59 59
60static inline void put_unaligned_le32(__u32 val, void *p) 60static inline void put_unaligned_le32(uint32_t val, void *p)
61{ 61{
62 __put_unaligned_le32(val, p); 62 __put_unaligned_le32(val, p);
63} 63}
64 64
65static inline void put_unaligned_le64(__u64 val, void *p) 65static inline void put_unaligned_le64(uint64_t val, void *p)
66{ 66{
67 __put_unaligned_le64(val, p); 67 __put_unaligned_le64(val, p);
68} 68}
diff --git a/tools/lguest/Makefile b/tools/lguest/Makefile
index 0ac34206f7a7..97bca4871ea3 100644
--- a/tools/lguest/Makefile
+++ b/tools/lguest/Makefile
@@ -1,5 +1,4 @@
1# This creates the demonstration utility "lguest" which runs a Linux guest. 1# This creates the demonstration utility "lguest" which runs a Linux guest.
2# Missing headers? Add "-I../../../include -I../../../arch/x86/include"
3CFLAGS:=-m32 -Wall -Wmissing-declarations -Wmissing-prototypes -O3 -U_FORTIFY_SOURCE 2CFLAGS:=-m32 -Wall -Wmissing-declarations -Wmissing-prototypes -O3 -U_FORTIFY_SOURCE
4 3
5all: lguest 4all: lguest
diff --git a/tools/lguest/lguest.c b/tools/lguest/lguest.c
index 07a03452c227..68f67cf3d318 100644
--- a/tools/lguest/lguest.c
+++ b/tools/lguest/lguest.c
@@ -42,14 +42,6 @@
42#include <pwd.h> 42#include <pwd.h>
43#include <grp.h> 43#include <grp.h>
44 44
45#include <linux/virtio_config.h>
46#include <linux/virtio_net.h>
47#include <linux/virtio_blk.h>
48#include <linux/virtio_console.h>
49#include <linux/virtio_rng.h>
50#include <linux/virtio_ring.h>
51#include <asm/bootparam.h>
52#include "../../include/linux/lguest_launcher.h"
53/*L:110 45/*L:110
54 * We can ignore the 43 include files we need for this program, but I do want 46 * We can ignore the 43 include files we need for this program, but I do want
55 * to draw attention to the use of kernel-style types. 47 * to draw attention to the use of kernel-style types.
@@ -65,6 +57,15 @@ typedef uint16_t u16;
65typedef uint8_t u8; 57typedef uint8_t u8;
66/*:*/ 58/*:*/
67 59
60#include <linux/virtio_config.h>
61#include <linux/virtio_net.h>
62#include <linux/virtio_blk.h>
63#include <linux/virtio_console.h>
64#include <linux/virtio_rng.h>
65#include <linux/virtio_ring.h>
66#include <asm/bootparam.h>
67#include "../../include/linux/lguest_launcher.h"
68
68#define BRIDGE_PFX "bridge:" 69#define BRIDGE_PFX "bridge:"
69#ifndef SIOCBRADDIF 70#ifndef SIOCBRADDIF
70#define SIOCBRADDIF 0x89a2 /* add interface to bridge */ 71#define SIOCBRADDIF 0x89a2 /* add interface to bridge */
@@ -177,7 +178,8 @@ static struct termios orig_term;
177 * in precise order. 178 * in precise order.
178 */ 179 */
179#define wmb() __asm__ __volatile__("" : : : "memory") 180#define wmb() __asm__ __volatile__("" : : : "memory")
180#define mb() __asm__ __volatile__("" : : : "memory") 181#define rmb() __asm__ __volatile__("lock; addl $0,0(%%esp)" : : : "memory")
182#define mb() __asm__ __volatile__("lock; addl $0,0(%%esp)" : : : "memory")
181 183
182/* Wrapper for the last available index. Makes it easier to change. */ 184/* Wrapper for the last available index. Makes it easier to change. */
183#define lg_last_avail(vq) ((vq)->last_avail_idx) 185#define lg_last_avail(vq) ((vq)->last_avail_idx)
@@ -676,6 +678,12 @@ static unsigned wait_for_vq_desc(struct virtqueue *vq,
676 errx(1, "Guest moved used index from %u to %u", 678 errx(1, "Guest moved used index from %u to %u",
677 last_avail, vq->vring.avail->idx); 679 last_avail, vq->vring.avail->idx);
678 680
681 /*
682 * Make sure we read the descriptor number *after* we read the ring
683 * update; don't let the cpu or compiler change the order.
684 */
685 rmb();
686
679 /* 687 /*
680 * Grab the next descriptor number they're advertising, and increment 688 * Grab the next descriptor number they're advertising, and increment
681 * the index we've seen. 689 * the index we've seen.
@@ -695,6 +703,12 @@ static unsigned wait_for_vq_desc(struct virtqueue *vq,
695 i = head; 703 i = head;
696 704
697 /* 705 /*
706 * We have to read the descriptor after we read the descriptor number,
707 * but there's a data dependency there so the CPU shouldn't reorder
708 * that: no rmb() required.
709 */
710
711 /*
698 * If this is an indirect entry, then this buffer contains a descriptor 712 * If this is an indirect entry, then this buffer contains a descriptor
699 * table which we handle as if it's any normal descriptor chain. 713 * table which we handle as if it's any normal descriptor chain.
700 */ 714 */
diff --git a/tools/lib/lk/Makefile b/tools/lib/lk/Makefile
index 2c5a19733357..280dd8205430 100644
--- a/tools/lib/lk/Makefile
+++ b/tools/lib/lk/Makefile
@@ -3,6 +3,21 @@ include ../../scripts/Makefile.include
3CC = $(CROSS_COMPILE)gcc 3CC = $(CROSS_COMPILE)gcc
4AR = $(CROSS_COMPILE)ar 4AR = $(CROSS_COMPILE)ar
5 5
6# Makefiles suck: This macro sets a default value of $(2) for the
7# variable named by $(1), unless the variable has been set by
8# environment or command line. This is necessary for CC and AR
9# because make sets default values, so the simpler ?= approach
10# won't work as expected.
11define allow-override
12 $(if $(or $(findstring environment,$(origin $(1))),\
13 $(findstring command line,$(origin $(1)))),,\
14 $(eval $(1) = $(2)))
15endef
16
17# Allow setting CC and AR, or setting CROSS_COMPILE as a prefix.
18$(call allow-override,CC,$(CROSS_COMPILE)gcc)
19$(call allow-override,AR,$(CROSS_COMPILE)ar)
20
6# guard against environment variables 21# guard against environment variables
7LIB_H= 22LIB_H=
8LIB_OBJS= 23LIB_OBJS=
@@ -14,7 +29,7 @@ LIB_OBJS += $(OUTPUT)debugfs.o
14LIBFILE = liblk.a 29LIBFILE = liblk.a
15 30
16CFLAGS = -ggdb3 -Wall -Wextra -std=gnu99 -Werror -O6 -D_FORTIFY_SOURCE=2 $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) -fPIC 31CFLAGS = -ggdb3 -Wall -Wextra -std=gnu99 -Werror -O6 -D_FORTIFY_SOURCE=2 $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) -fPIC
17EXTLIBS = -lpthread -lrt -lelf -lm 32EXTLIBS = -lelf -lpthread -lrt -lm
18ALL_CFLAGS = $(CFLAGS) $(BASIC_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 33ALL_CFLAGS = $(CFLAGS) $(BASIC_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
19ALL_LDFLAGS = $(LDFLAGS) 34ALL_LDFLAGS = $(LDFLAGS)
20 35
diff --git a/tools/perf/Documentation/Makefile b/tools/perf/Documentation/Makefile
index eb30044a922a..5a37a7c84e69 100644
--- a/tools/perf/Documentation/Makefile
+++ b/tools/perf/Documentation/Makefile
@@ -1,12 +1,6 @@
1include ../../scripts/Makefile.include
1include ../config/utilities.mak 2include ../config/utilities.mak
2 3
3OUTPUT := ./
4ifeq ("$(origin O)", "command line")
5 ifneq ($(O),)
6 OUTPUT := $(O)/
7 endif
8endif
9
10MAN1_TXT= \ 4MAN1_TXT= \
11 $(filter-out $(addsuffix .txt, $(ARTICLES) $(SP_ARTICLES)), \ 5 $(filter-out $(addsuffix .txt, $(ARTICLES) $(SP_ARTICLES)), \
12 $(wildcard perf-*.txt)) \ 6 $(wildcard perf-*.txt)) \
@@ -150,7 +144,7 @@ NO_SUBDIR = :
150endif 144endif
151 145
152ifneq ($(findstring $(MAKEFLAGS),s),s) 146ifneq ($(findstring $(MAKEFLAGS),s),s)
153ifndef V 147ifneq ($(V),1)
154 QUIET_ASCIIDOC = @echo ' ' ASCIIDOC $@; 148 QUIET_ASCIIDOC = @echo ' ' ASCIIDOC $@;
155 QUIET_XMLTO = @echo ' ' XMLTO $@; 149 QUIET_XMLTO = @echo ' ' XMLTO $@;
156 QUIET_DB2TEXI = @echo ' ' DB2TEXI $@; 150 QUIET_DB2TEXI = @echo ' ' DB2TEXI $@;
@@ -277,7 +271,7 @@ $(MAN_HTML): $(OUTPUT)%.html : %.txt
277 271
278$(OUTPUT)%.1 $(OUTPUT)%.5 $(OUTPUT)%.7 : $(OUTPUT)%.xml 272$(OUTPUT)%.1 $(OUTPUT)%.5 $(OUTPUT)%.7 : $(OUTPUT)%.xml
279 $(QUIET_XMLTO)$(RM) $@ && \ 273 $(QUIET_XMLTO)$(RM) $@ && \
280 $(XMLTO) -o $(OUTPUT) -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $< 274 $(XMLTO) -o $(OUTPUT). -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $<
281 275
282$(OUTPUT)%.xml : %.txt 276$(OUTPUT)%.xml : %.txt
283 $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \ 277 $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \
diff --git a/tools/perf/Documentation/examples.txt b/tools/perf/Documentation/examples.txt
index 77f952762426..a4e392156488 100644
--- a/tools/perf/Documentation/examples.txt
+++ b/tools/perf/Documentation/examples.txt
@@ -66,7 +66,7 @@ Furthermore, these tracepoints can be used to sample the workload as
66well. For example the page allocations done by a 'git gc' can be 66well. For example the page allocations done by a 'git gc' can be
67captured the following way: 67captured the following way:
68 68
69 titan:~/git> perf record -f -e kmem:mm_page_alloc -c 1 ./git gc 69 titan:~/git> perf record -e kmem:mm_page_alloc -c 1 ./git gc
70 Counting objects: 1148, done. 70 Counting objects: 1148, done.
71 Delta compression using up to 2 threads. 71 Delta compression using up to 2 threads.
72 Compressing objects: 100% (450/450), done. 72 Compressing objects: 100% (450/450), done.
@@ -120,7 +120,7 @@ Furthermore, call-graph sampling can be done too, of page
120allocations - to see precisely what kind of page allocations there 120allocations - to see precisely what kind of page allocations there
121are: 121are:
122 122
123 titan:~/git> perf record -f -g -e kmem:mm_page_alloc -c 1 ./git gc 123 titan:~/git> perf record -g -e kmem:mm_page_alloc -c 1 ./git gc
124 Counting objects: 1148, done. 124 Counting objects: 1148, done.
125 Delta compression using up to 2 threads. 125 Delta compression using up to 2 threads.
126 Compressing objects: 100% (450/450), done. 126 Compressing objects: 100% (450/450), done.
diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
index d4da111ef53d..e297b74471b8 100644
--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -65,16 +65,10 @@ OPTIONS
65-r:: 65-r::
66--realtime=:: 66--realtime=::
67 Collect data with this RT SCHED_FIFO priority. 67 Collect data with this RT SCHED_FIFO priority.
68
68-D:: 69-D::
69--no-delay:: 70--no-delay::
70 Collect data without buffering. 71 Collect data without buffering.
71-A::
72--append::
73 Append to the output file to do incremental profiling.
74
75-f::
76--force::
77 Overwrite existing data file. (deprecated)
78 72
79-c:: 73-c::
80--count=:: 74--count=::
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 203cb0eecff2..641fccddb249 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -121,17 +121,16 @@ SCRIPT_SH += perf-archive.sh
121grep-libs = $(filter -l%,$(1)) 121grep-libs = $(filter -l%,$(1))
122strip-libs = $(filter-out -l%,$(1)) 122strip-libs = $(filter-out -l%,$(1))
123 123
124LK_PATH=$(LK_DIR)
125
126ifneq ($(OUTPUT),) 124ifneq ($(OUTPUT),)
127 TE_PATH=$(OUTPUT) 125 TE_PATH=$(OUTPUT)
128ifneq ($(subdir),) 126ifneq ($(subdir),)
129 LK_PATH=$(OUTPUT)$(LK_DIR) 127 LK_PATH=$(objtree)/lib/lk/
130else 128else
131 LK_PATH=$(OUTPUT) 129 LK_PATH=$(OUTPUT)
132endif 130endif
133else 131else
134 TE_PATH=$(TRACE_EVENT_DIR) 132 TE_PATH=$(TRACE_EVENT_DIR)
133 LK_PATH=$(LK_DIR)
135endif 134endif
136 135
137LIBTRACEEVENT = $(TE_PATH)libtraceevent.a 136LIBTRACEEVENT = $(TE_PATH)libtraceevent.a
diff --git a/tools/perf/bench/mem-memcpy.c b/tools/perf/bench/mem-memcpy.c
index 93c83e3cb4a7..25fd3f1966f1 100644
--- a/tools/perf/bench/mem-memcpy.c
+++ b/tools/perf/bench/mem-memcpy.c
@@ -111,11 +111,11 @@ static double timeval2double(struct timeval *ts)
111static void alloc_mem(void **dst, void **src, size_t length) 111static void alloc_mem(void **dst, void **src, size_t length)
112{ 112{
113 *dst = zalloc(length); 113 *dst = zalloc(length);
114 if (!dst) 114 if (!*dst)
115 die("memory allocation failed - maybe length is too large?\n"); 115 die("memory allocation failed - maybe length is too large?\n");
116 116
117 *src = zalloc(length); 117 *src = zalloc(length);
118 if (!src) 118 if (!*src)
119 die("memory allocation failed - maybe length is too large?\n"); 119 die("memory allocation failed - maybe length is too large?\n");
120} 120}
121 121
diff --git a/tools/perf/bench/mem-memset.c b/tools/perf/bench/mem-memset.c
index c6e4bc523492..4a2f12081964 100644
--- a/tools/perf/bench/mem-memset.c
+++ b/tools/perf/bench/mem-memset.c
@@ -111,7 +111,7 @@ static double timeval2double(struct timeval *ts)
111static void alloc_mem(void **dst, size_t length) 111static void alloc_mem(void **dst, size_t length)
112{ 112{
113 *dst = zalloc(length); 113 *dst = zalloc(length);
114 if (!dst) 114 if (!*dst)
115 die("memory allocation failed - maybe length is too large?\n"); 115 die("memory allocation failed - maybe length is too large?\n");
116} 116}
117 117
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index da8f8eb383a0..0aac5f3e594d 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -607,7 +607,6 @@ int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused)
607 input_new = "perf.data.guest"; 607 input_new = "perf.data.guest";
608 } 608 }
609 609
610 symbol_conf.exclude_other = false;
611 if (symbol__init() < 0) 610 if (symbol__init() < 0)
612 return -1; 611 return -1;
613 612
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index 46878daca5cc..0259502638b4 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -708,7 +708,7 @@ static int parse_line_opt(const struct option *opt __maybe_unused,
708static int __cmd_record(int argc, const char **argv) 708static int __cmd_record(int argc, const char **argv)
709{ 709{
710 const char * const record_args[] = { 710 const char * const record_args[] = {
711 "record", "-a", "-R", "-f", "-c", "1", 711 "record", "-a", "-R", "-c", "1",
712 "-e", "kmem:kmalloc", 712 "-e", "kmem:kmalloc",
713 "-e", "kmem:kmalloc_node", 713 "-e", "kmem:kmalloc_node",
714 "-e", "kmem:kfree", 714 "-e", "kmem:kfree",
diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c
index 425830069749..76543a4a7a30 100644
--- a/tools/perf/builtin-lock.c
+++ b/tools/perf/builtin-lock.c
@@ -878,7 +878,7 @@ static int __cmd_report(void)
878static int __cmd_record(int argc, const char **argv) 878static int __cmd_record(int argc, const char **argv)
879{ 879{
880 const char *record_args[] = { 880 const char *record_args[] = {
881 "record", "-R", "-f", "-m", "1024", "-c", "1", 881 "record", "-R", "-m", "1024", "-c", "1",
882 }; 882 };
883 unsigned int rec_argc, i, j; 883 unsigned int rec_argc, i, j;
884 const char **rec_argv; 884 const char **rec_argv;
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index fff985cf3852..ecca62e27b28 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -61,11 +61,6 @@ static void __handle_on_exit_funcs(void)
61} 61}
62#endif 62#endif
63 63
64enum write_mode_t {
65 WRITE_FORCE,
66 WRITE_APPEND
67};
68
69struct perf_record { 64struct perf_record {
70 struct perf_tool tool; 65 struct perf_tool tool;
71 struct perf_record_opts opts; 66 struct perf_record_opts opts;
@@ -77,12 +72,8 @@ struct perf_record {
77 int output; 72 int output;
78 unsigned int page_size; 73 unsigned int page_size;
79 int realtime_prio; 74 int realtime_prio;
80 enum write_mode_t write_mode;
81 bool no_buildid; 75 bool no_buildid;
82 bool no_buildid_cache; 76 bool no_buildid_cache;
83 bool force;
84 bool file_new;
85 bool append_file;
86 long samples; 77 long samples;
87 off_t post_processing_offset; 78 off_t post_processing_offset;
88}; 79};
@@ -200,25 +191,6 @@ static void perf_record__sig_exit(int exit_status __maybe_unused, void *arg)
200 signal(signr, SIG_DFL); 191 signal(signr, SIG_DFL);
201} 192}
202 193
203static bool perf_evlist__equal(struct perf_evlist *evlist,
204 struct perf_evlist *other)
205{
206 struct perf_evsel *pos, *pair;
207
208 if (evlist->nr_entries != other->nr_entries)
209 return false;
210
211 pair = perf_evlist__first(other);
212
213 list_for_each_entry(pos, &evlist->entries, node) {
214 if (memcmp(&pos->attr, &pair->attr, sizeof(pos->attr) != 0))
215 return false;
216 pair = perf_evsel__next(pair);
217 }
218
219 return true;
220}
221
222static int perf_record__open(struct perf_record *rec) 194static int perf_record__open(struct perf_record *rec)
223{ 195{
224 char msg[512]; 196 char msg[512];
@@ -273,16 +245,7 @@ try_again:
273 goto out; 245 goto out;
274 } 246 }
275 247
276 if (rec->file_new) 248 session->evlist = evlist;
277 session->evlist = evlist;
278 else {
279 if (!perf_evlist__equal(session->evlist, evlist)) {
280 fprintf(stderr, "incompatible append\n");
281 rc = -1;
282 goto out;
283 }
284 }
285
286 perf_session__set_id_hdr_size(session); 249 perf_session__set_id_hdr_size(session);
287out: 250out:
288 return rc; 251 return rc;
@@ -415,23 +378,15 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
415 if (!strcmp(output_name, "-")) 378 if (!strcmp(output_name, "-"))
416 opts->pipe_output = true; 379 opts->pipe_output = true;
417 else if (!stat(output_name, &st) && st.st_size) { 380 else if (!stat(output_name, &st) && st.st_size) {
418 if (rec->write_mode == WRITE_FORCE) { 381 char oldname[PATH_MAX];
419 char oldname[PATH_MAX]; 382 snprintf(oldname, sizeof(oldname), "%s.old",
420 snprintf(oldname, sizeof(oldname), "%s.old", 383 output_name);
421 output_name); 384 unlink(oldname);
422 unlink(oldname); 385 rename(output_name, oldname);
423 rename(output_name, oldname);
424 }
425 } else if (rec->write_mode == WRITE_APPEND) {
426 rec->write_mode = WRITE_FORCE;
427 } 386 }
428 } 387 }
429 388
430 flags = O_CREAT|O_RDWR; 389 flags = O_CREAT|O_RDWR|O_TRUNC;
431 if (rec->write_mode == WRITE_APPEND)
432 rec->file_new = 0;
433 else
434 flags |= O_TRUNC;
435 390
436 if (opts->pipe_output) 391 if (opts->pipe_output)
437 output = STDOUT_FILENO; 392 output = STDOUT_FILENO;
@@ -445,7 +400,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
445 rec->output = output; 400 rec->output = output;
446 401
447 session = perf_session__new(output_name, O_WRONLY, 402 session = perf_session__new(output_name, O_WRONLY,
448 rec->write_mode == WRITE_FORCE, false, NULL); 403 true, false, NULL);
449 if (session == NULL) { 404 if (session == NULL) {
450 pr_err("Not enough memory for reading perf file header\n"); 405 pr_err("Not enough memory for reading perf file header\n");
451 return -1; 406 return -1;
@@ -465,12 +420,6 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
465 if (!rec->opts.branch_stack) 420 if (!rec->opts.branch_stack)
466 perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK); 421 perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK);
467 422
468 if (!rec->file_new) {
469 err = perf_session__read_header(session, output);
470 if (err < 0)
471 goto out_delete_session;
472 }
473
474 if (forks) { 423 if (forks) {
475 err = perf_evlist__prepare_workload(evsel_list, &opts->target, 424 err = perf_evlist__prepare_workload(evsel_list, &opts->target,
476 argv, opts->pipe_output, 425 argv, opts->pipe_output,
@@ -498,7 +447,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
498 err = perf_header__write_pipe(output); 447 err = perf_header__write_pipe(output);
499 if (err < 0) 448 if (err < 0)
500 goto out_delete_session; 449 goto out_delete_session;
501 } else if (rec->file_new) { 450 } else {
502 err = perf_session__write_header(session, evsel_list, 451 err = perf_session__write_header(session, evsel_list,
503 output, false); 452 output, false);
504 if (err < 0) 453 if (err < 0)
@@ -869,8 +818,6 @@ static struct perf_record record = {
869 .uses_mmap = true, 818 .uses_mmap = true,
870 }, 819 },
871 }, 820 },
872 .write_mode = WRITE_FORCE,
873 .file_new = true,
874}; 821};
875 822
876#define CALLCHAIN_HELP "do call-graph (stack chain/backtrace) recording: " 823#define CALLCHAIN_HELP "do call-graph (stack chain/backtrace) recording: "
@@ -906,12 +853,8 @@ const struct option record_options[] = {
906 "collect raw sample records from all opened counters"), 853 "collect raw sample records from all opened counters"),
907 OPT_BOOLEAN('a', "all-cpus", &record.opts.target.system_wide, 854 OPT_BOOLEAN('a', "all-cpus", &record.opts.target.system_wide,
908 "system-wide collection from all CPUs"), 855 "system-wide collection from all CPUs"),
909 OPT_BOOLEAN('A', "append", &record.append_file,
910 "append to the output file to do incremental profiling"),
911 OPT_STRING('C', "cpu", &record.opts.target.cpu_list, "cpu", 856 OPT_STRING('C', "cpu", &record.opts.target.cpu_list, "cpu",
912 "list of cpus to monitor"), 857 "list of cpus to monitor"),
913 OPT_BOOLEAN('f', "force", &record.force,
914 "overwrite existing data file (deprecated)"),
915 OPT_U64('c', "count", &record.opts.user_interval, "event period to sample"), 858 OPT_U64('c', "count", &record.opts.user_interval, "event period to sample"),
916 OPT_STRING('o', "output", &record.output_name, "file", 859 OPT_STRING('o', "output", &record.output_name, "file",
917 "output file name"), 860 "output file name"),
@@ -977,16 +920,6 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
977 if (!argc && perf_target__none(&rec->opts.target)) 920 if (!argc && perf_target__none(&rec->opts.target))
978 usage_with_options(record_usage, record_options); 921 usage_with_options(record_usage, record_options);
979 922
980 if (rec->force && rec->append_file) {
981 ui__error("Can't overwrite and append at the same time."
982 " You need to choose between -f and -A");
983 usage_with_options(record_usage, record_options);
984 } else if (rec->append_file) {
985 rec->write_mode = WRITE_APPEND;
986 } else {
987 rec->write_mode = WRITE_FORCE;
988 }
989
990 if (nr_cgroups && !rec->opts.target.system_wide) { 923 if (nr_cgroups && !rec->opts.target.system_wide) {
991 ui__error("cgroup monitoring only available in" 924 ui__error("cgroup monitoring only available in"
992 " system-wide mode\n"); 925 " system-wide mode\n");
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index ca98d34cd58b..3662047cc6b1 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -939,8 +939,7 @@ repeat:
939 */ 939 */
940 if (!strstr(sort_order, "parent")) 940 if (!strstr(sort_order, "parent"))
941 sort_parent.elide = 1; 941 sort_parent.elide = 1;
942 } else 942 }
943 symbol_conf.exclude_other = false;
944 943
945 if (argc) { 944 if (argc) {
946 /* 945 /*
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 2da2a6ca22bf..fed9ae432c16 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -1632,7 +1632,6 @@ static int __cmd_record(int argc, const char **argv)
1632 "record", 1632 "record",
1633 "-a", 1633 "-a",
1634 "-R", 1634 "-R",
1635 "-f",
1636 "-m", "1024", 1635 "-m", "1024",
1637 "-c", "1", 1636 "-c", "1",
1638 "-e", "sched:sched_switch", 1637 "-e", "sched:sched_switch",
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 7e910bab1097..352fbd7ff4a1 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -87,7 +87,7 @@ static int run_count = 1;
87static bool no_inherit = false; 87static bool no_inherit = false;
88static bool scale = true; 88static bool scale = true;
89static enum aggr_mode aggr_mode = AGGR_GLOBAL; 89static enum aggr_mode aggr_mode = AGGR_GLOBAL;
90static pid_t child_pid = -1; 90static volatile pid_t child_pid = -1;
91static bool null_run = false; 91static bool null_run = false;
92static int detailed_run = 0; 92static int detailed_run = 0;
93static bool big_num = true; 93static bool big_num = true;
@@ -924,7 +924,7 @@ static void abs_printout(int cpu, int nr, struct perf_evsel *evsel, double avg)
924static void print_aggr(char *prefix) 924static void print_aggr(char *prefix)
925{ 925{
926 struct perf_evsel *counter; 926 struct perf_evsel *counter;
927 int cpu, s, s2, id, nr; 927 int cpu, cpu2, s, s2, id, nr;
928 u64 ena, run, val; 928 u64 ena, run, val;
929 929
930 if (!(aggr_map || aggr_get_id)) 930 if (!(aggr_map || aggr_get_id))
@@ -936,7 +936,8 @@ static void print_aggr(char *prefix)
936 val = ena = run = 0; 936 val = ena = run = 0;
937 nr = 0; 937 nr = 0;
938 for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) { 938 for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
939 s2 = aggr_get_id(evsel_list->cpus, cpu); 939 cpu2 = perf_evsel__cpus(counter)->map[cpu];
940 s2 = aggr_get_id(evsel_list->cpus, cpu2);
940 if (s2 != id) 941 if (s2 != id)
941 continue; 942 continue;
942 val += counter->counts->cpu[cpu].val; 943 val += counter->counts->cpu[cpu].val;
@@ -948,7 +949,7 @@ static void print_aggr(char *prefix)
948 fprintf(output, "%s", prefix); 949 fprintf(output, "%s", prefix);
949 950
950 if (run == 0 || ena == 0) { 951 if (run == 0 || ena == 0) {
951 aggr_printout(counter, cpu, nr); 952 aggr_printout(counter, id, nr);
952 953
953 fprintf(output, "%*s%s%*s", 954 fprintf(output, "%*s%s%*s",
954 csv_output ? 0 : 18, 955 csv_output ? 0 : 18,
@@ -1148,13 +1149,34 @@ static void skip_signal(int signo)
1148 done = 1; 1149 done = 1;
1149 1150
1150 signr = signo; 1151 signr = signo;
1152 /*
1153 * render child_pid harmless
1154 * won't send SIGTERM to a random
1155 * process in case of race condition
1156 * and fast PID recycling
1157 */
1158 child_pid = -1;
1151} 1159}
1152 1160
1153static void sig_atexit(void) 1161static void sig_atexit(void)
1154{ 1162{
1163 sigset_t set, oset;
1164
1165 /*
1166 * avoid race condition with SIGCHLD handler
1167 * in skip_signal() which is modifying child_pid
1168 * goal is to avoid send SIGTERM to a random
1169 * process
1170 */
1171 sigemptyset(&set);
1172 sigaddset(&set, SIGCHLD);
1173 sigprocmask(SIG_BLOCK, &set, &oset);
1174
1155 if (child_pid != -1) 1175 if (child_pid != -1)
1156 kill(child_pid, SIGTERM); 1176 kill(child_pid, SIGTERM);
1157 1177
1178 sigprocmask(SIG_SETMASK, &oset, NULL);
1179
1158 if (signr == -1) 1180 if (signr == -1)
1159 return; 1181 return;
1160 1182
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index ab4cf232b852..4536a92b18f3 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -1005,7 +1005,7 @@ static int __cmd_record(int argc, const char **argv)
1005{ 1005{
1006#ifdef SUPPORT_OLD_POWER_EVENTS 1006#ifdef SUPPORT_OLD_POWER_EVENTS
1007 const char * const record_old_args[] = { 1007 const char * const record_old_args[] = {
1008 "record", "-a", "-R", "-f", "-c", "1", 1008 "record", "-a", "-R", "-c", "1",
1009 "-e", "power:power_start", 1009 "-e", "power:power_start",
1010 "-e", "power:power_end", 1010 "-e", "power:power_end",
1011 "-e", "power:power_frequency", 1011 "-e", "power:power_frequency",
@@ -1014,7 +1014,7 @@ static int __cmd_record(int argc, const char **argv)
1014 }; 1014 };
1015#endif 1015#endif
1016 const char * const record_new_args[] = { 1016 const char * const record_new_args[] = {
1017 "record", "-a", "-R", "-f", "-c", "1", 1017 "record", "-a", "-R", "-c", "1",
1018 "-e", "power:cpu_frequency", 1018 "-e", "power:cpu_frequency",
1019 "-e", "power:cpu_idle", 1019 "-e", "power:cpu_idle",
1020 "-e", "sched:sched_wakeup", 1020 "-e", "sched:sched_wakeup",
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index f036af9b6f09..e06c4f869330 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -1130,8 +1130,6 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
1130 if (top.evlist == NULL) 1130 if (top.evlist == NULL)
1131 return -ENOMEM; 1131 return -ENOMEM;
1132 1132
1133 symbol_conf.exclude_other = false;
1134
1135 argc = parse_options(argc, argv, options, top_usage, 0); 1133 argc = parse_options(argc, argv, options, top_usage, 0);
1136 if (argc) 1134 if (argc)
1137 usage_with_options(top_usage, options); 1135 usage_with_options(top_usage, options);
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index f139dcd2796e..b5d9238cb181 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -39,7 +39,7 @@ src-perf := $(srctree)/tools/perf
39endif 39endif
40 40
41ifeq ($(obj-perf),) 41ifeq ($(obj-perf),)
42obj-perf := $(objtree) 42obj-perf := $(OUTPUT)
43endif 43endif
44 44
45ifneq ($(obj-perf),) 45ifneq ($(obj-perf),)
@@ -85,7 +85,7 @@ CFLAGS += -Wall
85CFLAGS += -Wextra 85CFLAGS += -Wextra
86CFLAGS += -std=gnu99 86CFLAGS += -std=gnu99
87 87
88EXTLIBS = -lpthread -lrt -lelf -lm 88EXTLIBS = -lelf -lpthread -lrt -lm
89 89
90ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -fstack-protector-all,-fstack-protector-all),y) 90ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -fstack-protector-all,-fstack-protector-all),y)
91 CFLAGS += -fstack-protector-all 91 CFLAGS += -fstack-protector-all
@@ -165,7 +165,7 @@ else
165 LIBDW_LDFLAGS := -L$(LIBDW_DIR)/lib 165 LIBDW_LDFLAGS := -L$(LIBDW_DIR)/lib
166 endif 166 endif
167 167
168 FLAGS_DWARF=$(CFLAGS) $(LIBDW_CFLAGS) -ldw -lelf $(LIBDW_LDFLAGS) $(LDFLAGS) $(EXTLIBS) 168 FLAGS_DWARF=$(CFLAGS) $(LIBDW_CFLAGS) -ldw -lz -lelf $(LIBDW_LDFLAGS) $(LDFLAGS) $(EXTLIBS)
169 ifneq ($(call try-cc,$(SOURCE_DWARF),$(FLAGS_DWARF),libdw),y) 169 ifneq ($(call try-cc,$(SOURCE_DWARF),$(FLAGS_DWARF),libdw),y)
170 msg := $(warning No libdw.h found or old libdw.h found or elfutils is older than 0.138, disables dwarf support. Please install new elfutils-devel/libdw-dev); 170 msg := $(warning No libdw.h found or old libdw.h found or elfutils is older than 0.138, disables dwarf support. Please install new elfutils-devel/libdw-dev);
171 NO_DWARF := 1 171 NO_DWARF := 1
diff --git a/tools/perf/config/utilities.mak b/tools/perf/config/utilities.mak
index 8ef3bd30a549..94d2d4f9c35d 100644
--- a/tools/perf/config/utilities.mak
+++ b/tools/perf/config/utilities.mak
@@ -173,7 +173,7 @@ _ge-abspath = $(if $(is-executable),$(1))
173# Usage: absolute-executable-path-or-empty = $(call get-executable-or-default,variable,default) 173# Usage: absolute-executable-path-or-empty = $(call get-executable-or-default,variable,default)
174# 174#
175define get-executable-or-default 175define get-executable-or-default
176$(if $($(1)),$(call _ge_attempt,$($(1)),$(1)),$(call _ge_attempt,$(2),$(1))) 176$(if $($(1)),$(call _ge_attempt,$($(1)),$(1)),$(call _ge_attempt,$(2)))
177endef 177endef
178_ge_attempt = $(if $(get-executable),$(get-executable),$(_gea_warn)$(call _gea_err,$(2))) 178_ge_attempt = $(if $(get-executable),$(get-executable),$(_gea_warn)$(call _gea_err,$(2)))
179_gea_warn = $(warning The path '$(1)' is not executable.) 179_gea_warn = $(warning The path '$(1)' is not executable.)
@@ -181,7 +181,7 @@ _gea_err = $(if $(1),$(error Please set '$(1)' appropriately))
181 181
182# try-cc 182# try-cc
183# Usage: option = $(call try-cc, source-to-build, cc-options, msg) 183# Usage: option = $(call try-cc, source-to-build, cc-options, msg)
184ifndef V 184ifneq ($(V),1)
185TRY_CC_OUTPUT= > /dev/null 2>&1 185TRY_CC_OUTPUT= > /dev/null 2>&1
186endif 186endif
187TRY_CC_MSG=echo " CHK $(3)" 1>&2; 187TRY_CC_MSG=echo " CHK $(3)" 1>&2;
diff --git a/tools/perf/scripts/perl/Perf-Trace-Util/Context.xs b/tools/perf/scripts/perl/Perf-Trace-Util/Context.xs
index c1e2ed1ed34e..8c7ea42444d1 100644
--- a/tools/perf/scripts/perl/Perf-Trace-Util/Context.xs
+++ b/tools/perf/scripts/perl/Perf-Trace-Util/Context.xs
@@ -23,7 +23,7 @@
23#include "perl.h" 23#include "perl.h"
24#include "XSUB.h" 24#include "XSUB.h"
25#include "../../../perf.h" 25#include "../../../perf.h"
26#include "../../../util/script-event.h" 26#include "../../../util/trace-event.h"
27 27
28MODULE = Perf::Trace::Context PACKAGE = Perf::Trace::Context 28MODULE = Perf::Trace::Context PACKAGE = Perf::Trace::Context
29PROTOTYPES: ENABLE 29PROTOTYPES: ENABLE
diff --git a/tools/perf/util/PERF-VERSION-GEN b/tools/perf/util/PERF-VERSION-GEN
index 055fef34b6f6..15a77b7c0e36 100755
--- a/tools/perf/util/PERF-VERSION-GEN
+++ b/tools/perf/util/PERF-VERSION-GEN
@@ -13,13 +13,22 @@ LF='
13# First check if there is a .git to get the version from git describe 13# First check if there is a .git to get the version from git describe
14# otherwise try to get the version from the kernel Makefile 14# otherwise try to get the version from the kernel Makefile
15# 15#
16if test -d ../../.git -o -f ../../.git && 16CID=
17 VN=$(git tag 2>/dev/null | tail -1 | grep -E "v[0-9].[0-9]*") 17TAG=
18if test -d ../../.git -o -f ../../.git
18then 19then
19 VN=$(echo $VN"-g"$(git log -1 --abbrev=4 --pretty=format:"%h" HEAD)) 20 TAG=$(git describe --abbrev=0 --match "v[0-9].[0-9]*" 2>/dev/null )
20 VN=$(echo "$VN" | sed -e 's/-/./g'); 21 CID=$(git log -1 --abbrev=4 --pretty=format:"%h" 2>/dev/null) && CID="-g$CID"
21else 22fi
22 VN=$(MAKEFLAGS= make -sC ../.. kernelversion) 23if test -z "$TAG"
24then
25 TAG=$(MAKEFLAGS= make -sC ../.. kernelversion)
26fi
27VN="$TAG$CID"
28if test -n "$CID"
29then
30 # format version string, strip trailing zero of sublevel:
31 VN=$(echo "$VN" | sed -e 's/-/./g;s/\([0-9]*[.][0-9]*\)[.]0/\1/')
23fi 32fi
24 33
25VN=$(expr "$VN" : v*'\(.*\)') 34VN=$(expr "$VN" : v*'\(.*\)')
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index 6f7d5a9d6b05..c4374f07603c 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -513,10 +513,16 @@ void dsos__add(struct list_head *head, struct dso *dso)
513 list_add_tail(&dso->node, head); 513 list_add_tail(&dso->node, head);
514} 514}
515 515
516struct dso *dsos__find(struct list_head *head, const char *name) 516struct dso *dsos__find(struct list_head *head, const char *name, bool cmp_short)
517{ 517{
518 struct dso *pos; 518 struct dso *pos;
519 519
520 if (cmp_short) {
521 list_for_each_entry(pos, head, node)
522 if (strcmp(pos->short_name, name) == 0)
523 return pos;
524 return NULL;
525 }
520 list_for_each_entry(pos, head, node) 526 list_for_each_entry(pos, head, node)
521 if (strcmp(pos->long_name, name) == 0) 527 if (strcmp(pos->long_name, name) == 0)
522 return pos; 528 return pos;
@@ -525,7 +531,7 @@ struct dso *dsos__find(struct list_head *head, const char *name)
525 531
526struct dso *__dsos__findnew(struct list_head *head, const char *name) 532struct dso *__dsos__findnew(struct list_head *head, const char *name)
527{ 533{
528 struct dso *dso = dsos__find(head, name); 534 struct dso *dso = dsos__find(head, name, false);
529 535
530 if (!dso) { 536 if (!dso) {
531 dso = dso__new(name); 537 dso = dso__new(name);
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
index 450199ab51b5..d51aaf272c68 100644
--- a/tools/perf/util/dso.h
+++ b/tools/perf/util/dso.h
@@ -133,7 +133,8 @@ struct dso *dso__kernel_findnew(struct machine *machine, const char *name,
133 const char *short_name, int dso_type); 133 const char *short_name, int dso_type);
134 134
135void dsos__add(struct list_head *head, struct dso *dso); 135void dsos__add(struct list_head *head, struct dso *dso);
136struct dso *dsos__find(struct list_head *head, const char *name); 136struct dso *dsos__find(struct list_head *head, const char *name,
137 bool cmp_short);
137struct dso *__dsos__findnew(struct list_head *head, const char *name); 138struct dso *__dsos__findnew(struct list_head *head, const char *name);
138bool __dsos__read_build_ids(struct list_head *head, bool with_hits); 139bool __dsos__read_build_ids(struct list_head *head, bool with_hits);
139 140
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 99b43dd18c57..8065ce8fa9a5 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -821,6 +821,7 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist,
821 goto out_close_pipes; 821 goto out_close_pipes;
822 } 822 }
823 823
824 fcntl(go_pipe[1], F_SETFD, FD_CLOEXEC);
824 evlist->workload.cork_fd = go_pipe[1]; 825 evlist->workload.cork_fd = go_pipe[1];
825 close(child_ready_pipe[0]); 826 close(child_ready_pipe[0]);
826 return 0; 827 return 0;
@@ -837,10 +838,17 @@ out_close_ready_pipe:
837int perf_evlist__start_workload(struct perf_evlist *evlist) 838int perf_evlist__start_workload(struct perf_evlist *evlist)
838{ 839{
839 if (evlist->workload.cork_fd > 0) { 840 if (evlist->workload.cork_fd > 0) {
841 char bf;
842 int ret;
840 /* 843 /*
841 * Remove the cork, let it rip! 844 * Remove the cork, let it rip!
842 */ 845 */
843 return close(evlist->workload.cork_fd); 846 ret = write(evlist->workload.cork_fd, &bf, 1);
847 if (ret < 0)
848 perror("enable to write to pipe");
849
850 close(evlist->workload.cork_fd);
851 return ret;
844 } 852 }
845 853
846 return 0; 854 return 0;
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 63b6f8c8edf2..c9c7494506a1 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -124,7 +124,7 @@ struct event_format *event_format__new(const char *sys, const char *name)
124 bf = nbf; 124 bf = nbf;
125 } 125 }
126 126
127 n = read(fd, bf + size, BUFSIZ); 127 n = read(fd, bf + size, alloc_size - size);
128 if (n < 0) 128 if (n < 0)
129 goto out_free_bf; 129 goto out_free_bf;
130 size += n; 130 size += n;
@@ -1170,7 +1170,7 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event,
1170 } else { 1170 } else {
1171 data->user_stack.data = (char *)array; 1171 data->user_stack.data = (char *)array;
1172 array += size / sizeof(*array); 1172 array += size / sizeof(*array);
1173 data->user_stack.size = *array; 1173 data->user_stack.size = *array++;
1174 } 1174 }
1175 } 1175 }
1176 1176
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 738d3b8d9745..a4dafbee2511 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -2303,29 +2303,18 @@ int perf_session__write_header(struct perf_session *session,
2303 struct perf_file_header f_header; 2303 struct perf_file_header f_header;
2304 struct perf_file_attr f_attr; 2304 struct perf_file_attr f_attr;
2305 struct perf_header *header = &session->header; 2305 struct perf_header *header = &session->header;
2306 struct perf_evsel *evsel, *pair = NULL; 2306 struct perf_evsel *evsel;
2307 int err; 2307 int err;
2308 2308
2309 lseek(fd, sizeof(f_header), SEEK_SET); 2309 lseek(fd, sizeof(f_header), SEEK_SET);
2310 2310
2311 if (session->evlist != evlist)
2312 pair = perf_evlist__first(session->evlist);
2313
2314 list_for_each_entry(evsel, &evlist->entries, node) { 2311 list_for_each_entry(evsel, &evlist->entries, node) {
2315 evsel->id_offset = lseek(fd, 0, SEEK_CUR); 2312 evsel->id_offset = lseek(fd, 0, SEEK_CUR);
2316 err = do_write(fd, evsel->id, evsel->ids * sizeof(u64)); 2313 err = do_write(fd, evsel->id, evsel->ids * sizeof(u64));
2317 if (err < 0) { 2314 if (err < 0) {
2318out_err_write:
2319 pr_debug("failed to write perf header\n"); 2315 pr_debug("failed to write perf header\n");
2320 return err; 2316 return err;
2321 } 2317 }
2322 if (session->evlist != evlist) {
2323 err = do_write(fd, pair->id, pair->ids * sizeof(u64));
2324 if (err < 0)
2325 goto out_err_write;
2326 evsel->ids += pair->ids;
2327 pair = perf_evsel__next(pair);
2328 }
2329 } 2318 }
2330 2319
2331 header->attr_offset = lseek(fd, 0, SEEK_CUR); 2320 header->attr_offset = lseek(fd, 0, SEEK_CUR);
@@ -2967,6 +2956,8 @@ int perf_event__process_attr(union perf_event *event,
2967 perf_evlist__id_add(evlist, evsel, 0, i, event->attr.id[i]); 2956 perf_evlist__id_add(evlist, evsel, 0, i, event->attr.id[i]);
2968 } 2957 }
2969 2958
2959 symbol_conf.nr_events = evlist->nr_entries;
2960
2970 return 0; 2961 return 0;
2971} 2962}
2972 2963
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 6c8bb0fb189b..995fc25db8c6 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -860,7 +860,8 @@ int parse_events_terms(struct list_head *terms, const char *str)
860 return 0; 860 return 0;
861 } 861 }
862 862
863 parse_events__free_terms(data.terms); 863 if (data.terms)
864 parse_events__free_terms(data.terms);
864 return ret; 865 return ret;
865} 866}
866 867
@@ -1183,6 +1184,7 @@ static int new_term(struct parse_events_term **_term, int type_val,
1183 term->val.str = str; 1184 term->val.str = str;
1184 break; 1185 break;
1185 default: 1186 default:
1187 free(term);
1186 return -EINVAL; 1188 return -EINVAL;
1187 } 1189 }
1188 1190
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 8cf3b5426a9a..d5528e1cc03a 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -32,7 +32,6 @@ int vmlinux_path__nr_entries;
32char **vmlinux_path; 32char **vmlinux_path;
33 33
34struct symbol_conf symbol_conf = { 34struct symbol_conf symbol_conf = {
35 .exclude_other = true,
36 .use_modules = true, 35 .use_modules = true,
37 .try_vmlinux_path = true, 36 .try_vmlinux_path = true,
38 .annotate_src = true, 37 .annotate_src = true,
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 7a484c97e500..2732fad03908 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -72,6 +72,7 @@
72#include "types.h" 72#include "types.h"
73#include <sys/ttydefaults.h> 73#include <sys/ttydefaults.h>
74#include <lk/debugfs.h> 74#include <lk/debugfs.h>
75#include <termios.h>
75 76
76extern const char *graph_line; 77extern const char *graph_line;
77extern const char *graph_dotted_line; 78extern const char *graph_dotted_line;
@@ -274,6 +275,5 @@ void dump_stack(void);
274 275
275extern unsigned int page_size; 276extern unsigned int page_size;
276 277
277struct winsize;
278void get_term_dimensions(struct winsize *ws); 278void get_term_dimensions(struct winsize *ws);
279#endif /* GIT_COMPAT_UTIL_H */ 279#endif /* GIT_COMPAT_UTIL_H */
diff --git a/tools/perf/util/vdso.c b/tools/perf/util/vdso.c
index e60951fcdb12..39159822d58f 100644
--- a/tools/perf/util/vdso.c
+++ b/tools/perf/util/vdso.c
@@ -91,7 +91,7 @@ void vdso__exit(void)
91 91
92struct dso *vdso__dso_findnew(struct list_head *head) 92struct dso *vdso__dso_findnew(struct list_head *head)
93{ 93{
94 struct dso *dso = dsos__find(head, VDSO__MAP_NAME); 94 struct dso *dso = dsos__find(head, VDSO__MAP_NAME, true);
95 95
96 if (!dso) { 96 if (!dso) {
97 char *file; 97 char *file;
diff --git a/tools/power/cpupower/Makefile b/tools/power/cpupower/Makefile
index d875a74a3bdf..cbfec92af327 100644
--- a/tools/power/cpupower/Makefile
+++ b/tools/power/cpupower/Makefile
@@ -128,10 +128,12 @@ UTIL_OBJS = utils/helpers/amd.o utils/helpers/topology.o utils/helpers/msr.o \
128 utils/helpers/sysfs.o utils/helpers/misc.o utils/helpers/cpuid.o \ 128 utils/helpers/sysfs.o utils/helpers/misc.o utils/helpers/cpuid.o \
129 utils/helpers/pci.o utils/helpers/bitmask.o \ 129 utils/helpers/pci.o utils/helpers/bitmask.o \
130 utils/idle_monitor/nhm_idle.o utils/idle_monitor/snb_idle.o \ 130 utils/idle_monitor/nhm_idle.o utils/idle_monitor/snb_idle.o \
131 utils/idle_monitor/hsw_ext_idle.o \
131 utils/idle_monitor/amd_fam14h_idle.o utils/idle_monitor/cpuidle_sysfs.o \ 132 utils/idle_monitor/amd_fam14h_idle.o utils/idle_monitor/cpuidle_sysfs.o \
132 utils/idle_monitor/mperf_monitor.o utils/idle_monitor/cpupower-monitor.o \ 133 utils/idle_monitor/mperf_monitor.o utils/idle_monitor/cpupower-monitor.o \
133 utils/cpupower.o utils/cpufreq-info.o utils/cpufreq-set.o \ 134 utils/cpupower.o utils/cpufreq-info.o utils/cpufreq-set.o \
134 utils/cpupower-set.o utils/cpupower-info.o utils/cpuidle-info.o 135 utils/cpupower-set.o utils/cpupower-info.o utils/cpuidle-info.o \
136 utils/cpuidle-set.o
135 137
136UTIL_SRC := $(UTIL_OBJS:.o=.c) 138UTIL_SRC := $(UTIL_OBJS:.o=.c)
137 139
diff --git a/tools/power/cpupower/man/cpupower-monitor.1 b/tools/power/cpupower/man/cpupower-monitor.1
index e01c35d13b6e..914cbb9d9cd0 100644
--- a/tools/power/cpupower/man/cpupower-monitor.1
+++ b/tools/power/cpupower/man/cpupower-monitor.1
@@ -110,13 +110,21 @@ May work poorly on Linux-2.6.20 through 2.6.29, as the \fBacpi-cpufreq \fP
110kernel frequency driver periodically cleared aperf/mperf registers in those 110kernel frequency driver periodically cleared aperf/mperf registers in those
111kernels. 111kernels.
112 112
113.SS "Nehalem" "SandyBridge" 113.SS "Nehalem" "SandyBridge" "HaswellExtended"
114Intel Core and Package sleep state counters. 114Intel Core and Package sleep state counters.
115Threads (hyperthreaded cores) may not be able to enter deeper core states if 115Threads (hyperthreaded cores) may not be able to enter deeper core states if
116its sibling is utilized. 116its sibling is utilized.
117Deepest package sleep states may in reality show up as machine/platform wide 117Deepest package sleep states may in reality show up as machine/platform wide
118sleep states and can only be entered if all cores are idle. Look up Intel 118sleep states and can only be entered if all cores are idle. Look up Intel
119manuals (some are provided in the References section) for further details. 119manuals (some are provided in the References section) for further details.
120The monitors are named after the CPU family where the sleep state capabilities
121got introduced and may not match exactly the CPU name of the platform.
122For example an IvyBridge processor has sleep state capabilities which got
123introduced in Nehalem and SandyBridge processor families.
124Thus on an IvyBridge processor one will get Nehalem and SandyBridge sleep
125state monitors.
126HaswellExtended extra package sleep state capabilities are available only in a
127specific Haswell (family 0x45) and probably also other future processors.
120 128
121.SS "Fam_12h" "Fam_14h" 129.SS "Fam_12h" "Fam_14h"
122AMD laptop and desktop processor (family 12h and 14h) sleep state counters. 130AMD laptop and desktop processor (family 12h and 14h) sleep state counters.
diff --git a/tools/power/cpupower/utils/builtin.h b/tools/power/cpupower/utils/builtin.h
index c10496fbe3c6..2284c8ea4e2a 100644
--- a/tools/power/cpupower/utils/builtin.h
+++ b/tools/power/cpupower/utils/builtin.h
@@ -5,6 +5,7 @@ extern int cmd_set(int argc, const char **argv);
5extern int cmd_info(int argc, const char **argv); 5extern int cmd_info(int argc, const char **argv);
6extern int cmd_freq_set(int argc, const char **argv); 6extern int cmd_freq_set(int argc, const char **argv);
7extern int cmd_freq_info(int argc, const char **argv); 7extern int cmd_freq_info(int argc, const char **argv);
8extern int cmd_idle_set(int argc, const char **argv);
8extern int cmd_idle_info(int argc, const char **argv); 9extern int cmd_idle_info(int argc, const char **argv);
9extern int cmd_monitor(int argc, const char **argv); 10extern int cmd_monitor(int argc, const char **argv);
10 11
diff --git a/tools/power/cpupower/utils/cpuidle-info.c b/tools/power/cpupower/utils/cpuidle-info.c
index 8145af5f93a6..75e66de7e7a7 100644
--- a/tools/power/cpupower/utils/cpuidle-info.c
+++ b/tools/power/cpupower/utils/cpuidle-info.c
@@ -22,7 +22,7 @@
22 22
23static void cpuidle_cpu_output(unsigned int cpu, int verbose) 23static void cpuidle_cpu_output(unsigned int cpu, int verbose)
24{ 24{
25 int idlestates, idlestate; 25 unsigned int idlestates, idlestate;
26 char *tmp; 26 char *tmp;
27 27
28 printf(_ ("Analyzing CPU %d:\n"), cpu); 28 printf(_ ("Analyzing CPU %d:\n"), cpu);
@@ -31,10 +31,8 @@ static void cpuidle_cpu_output(unsigned int cpu, int verbose)
31 if (idlestates == 0) { 31 if (idlestates == 0) {
32 printf(_("CPU %u: No idle states\n"), cpu); 32 printf(_("CPU %u: No idle states\n"), cpu);
33 return; 33 return;
34 } else if (idlestates <= 0) {
35 printf(_("CPU %u: Can't read idle state info\n"), cpu);
36 return;
37 } 34 }
35
38 printf(_("Number of idle states: %d\n"), idlestates); 36 printf(_("Number of idle states: %d\n"), idlestates);
39 printf(_("Available idle states:")); 37 printf(_("Available idle states:"));
40 for (idlestate = 0; idlestate < idlestates; idlestate++) { 38 for (idlestate = 0; idlestate < idlestates; idlestate++) {
@@ -50,10 +48,14 @@ static void cpuidle_cpu_output(unsigned int cpu, int verbose)
50 return; 48 return;
51 49
52 for (idlestate = 0; idlestate < idlestates; idlestate++) { 50 for (idlestate = 0; idlestate < idlestates; idlestate++) {
51 int disabled = sysfs_is_idlestate_disabled(cpu, idlestate);
52 /* Disabled interface not supported on older kernels */
53 if (disabled < 0)
54 disabled = 0;
53 tmp = sysfs_get_idlestate_name(cpu, idlestate); 55 tmp = sysfs_get_idlestate_name(cpu, idlestate);
54 if (!tmp) 56 if (!tmp)
55 continue; 57 continue;
56 printf("%s:\n", tmp); 58 printf("%s%s:\n", tmp, (disabled) ? " (DISABLED) " : "");
57 free(tmp); 59 free(tmp);
58 60
59 tmp = sysfs_get_idlestate_desc(cpu, idlestate); 61 tmp = sysfs_get_idlestate_desc(cpu, idlestate);
@@ -98,21 +100,13 @@ static void cpuidle_general_output(void)
98static void proc_cpuidle_cpu_output(unsigned int cpu) 100static void proc_cpuidle_cpu_output(unsigned int cpu)
99{ 101{
100 long max_allowed_cstate = 2000000000; 102 long max_allowed_cstate = 2000000000;
101 int cstates, cstate; 103 unsigned int cstate, cstates;
102 104
103 cstates = sysfs_get_idlestate_count(cpu); 105 cstates = sysfs_get_idlestate_count(cpu);
104 if (cstates == 0) { 106 if (cstates == 0) {
105 /* 107 printf(_("CPU %u: No C-states info\n"), cpu);
106 * Go on and print same useless info as you'd see with
107 * cat /proc/acpi/processor/../power
108 * printf(_("CPU %u: No C-states available\n"), cpu);
109 * return;
110 */
111 } else if (cstates <= 0) {
112 printf(_("CPU %u: Can't read C-state info\n"), cpu);
113 return; 108 return;
114 } 109 }
115 /* printf("Cstates: %d\n", cstates); */
116 110
117 printf(_("active state: C0\n")); 111 printf(_("active state: C0\n"));
118 printf(_("max_cstate: C%u\n"), cstates-1); 112 printf(_("max_cstate: C%u\n"), cstates-1);
diff --git a/tools/power/cpupower/utils/cpuidle-set.c b/tools/power/cpupower/utils/cpuidle-set.c
new file mode 100644
index 000000000000..c78141c5dfac
--- /dev/null
+++ b/tools/power/cpupower/utils/cpuidle-set.c
@@ -0,0 +1,118 @@
1#include <unistd.h>
2#include <stdio.h>
3#include <errno.h>
4#include <stdlib.h>
5#include <limits.h>
6#include <string.h>
7#include <ctype.h>
8
9#include <getopt.h>
10
11#include "cpufreq.h"
12#include "helpers/helpers.h"
13#include "helpers/sysfs.h"
14
15static struct option info_opts[] = {
16 { .name = "disable", .has_arg = required_argument, .flag = NULL, .val = 'd'},
17 { .name = "enable", .has_arg = required_argument, .flag = NULL, .val = 'e'},
18 { },
19};
20
21
22int cmd_idle_set(int argc, char **argv)
23{
24 extern char *optarg;
25 extern int optind, opterr, optopt;
26 int ret = 0, cont = 1, param = 0, idlestate = 0;
27 unsigned int cpu = 0;
28
29 do {
30 ret = getopt_long(argc, argv, "d:e:", info_opts, NULL);
31 if (ret == -1)
32 break;
33 switch (ret) {
34 case '?':
35 param = '?';
36 cont = 0;
37 break;
38 case 'd':
39 if (param) {
40 param = -1;
41 cont = 0;
42 break;
43 }
44 param = ret;
45 idlestate = atoi(optarg);
46 break;
47 case 'e':
48 if (param) {
49 param = -1;
50 cont = 0;
51 break;
52 }
53 param = ret;
54 idlestate = atoi(optarg);
55 break;
56 case -1:
57 cont = 0;
58 break;
59 }
60 } while (cont);
61
62 switch (param) {
63 case -1:
64 printf(_("You can't specify more than one "
65 "output-specific argument\n"));
66 exit(EXIT_FAILURE);
67 case '?':
68 printf(_("invalid or unknown argument\n"));
69 exit(EXIT_FAILURE);
70 }
71
72 /* Default is: set all CPUs */
73 if (bitmask_isallclear(cpus_chosen))
74 bitmask_setall(cpus_chosen);
75
76 for (cpu = bitmask_first(cpus_chosen);
77 cpu <= bitmask_last(cpus_chosen); cpu++) {
78
79 if (!bitmask_isbitset(cpus_chosen, cpu))
80 continue;
81
82 switch (param) {
83
84 case 'd':
85 ret = sysfs_idlestate_disable(cpu, idlestate, 1);
86 if (ret == 0)
87 printf(_("Idlestate %u disabled on CPU %u\n"), idlestate, cpu);
88 else if (ret == -1)
89 printf(_("Idlestate %u not available on CPU %u\n"),
90 idlestate, cpu);
91 else if (ret == -2)
92 printf(_("Idlestate disabling not supported by kernel\n"));
93 else
94 printf(_("Idlestate %u not disabled on CPU %u\n"),
95 idlestate, cpu);
96 break;
97 case 'e':
98 ret = sysfs_idlestate_disable(cpu, idlestate, 0);
99 if (ret == 0)
100 printf(_("Idlestate %u enabled on CPU %u\n"), idlestate, cpu);
101 else if (ret == -1)
102 printf(_("Idlestate %u not available on CPU %u\n"),
103 idlestate, cpu);
104 else if (ret == -2)
105 printf(_("Idlestate enabling not supported by kernel\n"));
106 else
107 printf(_("Idlestate %u not enabled on CPU %u\n"),
108 idlestate, cpu);
109 break;
110 default:
111 /* Not reachable with proper args checking */
112 printf(_("Invalid or unknown argument\n"));
113 exit(EXIT_FAILURE);
114 break;
115 }
116 }
117 return EXIT_SUCCESS;
118}
diff --git a/tools/power/cpupower/utils/cpupower.c b/tools/power/cpupower/utils/cpupower.c
index 52bee591c1c5..7efc570ffbaa 100644
--- a/tools/power/cpupower/utils/cpupower.c
+++ b/tools/power/cpupower/utils/cpupower.c
@@ -17,12 +17,6 @@
17#include "helpers/helpers.h" 17#include "helpers/helpers.h"
18#include "helpers/bitmask.h" 18#include "helpers/bitmask.h"
19 19
20struct cmd_struct {
21 const char *cmd;
22 int (*main)(int, const char **);
23 int needs_root;
24};
25
26#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) 20#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
27 21
28static int cmd_help(int argc, const char **argv); 22static int cmd_help(int argc, const char **argv);
@@ -43,10 +37,17 @@ int be_verbose;
43 37
44static void print_help(void); 38static void print_help(void);
45 39
40struct cmd_struct {
41 const char *cmd;
42 int (*main)(int, const char **);
43 int needs_root;
44};
45
46static struct cmd_struct commands[] = { 46static struct cmd_struct commands[] = {
47 { "frequency-info", cmd_freq_info, 0 }, 47 { "frequency-info", cmd_freq_info, 0 },
48 { "frequency-set", cmd_freq_set, 1 }, 48 { "frequency-set", cmd_freq_set, 1 },
49 { "idle-info", cmd_idle_info, 0 }, 49 { "idle-info", cmd_idle_info, 0 },
50 { "idle-set", cmd_idle_set, 1 },
50 { "set", cmd_set, 1 }, 51 { "set", cmd_set, 1 },
51 { "info", cmd_info, 0 }, 52 { "info", cmd_info, 0 },
52 { "monitor", cmd_monitor, 0 }, 53 { "monitor", cmd_monitor, 0 },
diff --git a/tools/power/cpupower/utils/helpers/sysfs.c b/tools/power/cpupower/utils/helpers/sysfs.c
index 38ab91629463..5cdc600e8152 100644
--- a/tools/power/cpupower/utils/helpers/sysfs.c
+++ b/tools/power/cpupower/utils/helpers/sysfs.c
@@ -89,6 +89,33 @@ int sysfs_is_cpu_online(unsigned int cpu)
89 89
90/* CPUidle idlestate specific /sys/devices/system/cpu/cpuX/cpuidle/ access */ 90/* CPUidle idlestate specific /sys/devices/system/cpu/cpuX/cpuidle/ access */
91 91
92
93/* CPUidle idlestate specific /sys/devices/system/cpu/cpuX/cpuidle/ access */
94
95/*
96 * helper function to check whether a file under "../cpuX/cpuidle/stateX/" dir
97 * exists.
98 * For example the functionality to disable c-states was introduced in later
99 * kernel versions, this function can be used to explicitly check for this
100 * feature.
101 *
102 * returns 1 if the file exists, 0 otherwise.
103 */
104unsigned int sysfs_idlestate_file_exists(unsigned int cpu,
105 unsigned int idlestate,
106 const char *fname)
107{
108 char path[SYSFS_PATH_MAX];
109 struct stat statbuf;
110
111
112 snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/cpuidle/state%u/%s",
113 cpu, idlestate, fname);
114 if (stat(path, &statbuf) != 0)
115 return 0;
116 return 1;
117}
118
92/* 119/*
93 * helper function to read file from /sys into given buffer 120 * helper function to read file from /sys into given buffer
94 * fname is a relative path under "cpuX/cpuidle/stateX/" dir 121 * fname is a relative path under "cpuX/cpuidle/stateX/" dir
@@ -121,6 +148,40 @@ unsigned int sysfs_idlestate_read_file(unsigned int cpu, unsigned int idlestate,
121 return (unsigned int) numread; 148 return (unsigned int) numread;
122} 149}
123 150
151/*
152 * helper function to write a new value to a /sys file
153 * fname is a relative path under "../cpuX/cpuidle/cstateY/" dir
154 *
155 * Returns the number of bytes written or 0 on error
156 */
157static
158unsigned int sysfs_idlestate_write_file(unsigned int cpu,
159 unsigned int idlestate,
160 const char *fname,
161 const char *value, size_t len)
162{
163 char path[SYSFS_PATH_MAX];
164 int fd;
165 ssize_t numwrite;
166
167 snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/cpuidle/state%u/%s",
168 cpu, idlestate, fname);
169
170 fd = open(path, O_WRONLY);
171 if (fd == -1)
172 return 0;
173
174 numwrite = write(fd, value, len);
175 if (numwrite < 1) {
176 close(fd);
177 return 0;
178 }
179
180 close(fd);
181
182 return (unsigned int) numwrite;
183}
184
124/* read access to files which contain one numeric value */ 185/* read access to files which contain one numeric value */
125 186
126enum idlestate_value { 187enum idlestate_value {
@@ -128,6 +189,7 @@ enum idlestate_value {
128 IDLESTATE_POWER, 189 IDLESTATE_POWER,
129 IDLESTATE_LATENCY, 190 IDLESTATE_LATENCY,
130 IDLESTATE_TIME, 191 IDLESTATE_TIME,
192 IDLESTATE_DISABLE,
131 MAX_IDLESTATE_VALUE_FILES 193 MAX_IDLESTATE_VALUE_FILES
132}; 194};
133 195
@@ -136,6 +198,7 @@ static const char *idlestate_value_files[MAX_IDLESTATE_VALUE_FILES] = {
136 [IDLESTATE_POWER] = "power", 198 [IDLESTATE_POWER] = "power",
137 [IDLESTATE_LATENCY] = "latency", 199 [IDLESTATE_LATENCY] = "latency",
138 [IDLESTATE_TIME] = "time", 200 [IDLESTATE_TIME] = "time",
201 [IDLESTATE_DISABLE] = "disable",
139}; 202};
140 203
141static unsigned long long sysfs_idlestate_get_one_value(unsigned int cpu, 204static unsigned long long sysfs_idlestate_get_one_value(unsigned int cpu,
@@ -205,8 +268,59 @@ static char *sysfs_idlestate_get_one_string(unsigned int cpu,
205 return result; 268 return result;
206} 269}
207 270
271/*
272 * Returns:
273 * 1 if disabled
274 * 0 if enabled
275 * -1 if idlestate is not available
276 * -2 if disabling is not supported by the kernel
277 */
278int sysfs_is_idlestate_disabled(unsigned int cpu,
279 unsigned int idlestate)
280{
281 if (sysfs_get_idlestate_count(cpu) < idlestate)
282 return -1;
283
284 if (!sysfs_idlestate_file_exists(cpu, idlestate,
285 idlestate_value_files[IDLESTATE_DISABLE]))
286 return -2;
287 return sysfs_idlestate_get_one_value(cpu, idlestate, IDLESTATE_DISABLE);
288}
289
290/*
291 * Pass 1 as last argument to disable or 0 to enable the state
292 * Returns:
293 * 0 on success
294 * negative values on error, for example:
295 * -1 if idlestate is not available
296 * -2 if disabling is not supported by the kernel
297 * -3 No write access to disable/enable C-states
298 */
299int sysfs_idlestate_disable(unsigned int cpu,
300 unsigned int idlestate,
301 unsigned int disable)
302{
303 char value[SYSFS_PATH_MAX];
304 int bytes_written;
305
306 if (sysfs_get_idlestate_count(cpu) < idlestate)
307 return -1;
308
309 if (!sysfs_idlestate_file_exists(cpu, idlestate,
310 idlestate_value_files[IDLESTATE_DISABLE]))
311 return -2;
312
313 snprintf(value, SYSFS_PATH_MAX, "%u", disable);
314
315 bytes_written = sysfs_idlestate_write_file(cpu, idlestate, "disable",
316 value, sizeof(disable));
317 if (bytes_written)
318 return 0;
319 return -3;
320}
321
208unsigned long sysfs_get_idlestate_latency(unsigned int cpu, 322unsigned long sysfs_get_idlestate_latency(unsigned int cpu,
209 unsigned int idlestate) 323 unsigned int idlestate)
210{ 324{
211 return sysfs_idlestate_get_one_value(cpu, idlestate, IDLESTATE_LATENCY); 325 return sysfs_idlestate_get_one_value(cpu, idlestate, IDLESTATE_LATENCY);
212} 326}
@@ -238,7 +352,7 @@ char *sysfs_get_idlestate_desc(unsigned int cpu, unsigned int idlestate)
238 * Negativ in error case 352 * Negativ in error case
239 * Zero if cpuidle does not export any C-states 353 * Zero if cpuidle does not export any C-states
240 */ 354 */
241int sysfs_get_idlestate_count(unsigned int cpu) 355unsigned int sysfs_get_idlestate_count(unsigned int cpu)
242{ 356{
243 char file[SYSFS_PATH_MAX]; 357 char file[SYSFS_PATH_MAX];
244 struct stat statbuf; 358 struct stat statbuf;
diff --git a/tools/power/cpupower/utils/helpers/sysfs.h b/tools/power/cpupower/utils/helpers/sysfs.h
index 8cb797bbceb0..d28f11fedbda 100644
--- a/tools/power/cpupower/utils/helpers/sysfs.h
+++ b/tools/power/cpupower/utils/helpers/sysfs.h
@@ -7,8 +7,16 @@
7 7
8extern unsigned int sysfs_read_file(const char *path, char *buf, size_t buflen); 8extern unsigned int sysfs_read_file(const char *path, char *buf, size_t buflen);
9 9
10extern unsigned int sysfs_idlestate_file_exists(unsigned int cpu,
11 unsigned int idlestate,
12 const char *fname);
13
10extern int sysfs_is_cpu_online(unsigned int cpu); 14extern int sysfs_is_cpu_online(unsigned int cpu);
11 15
16extern int sysfs_is_idlestate_disabled(unsigned int cpu,
17 unsigned int idlestate);
18extern int sysfs_idlestate_disable(unsigned int cpu, unsigned int idlestate,
19 unsigned int disable);
12extern unsigned long sysfs_get_idlestate_latency(unsigned int cpu, 20extern unsigned long sysfs_get_idlestate_latency(unsigned int cpu,
13 unsigned int idlestate); 21 unsigned int idlestate);
14extern unsigned long sysfs_get_idlestate_usage(unsigned int cpu, 22extern unsigned long sysfs_get_idlestate_usage(unsigned int cpu,
@@ -19,7 +27,7 @@ extern char *sysfs_get_idlestate_name(unsigned int cpu,
19 unsigned int idlestate); 27 unsigned int idlestate);
20extern char *sysfs_get_idlestate_desc(unsigned int cpu, 28extern char *sysfs_get_idlestate_desc(unsigned int cpu,
21 unsigned int idlestate); 29 unsigned int idlestate);
22extern int sysfs_get_idlestate_count(unsigned int cpu); 30extern unsigned int sysfs_get_idlestate_count(unsigned int cpu);
23 31
24extern char *sysfs_get_cpuidle_governor(void); 32extern char *sysfs_get_cpuidle_governor(void);
25extern char *sysfs_get_cpuidle_driver(void); 33extern char *sysfs_get_cpuidle_driver(void);
diff --git a/tools/power/cpupower/utils/idle_monitor/hsw_ext_idle.c b/tools/power/cpupower/utils/idle_monitor/hsw_ext_idle.c
new file mode 100644
index 000000000000..ebeaba6571a3
--- /dev/null
+++ b/tools/power/cpupower/utils/idle_monitor/hsw_ext_idle.c
@@ -0,0 +1,196 @@
1/*
2 * (C) 2010,2011 Thomas Renninger <trenn@suse.de>, Novell Inc.
3 *
4 * Licensed under the terms of the GNU GPL License version 2.
5 *
6 * Based on SandyBridge monitor. Implements the new package C-states
7 * (PC8, PC9, PC10) coming with a specific Haswell (family 0x45) CPU.
8 */
9
10#if defined(__i386__) || defined(__x86_64__)
11
12#include <stdio.h>
13#include <stdint.h>
14#include <stdlib.h>
15#include <string.h>
16
17#include "helpers/helpers.h"
18#include "idle_monitor/cpupower-monitor.h"
19
20#define MSR_PKG_C8_RESIDENCY 0x00000630
21#define MSR_PKG_C9_RESIDENCY 0x00000631
22#define MSR_PKG_C10_RESIDENCY 0x00000632
23
24#define MSR_TSC 0x10
25
26enum intel_hsw_ext_id { PC8 = 0, PC9, PC10, HSW_EXT_CSTATE_COUNT,
27 TSC = 0xFFFF };
28
29static int hsw_ext_get_count_percent(unsigned int self_id, double *percent,
30 unsigned int cpu);
31
32static cstate_t hsw_ext_cstates[HSW_EXT_CSTATE_COUNT] = {
33 {
34 .name = "PC8",
35 .desc = N_("Processor Package C8"),
36 .id = PC8,
37 .range = RANGE_PACKAGE,
38 .get_count_percent = hsw_ext_get_count_percent,
39 },
40 {
41 .name = "PC9",
42 .desc = N_("Processor Package C9"),
43 .desc = N_("Processor Package C2"),
44 .id = PC9,
45 .range = RANGE_PACKAGE,
46 .get_count_percent = hsw_ext_get_count_percent,
47 },
48 {
49 .name = "PC10",
50 .desc = N_("Processor Package C10"),
51 .id = PC10,
52 .range = RANGE_PACKAGE,
53 .get_count_percent = hsw_ext_get_count_percent,
54 },
55};
56
57static unsigned long long tsc_at_measure_start;
58static unsigned long long tsc_at_measure_end;
59static unsigned long long *previous_count[HSW_EXT_CSTATE_COUNT];
60static unsigned long long *current_count[HSW_EXT_CSTATE_COUNT];
61/* valid flag for all CPUs. If a MSR read failed it will be zero */
62static int *is_valid;
63
64static int hsw_ext_get_count(enum intel_hsw_ext_id id, unsigned long long *val,
65 unsigned int cpu)
66{
67 int msr;
68
69 switch (id) {
70 case PC8:
71 msr = MSR_PKG_C8_RESIDENCY;
72 break;
73 case PC9:
74 msr = MSR_PKG_C9_RESIDENCY;
75 break;
76 case PC10:
77 msr = MSR_PKG_C10_RESIDENCY;
78 break;
79 case TSC:
80 msr = MSR_TSC;
81 break;
82 default:
83 return -1;
84 };
85 if (read_msr(cpu, msr, val))
86 return -1;
87 return 0;
88}
89
90static int hsw_ext_get_count_percent(unsigned int id, double *percent,
91 unsigned int cpu)
92{
93 *percent = 0.0;
94
95 if (!is_valid[cpu])
96 return -1;
97
98 *percent = (100.0 *
99 (current_count[id][cpu] - previous_count[id][cpu])) /
100 (tsc_at_measure_end - tsc_at_measure_start);
101
102 dprint("%s: previous: %llu - current: %llu - (%u)\n",
103 hsw_ext_cstates[id].name, previous_count[id][cpu],
104 current_count[id][cpu], cpu);
105
106 dprint("%s: tsc_diff: %llu - count_diff: %llu - percent: %2.f (%u)\n",
107 hsw_ext_cstates[id].name,
108 (unsigned long long) tsc_at_measure_end - tsc_at_measure_start,
109 current_count[id][cpu] - previous_count[id][cpu],
110 *percent, cpu);
111
112 return 0;
113}
114
115static int hsw_ext_start(void)
116{
117 int num, cpu;
118 unsigned long long val;
119
120 for (num = 0; num < HSW_EXT_CSTATE_COUNT; num++) {
121 for (cpu = 0; cpu < cpu_count; cpu++) {
122 hsw_ext_get_count(num, &val, cpu);
123 previous_count[num][cpu] = val;
124 }
125 }
126 hsw_ext_get_count(TSC, &tsc_at_measure_start, 0);
127 return 0;
128}
129
130static int hsw_ext_stop(void)
131{
132 unsigned long long val;
133 int num, cpu;
134
135 hsw_ext_get_count(TSC, &tsc_at_measure_end, 0);
136
137 for (num = 0; num < HSW_EXT_CSTATE_COUNT; num++) {
138 for (cpu = 0; cpu < cpu_count; cpu++) {
139 is_valid[cpu] = !hsw_ext_get_count(num, &val, cpu);
140 current_count[num][cpu] = val;
141 }
142 }
143 return 0;
144}
145
146struct cpuidle_monitor intel_hsw_ext_monitor;
147
148static struct cpuidle_monitor *hsw_ext_register(void)
149{
150 int num;
151
152 if (cpupower_cpu_info.vendor != X86_VENDOR_INTEL
153 || cpupower_cpu_info.family != 6)
154 return NULL;
155
156 switch (cpupower_cpu_info.model) {
157 case 0x45: /* HSW */
158 break;
159 default:
160 return NULL;
161 }
162
163 is_valid = calloc(cpu_count, sizeof(int));
164 for (num = 0; num < HSW_EXT_CSTATE_COUNT; num++) {
165 previous_count[num] = calloc(cpu_count,
166 sizeof(unsigned long long));
167 current_count[num] = calloc(cpu_count,
168 sizeof(unsigned long long));
169 }
170 intel_hsw_ext_monitor.name_len = strlen(intel_hsw_ext_monitor.name);
171 return &intel_hsw_ext_monitor;
172}
173
174void hsw_ext_unregister(void)
175{
176 int num;
177 free(is_valid);
178 for (num = 0; num < HSW_EXT_CSTATE_COUNT; num++) {
179 free(previous_count[num]);
180 free(current_count[num]);
181 }
182}
183
184struct cpuidle_monitor intel_hsw_ext_monitor = {
185 .name = "HaswellExtended",
186 .hw_states = hsw_ext_cstates,
187 .hw_states_num = HSW_EXT_CSTATE_COUNT,
188 .start = hsw_ext_start,
189 .stop = hsw_ext_stop,
190 .do_register = hsw_ext_register,
191 .unregister = hsw_ext_unregister,
192 .needs_root = 1,
193 .overflow_s = 922000000 /* 922337203 seconds TSC overflow
194 at 20GHz */
195};
196#endif /* defined(__i386__) || defined(__x86_64__) */
diff --git a/tools/power/cpupower/utils/idle_monitor/idle_monitors.def b/tools/power/cpupower/utils/idle_monitor/idle_monitors.def
index e3f8d9b2b18f..0d6ba4dbb9c7 100644
--- a/tools/power/cpupower/utils/idle_monitor/idle_monitors.def
+++ b/tools/power/cpupower/utils/idle_monitor/idle_monitors.def
@@ -2,6 +2,7 @@
2DEF(amd_fam14h) 2DEF(amd_fam14h)
3DEF(intel_nhm) 3DEF(intel_nhm)
4DEF(intel_snb) 4DEF(intel_snb)
5DEF(intel_hsw_ext)
5DEF(mperf) 6DEF(mperf)
6#endif 7#endif
7DEF(cpuidle_sysfs) 8DEF(cpuidle_sysfs)
diff --git a/tools/power/cpupower/utils/idle_monitor/snb_idle.c b/tools/power/cpupower/utils/idle_monitor/snb_idle.c
index a99b43b97d6d..efc8a69c9aba 100644
--- a/tools/power/cpupower/utils/idle_monitor/snb_idle.c
+++ b/tools/power/cpupower/utils/idle_monitor/snb_idle.c
@@ -155,6 +155,10 @@ static struct cpuidle_monitor *snb_register(void)
155 case 0x2D: /* SNB Xeon */ 155 case 0x2D: /* SNB Xeon */
156 case 0x3A: /* IVB */ 156 case 0x3A: /* IVB */
157 case 0x3E: /* IVB Xeon */ 157 case 0x3E: /* IVB Xeon */
158 case 0x3C: /* HSW */
159 case 0x3F: /* HSW */
160 case 0x45: /* HSW */
161 case 0x46: /* HSW */
158 break; 162 break;
159 default: 163 default:
160 return NULL; 164 return NULL;
diff --git a/tools/scripts/Makefile.include b/tools/scripts/Makefile.include
index f03e681f8891..0d0506d55c71 100644
--- a/tools/scripts/Makefile.include
+++ b/tools/scripts/Makefile.include
@@ -59,7 +59,7 @@ QUIET_SUBDIR0 = +$(MAKE) $(COMMAND_O) -C # space to separate -C and subdir
59QUIET_SUBDIR1 = 59QUIET_SUBDIR1 =
60 60
61ifneq ($(findstring $(MAKEFLAGS),s),s) 61ifneq ($(findstring $(MAKEFLAGS),s),s)
62ifndef V 62ifneq ($(V),1)
63 QUIET_CC = @echo ' ' CC $@; 63 QUIET_CC = @echo ' ' CC $@;
64 QUIET_AR = @echo ' ' AR $@; 64 QUIET_AR = @echo ' ' AR $@;
65 QUIET_LINK = @echo ' ' LINK $@; 65 QUIET_LINK = @echo ' ' LINK $@;
diff --git a/tools/testing/selftests/net/psock_tpacket.c b/tools/testing/selftests/net/psock_tpacket.c
index c41b58640a05..24adf709bd9d 100644
--- a/tools/testing/selftests/net/psock_tpacket.c
+++ b/tools/testing/selftests/net/psock_tpacket.c
@@ -1,6 +1,7 @@
1/* 1/*
2 * Copyright 2013 Red Hat, Inc. 2 * Copyright 2013 Red Hat, Inc.
3 * Author: Daniel Borkmann <dborkman@redhat.com> 3 * Author: Daniel Borkmann <dborkman@redhat.com>
4 * Chetan Loke <loke.chetan@gmail.com> (TPACKET_V3 usage example)
4 * 5 *
5 * A basic test of packet socket's TPACKET_V1/TPACKET_V2/TPACKET_V3 behavior. 6 * A basic test of packet socket's TPACKET_V1/TPACKET_V2/TPACKET_V3 behavior.
6 * 7 *
@@ -71,18 +72,8 @@
71# define __align_tpacket(x) __attribute__((aligned(TPACKET_ALIGN(x)))) 72# define __align_tpacket(x) __attribute__((aligned(TPACKET_ALIGN(x))))
72#endif 73#endif
73 74
74#define BLOCK_STATUS(x) ((x)->h1.block_status)
75#define BLOCK_NUM_PKTS(x) ((x)->h1.num_pkts)
76#define BLOCK_O2FP(x) ((x)->h1.offset_to_first_pkt)
77#define BLOCK_LEN(x) ((x)->h1.blk_len)
78#define BLOCK_SNUM(x) ((x)->h1.seq_num)
79#define BLOCK_O2PRIV(x) ((x)->offset_to_priv)
80#define BLOCK_PRIV(x) ((void *) ((uint8_t *) (x) + BLOCK_O2PRIV(x)))
81#define BLOCK_HDR_LEN (ALIGN_8(sizeof(struct block_desc)))
82#define ALIGN_8(x) (((x) + 8 - 1) & ~(8 - 1))
83#define BLOCK_PLUS_PRIV(sz_pri) (BLOCK_HDR_LEN + ALIGN_8((sz_pri)))
84
85#define NUM_PACKETS 100 75#define NUM_PACKETS 100
76#define ALIGN_8(x) (((x) + 8 - 1) & ~(8 - 1))
86 77
87struct ring { 78struct ring {
88 struct iovec *rd; 79 struct iovec *rd;
@@ -476,41 +467,30 @@ static uint64_t __v3_prev_block_seq_num = 0;
476 467
477void __v3_test_block_seq_num(struct block_desc *pbd) 468void __v3_test_block_seq_num(struct block_desc *pbd)
478{ 469{
479 if (__v3_prev_block_seq_num + 1 != BLOCK_SNUM(pbd)) { 470 if (__v3_prev_block_seq_num + 1 != pbd->h1.seq_num) {
480 fprintf(stderr, "\nprev_block_seq_num:%"PRIu64", expected " 471 fprintf(stderr, "\nprev_block_seq_num:%"PRIu64", expected "
481 "seq:%"PRIu64" != actual seq:%"PRIu64"\n", 472 "seq:%"PRIu64" != actual seq:%"PRIu64"\n",
482 __v3_prev_block_seq_num, __v3_prev_block_seq_num + 1, 473 __v3_prev_block_seq_num, __v3_prev_block_seq_num + 1,
483 (uint64_t) BLOCK_SNUM(pbd)); 474 (uint64_t) pbd->h1.seq_num);
484 exit(1); 475 exit(1);
485 } 476 }
486 477
487 __v3_prev_block_seq_num = BLOCK_SNUM(pbd); 478 __v3_prev_block_seq_num = pbd->h1.seq_num;
488} 479}
489 480
490static void __v3_test_block_len(struct block_desc *pbd, uint32_t bytes, int block_num) 481static void __v3_test_block_len(struct block_desc *pbd, uint32_t bytes, int block_num)
491{ 482{
492 if (BLOCK_NUM_PKTS(pbd)) { 483 if (pbd->h1.num_pkts && bytes != pbd->h1.blk_len) {
493 if (bytes != BLOCK_LEN(pbd)) { 484 fprintf(stderr, "\nblock:%u with %upackets, expected "
494 fprintf(stderr, "\nblock:%u with %upackets, expected " 485 "len:%u != actual len:%u\n", block_num,
495 "len:%u != actual len:%u\n", block_num, 486 pbd->h1.num_pkts, bytes, pbd->h1.blk_len);
496 BLOCK_NUM_PKTS(pbd), bytes, BLOCK_LEN(pbd)); 487 exit(1);
497 exit(1);
498 }
499 } else {
500 if (BLOCK_LEN(pbd) != BLOCK_PLUS_PRIV(13)) {
501 fprintf(stderr, "\nblock:%u, expected len:%lu != "
502 "actual len:%u\n", block_num, BLOCK_HDR_LEN,
503 BLOCK_LEN(pbd));
504 exit(1);
505 }
506 } 488 }
507} 489}
508 490
509static void __v3_test_block_header(struct block_desc *pbd, const int block_num) 491static void __v3_test_block_header(struct block_desc *pbd, const int block_num)
510{ 492{
511 uint32_t block_status = BLOCK_STATUS(pbd); 493 if ((pbd->h1.block_status & TP_STATUS_USER) == 0) {
512
513 if ((block_status & TP_STATUS_USER) == 0) {
514 fprintf(stderr, "\nblock %u: not in TP_STATUS_USER\n", block_num); 494 fprintf(stderr, "\nblock %u: not in TP_STATUS_USER\n", block_num);
515 exit(1); 495 exit(1);
516 } 496 }
@@ -520,14 +500,15 @@ static void __v3_test_block_header(struct block_desc *pbd, const int block_num)
520 500
521static void __v3_walk_block(struct block_desc *pbd, const int block_num) 501static void __v3_walk_block(struct block_desc *pbd, const int block_num)
522{ 502{
523 int num_pkts = BLOCK_NUM_PKTS(pbd), i; 503 int num_pkts = pbd->h1.num_pkts, i;
524 unsigned long bytes = 0; 504 unsigned long bytes = 0, bytes_with_padding = ALIGN_8(sizeof(*pbd));
525 unsigned long bytes_with_padding = BLOCK_PLUS_PRIV(13);
526 struct tpacket3_hdr *ppd; 505 struct tpacket3_hdr *ppd;
527 506
528 __v3_test_block_header(pbd, block_num); 507 __v3_test_block_header(pbd, block_num);
529 508
530 ppd = (struct tpacket3_hdr *) ((uint8_t *) pbd + BLOCK_O2FP(pbd)); 509 ppd = (struct tpacket3_hdr *) ((uint8_t *) pbd +
510 pbd->h1.offset_to_first_pkt);
511
531 for (i = 0; i < num_pkts; ++i) { 512 for (i = 0; i < num_pkts; ++i) {
532 bytes += ppd->tp_snaplen; 513 bytes += ppd->tp_snaplen;
533 514
@@ -551,7 +532,7 @@ static void __v3_walk_block(struct block_desc *pbd, const int block_num)
551 532
552void __v3_flush_block(struct block_desc *pbd) 533void __v3_flush_block(struct block_desc *pbd)
553{ 534{
554 BLOCK_STATUS(pbd) = TP_STATUS_KERNEL; 535 pbd->h1.block_status = TP_STATUS_KERNEL;
555 __sync_synchronize(); 536 __sync_synchronize();
556} 537}
557 538
@@ -577,7 +558,7 @@ static void walk_v3_rx(int sock, struct ring *ring)
577 while (total_packets < NUM_PACKETS * 2) { 558 while (total_packets < NUM_PACKETS * 2) {
578 pbd = (struct block_desc *) ring->rd[block_num].iov_base; 559 pbd = (struct block_desc *) ring->rd[block_num].iov_base;
579 560
580 while ((BLOCK_STATUS(pbd) & TP_STATUS_USER) == 0) 561 while ((pbd->h1.block_status & TP_STATUS_USER) == 0)
581 poll(&pfd, 1, 1); 562 poll(&pfd, 1, 1);
582 563
583 __v3_walk_block(pbd, block_num); 564 __v3_walk_block(pbd, block_num);
@@ -624,8 +605,8 @@ static void __v1_v2_fill(struct ring *ring, unsigned int blocks)
624static void __v3_fill(struct ring *ring, unsigned int blocks) 605static void __v3_fill(struct ring *ring, unsigned int blocks)
625{ 606{
626 ring->req3.tp_retire_blk_tov = 64; 607 ring->req3.tp_retire_blk_tov = 64;
627 ring->req3.tp_sizeof_priv = 13; 608 ring->req3.tp_sizeof_priv = 0;
628 ring->req3.tp_feature_req_word |= TP_FT_REQ_FILL_RXHASH; 609 ring->req3.tp_feature_req_word = TP_FT_REQ_FILL_RXHASH;
629 610
630 ring->req3.tp_block_size = getpagesize() << 2; 611 ring->req3.tp_block_size = getpagesize() << 2;
631 ring->req3.tp_frame_size = TPACKET_ALIGNMENT << 7; 612 ring->req3.tp_frame_size = TPACKET_ALIGNMENT << 7;
diff --git a/tools/virtio/linux/module.h b/tools/virtio/linux/module.h
index 3039a7e972b6..28ce95a05997 100644
--- a/tools/virtio/linux/module.h
+++ b/tools/virtio/linux/module.h
@@ -1 +1,6 @@
1#include <linux/export.h> 1#include <linux/export.h>
2
3#define MODULE_LICENSE(__MODULE_LICENSE_value) \
4 static __attribute__((unused)) const char *__MODULE_LICENSE_name = \
5 __MODULE_LICENSE_value
6
diff --git a/tools/virtio/linux/virtio.h b/tools/virtio/linux/virtio.h
index cd801838156f..844783040703 100644
--- a/tools/virtio/linux/virtio.h
+++ b/tools/virtio/linux/virtio.h
@@ -45,9 +45,6 @@ struct virtqueue {
45 void *priv; 45 void *priv;
46}; 46};
47 47
48#define MODULE_LICENSE(__MODULE_LICENSE_value) \
49 const char *__MODULE_LICENSE_name = __MODULE_LICENSE_value
50
51/* Interfaces exported by virtio_ring. */ 48/* Interfaces exported by virtio_ring. */
52int virtqueue_add_sgs(struct virtqueue *vq, 49int virtqueue_add_sgs(struct virtqueue *vq,
53 struct scatterlist *sgs[], 50 struct scatterlist *sgs[],