diff options
Diffstat (limited to 'tools')
30 files changed, 587 insertions, 393 deletions
diff --git a/tools/hv/hv_fcopy_daemon.c b/tools/hv/hv_fcopy_daemon.c index 4ecc4fd0bc1b..fba1c75aa484 100644 --- a/tools/hv/hv_fcopy_daemon.c +++ b/tools/hv/hv_fcopy_daemon.c @@ -82,8 +82,10 @@ static int hv_start_fcopy(struct hv_start_fcopy *smsg) if (!access(target_fname, F_OK)) { syslog(LOG_INFO, "File: %s exists", target_fname); - if (!smsg->copy_flags & OVER_WRITE) + if (!(smsg->copy_flags & OVER_WRITE)) { + error = HV_ERROR_ALREADY_EXISTS; goto done; + } } target_fd = open(target_fname, O_RDWR | O_CREAT | O_CLOEXEC, 0744); diff --git a/tools/lib/api/fs/debugfs.c b/tools/lib/api/fs/debugfs.c index 7c4347962353..a74fba6d7743 100644 --- a/tools/lib/api/fs/debugfs.c +++ b/tools/lib/api/fs/debugfs.c @@ -12,8 +12,8 @@ char debugfs_mountpoint[PATH_MAX + 1] = "/sys/kernel/debug"; static const char * const debugfs_known_mountpoints[] = { - "/sys/kernel/debug/", - "/debug/", + "/sys/kernel/debug", + "/debug", 0, }; diff --git a/tools/lib/lockdep/Makefile b/tools/lib/lockdep/Makefile index 07b0b7542511..cb09d3ff8f58 100644 --- a/tools/lib/lockdep/Makefile +++ b/tools/lib/lockdep/Makefile @@ -1,13 +1,8 @@ -# liblockdep version -LL_VERSION = 0 -LL_PATCHLEVEL = 0 -LL_EXTRAVERSION = 1 - # file format version FILE_VERSION = 1 MAKEFLAGS += --no-print-directory - +LIBLOCKDEP_VERSION=$(shell make -sC ../../.. kernelversion) # Makefiles suck: This macro sets a default value of $(2) for the # variable named by $(1), unless the variable has been set by @@ -98,7 +93,7 @@ export prefix libdir bindir src obj libdir_SQ = $(subst ','\'',$(libdir)) bindir_SQ = $(subst ','\'',$(bindir)) -LIB_FILE = liblockdep.a liblockdep.so +LIB_FILE = liblockdep.a liblockdep.so.$(LIBLOCKDEP_VERSION) BIN_FILE = lockdep CONFIG_INCLUDES = @@ -110,8 +105,6 @@ N = export Q VERBOSE -LIBLOCKDEP_VERSION = $(LL_VERSION).$(LL_PATCHLEVEL).$(LL_EXTRAVERSION) - INCLUDES = -I. -I/usr/local/include -I./uinclude -I./include $(CONFIG_INCLUDES) # Set compile option CFLAGS if not set elsewhere @@ -146,7 +139,7 @@ do_app_build = \ do_compile_shared_library = \ ($(print_shared_lib_compile) \ - $(CC) --shared $^ -o $@ -lpthread -ldl) + $(CC) --shared $^ -o $@ -lpthread -ldl -Wl,-soname='"$@"';$(shell ln -s $@ liblockdep.so)) do_build_static_lib = \ ($(print_static_lib_build) \ @@ -177,7 +170,7 @@ all: all_cmd all_cmd: $(CMD_TARGETS) -liblockdep.so: $(PEVENT_LIB_OBJS) +liblockdep.so.$(LIBLOCKDEP_VERSION): $(PEVENT_LIB_OBJS) $(Q)$(do_compile_shared_library) liblockdep.a: $(PEVENT_LIB_OBJS) diff --git a/tools/lib/lockdep/uinclude/linux/lockdep.h b/tools/lib/lockdep/uinclude/linux/lockdep.h index d0f5d6e50214..c1552c28507e 100644 --- a/tools/lib/lockdep/uinclude/linux/lockdep.h +++ b/tools/lib/lockdep/uinclude/linux/lockdep.h @@ -10,6 +10,9 @@ #define MAX_LOCK_DEPTH 2000UL +#define asmlinkage +#define __visible + #include "../../../include/linux/lockdep.h" struct task_struct { diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index 1587ea392ad6..b83184f2d484 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c @@ -50,6 +50,18 @@ static int show_warning = 1; warning(fmt, ##__VA_ARGS__); \ } while (0) +#define do_warning_event(event, fmt, ...) \ + do { \ + if (!show_warning) \ + continue; \ + \ + if (event) \ + warning("[%s:%s] " fmt, event->system, \ + event->name, ##__VA_ARGS__); \ + else \ + warning(fmt, ##__VA_ARGS__); \ + } while (0) + static void init_input_buf(const char *buf, unsigned long long size) { input_buf = buf; @@ -1355,7 +1367,7 @@ static int event_read_fields(struct event_format *event, struct format_field **f } if (!field->type) { - do_warning("%s: no type found", __func__); + do_warning_event(event, "%s: no type found", __func__); goto fail; } field->name = last_token; @@ -1402,7 +1414,7 @@ static int event_read_fields(struct event_format *event, struct format_field **f free_token(token); type = read_token(&token); if (type == EVENT_NONE) { - do_warning("failed to find token"); + do_warning_event(event, "failed to find token"); goto fail; } } @@ -1636,7 +1648,7 @@ process_cond(struct event_format *event, struct print_arg *top, char **tok) right = alloc_arg(); if (!arg || !left || !right) { - do_warning("%s: not enough memory!", __func__); + do_warning_event(event, "%s: not enough memory!", __func__); /* arg will be freed at out_free */ free_arg(left); free_arg(right); @@ -1686,7 +1698,7 @@ process_array(struct event_format *event, struct print_arg *top, char **tok) arg = alloc_arg(); if (!arg) { - do_warning("%s: not enough memory!", __func__); + do_warning_event(event, "%s: not enough memory!", __func__); /* '*tok' is set to top->op.op. No need to free. */ *tok = NULL; return EVENT_ERROR; @@ -1792,7 +1804,7 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) if (arg->type == PRINT_OP && !arg->op.left) { /* handle single op */ if (token[1]) { - do_warning("bad op token %s", token); + do_warning_event(event, "bad op token %s", token); goto out_free; } switch (token[0]) { @@ -1802,7 +1814,7 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) case '-': break; default: - do_warning("bad op token %s", token); + do_warning_event(event, "bad op token %s", token); goto out_free; } @@ -1888,7 +1900,7 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) char *new_atom; if (left->type != PRINT_ATOM) { - do_warning("bad pointer type"); + do_warning_event(event, "bad pointer type"); goto out_free; } new_atom = realloc(left->atom.atom, @@ -1930,7 +1942,7 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) type = process_array(event, arg, tok); } else { - do_warning("unknown op '%s'", token); + do_warning_event(event, "unknown op '%s'", token); event->flags |= EVENT_FL_FAILED; /* the arg is now the left side */ goto out_free; @@ -1951,7 +1963,7 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) return type; out_warn_free: - do_warning("%s: not enough memory!", __func__); + do_warning_event(event, "%s: not enough memory!", __func__); out_free: free_token(token); *tok = NULL; @@ -2385,7 +2397,7 @@ process_flags(struct event_format *event, struct print_arg *arg, char **tok) field = alloc_arg(); if (!field) { - do_warning("%s: not enough memory!", __func__); + do_warning_event(event, "%s: not enough memory!", __func__); goto out_free; } @@ -2438,7 +2450,7 @@ process_symbols(struct event_format *event, struct print_arg *arg, char **tok) field = alloc_arg(); if (!field) { - do_warning("%s: not enough memory!", __func__); + do_warning_event(event, "%s: not enough memory!", __func__); goto out_free; } @@ -2477,7 +2489,7 @@ process_hex(struct event_format *event, struct print_arg *arg, char **tok) field = alloc_arg(); if (!field) { - do_warning("%s: not enough memory!", __func__); + do_warning_event(event, "%s: not enough memory!", __func__); goto out_free; } @@ -2492,7 +2504,7 @@ process_hex(struct event_format *event, struct print_arg *arg, char **tok) field = alloc_arg(); if (!field) { - do_warning("%s: not enough memory!", __func__); + do_warning_event(event, "%s: not enough memory!", __func__); *tok = NULL; return EVENT_ERROR; } @@ -2555,7 +2567,7 @@ process_dynamic_array(struct event_format *event, struct print_arg *arg, char ** free_token(token); arg = alloc_arg(); if (!arg) { - do_warning("%s: not enough memory!", __func__); + do_warning_event(event, "%s: not enough memory!", __func__); *tok = NULL; return EVENT_ERROR; } @@ -2614,13 +2626,14 @@ process_paren(struct event_format *event, struct print_arg *arg, char **tok) /* prevous must be an atom */ if (arg->type != PRINT_ATOM) { - do_warning("previous needed to be PRINT_ATOM"); + do_warning_event(event, "previous needed to be PRINT_ATOM"); goto out_free; } item_arg = alloc_arg(); if (!item_arg) { - do_warning("%s: not enough memory!", __func__); + do_warning_event(event, "%s: not enough memory!", + __func__); goto out_free; } @@ -2721,21 +2734,24 @@ process_func_handler(struct event_format *event, struct pevent_function_handler for (i = 0; i < func->nr_args; i++) { farg = alloc_arg(); if (!farg) { - do_warning("%s: not enough memory!", __func__); + do_warning_event(event, "%s: not enough memory!", + __func__); return EVENT_ERROR; } type = process_arg(event, farg, &token); if (i < (func->nr_args - 1)) { if (type != EVENT_DELIM || strcmp(token, ",") != 0) { - warning("Error: function '%s()' expects %d arguments but event %s only uses %d", + do_warning_event(event, + "Error: function '%s()' expects %d arguments but event %s only uses %d", func->name, func->nr_args, event->name, i + 1); goto err; } } else { if (type != EVENT_DELIM || strcmp(token, ")") != 0) { - warning("Error: function '%s()' only expects %d arguments but event %s has more", + do_warning_event(event, + "Error: function '%s()' only expects %d arguments but event %s has more", func->name, func->nr_args, event->name); goto err; } @@ -2792,7 +2808,7 @@ process_function(struct event_format *event, struct print_arg *arg, return process_func_handler(event, func, arg, tok); } - do_warning("function %s not defined", token); + do_warning_event(event, "function %s not defined", token); free_token(token); return EVENT_ERROR; } @@ -2878,7 +2894,7 @@ process_arg_token(struct event_format *event, struct print_arg *arg, case EVENT_ERROR ... EVENT_NEWLINE: default: - do_warning("unexpected type %d", type); + do_warning_event(event, "unexpected type %d", type); return EVENT_ERROR; } *tok = token; @@ -2901,7 +2917,8 @@ static int event_read_print_args(struct event_format *event, struct print_arg ** arg = alloc_arg(); if (!arg) { - do_warning("%s: not enough memory!", __func__); + do_warning_event(event, "%s: not enough memory!", + __func__); return -1; } @@ -3481,11 +3498,12 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg return val; out_warning_op: - do_warning("%s: unknown op '%s'", __func__, arg->op.op); + do_warning_event(event, "%s: unknown op '%s'", __func__, arg->op.op); return 0; out_warning_field: - do_warning("%s: field %s not found", __func__, arg->field.name); + do_warning_event(event, "%s: field %s not found", + __func__, arg->field.name); return 0; } @@ -3591,7 +3609,8 @@ static void print_str_arg(struct trace_seq *s, void *data, int size, } str = malloc(len + 1); if (!str) { - do_warning("%s: not enough memory!", __func__); + do_warning_event(event, "%s: not enough memory!", + __func__); return; } memcpy(str, data + field->offset, len); @@ -3697,7 +3716,8 @@ static void print_str_arg(struct trace_seq *s, void *data, int size, return; out_warning_field: - do_warning("%s: field %s not found", __func__, arg->field.name); + do_warning_event(event, "%s: field %s not found", + __func__, arg->field.name); } static unsigned long long @@ -3742,14 +3762,16 @@ process_defined_func(struct trace_seq *s, void *data, int size, trace_seq_terminate(&str); string = malloc(sizeof(*string)); if (!string) { - do_warning("%s(%d): malloc str", __func__, __LINE__); + do_warning_event(event, "%s(%d): malloc str", + __func__, __LINE__); goto out_free; } string->next = strings; string->str = strdup(str.buffer); if (!string->str) { free(string); - do_warning("%s(%d): malloc str", __func__, __LINE__); + do_warning_event(event, "%s(%d): malloc str", + __func__, __LINE__); goto out_free; } args[i] = (uintptr_t)string->str; @@ -3761,7 +3783,7 @@ process_defined_func(struct trace_seq *s, void *data, int size, * Something went totally wrong, this is not * an input error, something in this code broke. */ - do_warning("Unexpected end of arguments\n"); + do_warning_event(event, "Unexpected end of arguments\n"); goto out_free; } farg = farg->next; @@ -3811,12 +3833,12 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc if (!field) { field = pevent_find_field(event, "buf"); if (!field) { - do_warning("can't find buffer field for binary printk"); + do_warning_event(event, "can't find buffer field for binary printk"); return NULL; } ip_field = pevent_find_field(event, "ip"); if (!ip_field) { - do_warning("can't find ip field for binary printk"); + do_warning_event(event, "can't find ip field for binary printk"); return NULL; } pevent->bprint_buf_field = field; @@ -3830,7 +3852,8 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc */ args = alloc_arg(); if (!args) { - do_warning("%s(%d): not enough memory!", __func__, __LINE__); + do_warning_event(event, "%s(%d): not enough memory!", + __func__, __LINE__); return NULL; } arg = args; @@ -3896,7 +3919,7 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc bptr += vsize; arg = alloc_arg(); if (!arg) { - do_warning("%s(%d): not enough memory!", + do_warning_event(event, "%s(%d): not enough memory!", __func__, __LINE__); goto out_free; } @@ -3919,7 +3942,7 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc case 's': arg = alloc_arg(); if (!arg) { - do_warning("%s(%d): not enough memory!", + do_warning_event(event, "%s(%d): not enough memory!", __func__, __LINE__); goto out_free; } @@ -3959,7 +3982,7 @@ get_bprint_format(void *data, int size __maybe_unused, if (!field) { field = pevent_find_field(event, "fmt"); if (!field) { - do_warning("can't find format field for binary printk"); + do_warning_event(event, "can't find format field for binary printk"); return NULL; } pevent->bprint_fmt_field = field; @@ -4003,8 +4026,8 @@ static void print_mac_arg(struct trace_seq *s, int mac, void *data, int size, arg->field.field = pevent_find_any_field(event, arg->field.name); if (!arg->field.field) { - do_warning("%s: field %s not found", - __func__, arg->field.name); + do_warning_event(event, "%s: field %s not found", + __func__, arg->field.name); return; } } @@ -4176,7 +4199,7 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event case '*': /* The argument is the length. */ if (!arg) { - do_warning("no argument match"); + do_warning_event(event, "no argument match"); event->flags |= EVENT_FL_FAILED; goto out_failed; } @@ -4213,7 +4236,7 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event case 'X': case 'u': if (!arg) { - do_warning("no argument match"); + do_warning_event(event, "no argument match"); event->flags |= EVENT_FL_FAILED; goto out_failed; } @@ -4223,7 +4246,7 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event /* should never happen */ if (len > 31) { - do_warning("bad format!"); + do_warning_event(event, "bad format!"); event->flags |= EVENT_FL_FAILED; len = 31; } @@ -4290,13 +4313,13 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event trace_seq_printf(s, format, (long long)val); break; default: - do_warning("bad count (%d)", ls); + do_warning_event(event, "bad count (%d)", ls); event->flags |= EVENT_FL_FAILED; } break; case 's': if (!arg) { - do_warning("no matching argument"); + do_warning_event(event, "no matching argument"); event->flags |= EVENT_FL_FAILED; goto out_failed; } @@ -4306,7 +4329,7 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event /* should never happen */ if (len > 31) { - do_warning("bad format!"); + do_warning_event(event, "bad format!"); event->flags |= EVENT_FL_FAILED; len = 31; } @@ -4321,6 +4344,7 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event format, len_arg, arg); trace_seq_terminate(&p); trace_seq_puts(s, p.buffer); + trace_seq_destroy(&p); arg = arg->next; break; default: diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h index 791c539374c7..feab94281634 100644 --- a/tools/lib/traceevent/event-parse.h +++ b/tools/lib/traceevent/event-parse.h @@ -876,8 +876,8 @@ struct event_filter { struct event_filter *pevent_filter_alloc(struct pevent *pevent); /* for backward compatibility */ -#define FILTER_NONE PEVENT_ERRNO__FILTER_NOT_FOUND -#define FILTER_NOEXIST PEVENT_ERRNO__NO_FILTER +#define FILTER_NONE PEVENT_ERRNO__NO_FILTER +#define FILTER_NOEXIST PEVENT_ERRNO__FILTER_NOT_FOUND #define FILTER_MISS PEVENT_ERRNO__FILTER_MISS #define FILTER_MATCH PEVENT_ERRNO__FILTER_MATCH diff --git a/tools/net/bpf_dbg.c b/tools/net/bpf_dbg.c index 65dc757f7f7b..9a287bec695a 100644 --- a/tools/net/bpf_dbg.c +++ b/tools/net/bpf_dbg.c @@ -87,9 +87,6 @@ __attribute__ ((format (printf, (pos_fmtstr), (pos_fmtargs)))) #endif -#define CMD(_name, _func) { .name = _name, .func = _func, } -#define OP(_op, _name) [_op] = _name - enum { CMD_OK, CMD_ERR, @@ -145,32 +142,32 @@ static size_t pcap_map_size = 0; static char *pcap_ptr_va_start, *pcap_ptr_va_curr; static const char * const op_table[] = { - OP(BPF_ST, "st"), - OP(BPF_STX, "stx"), - OP(BPF_LD_B, "ldb"), - OP(BPF_LD_H, "ldh"), - OP(BPF_LD_W, "ld"), - OP(BPF_LDX, "ldx"), - OP(BPF_LDX_B, "ldxb"), - OP(BPF_JMP_JA, "ja"), - OP(BPF_JMP_JEQ, "jeq"), - OP(BPF_JMP_JGT, "jgt"), - OP(BPF_JMP_JGE, "jge"), - OP(BPF_JMP_JSET, "jset"), - OP(BPF_ALU_ADD, "add"), - OP(BPF_ALU_SUB, "sub"), - OP(BPF_ALU_MUL, "mul"), - OP(BPF_ALU_DIV, "div"), - OP(BPF_ALU_MOD, "mod"), - OP(BPF_ALU_NEG, "neg"), - OP(BPF_ALU_AND, "and"), - OP(BPF_ALU_OR, "or"), - OP(BPF_ALU_XOR, "xor"), - OP(BPF_ALU_LSH, "lsh"), - OP(BPF_ALU_RSH, "rsh"), - OP(BPF_MISC_TAX, "tax"), - OP(BPF_MISC_TXA, "txa"), - OP(BPF_RET, "ret"), + [BPF_ST] = "st", + [BPF_STX] = "stx", + [BPF_LD_B] = "ldb", + [BPF_LD_H] = "ldh", + [BPF_LD_W] = "ld", + [BPF_LDX] = "ldx", + [BPF_LDX_B] = "ldxb", + [BPF_JMP_JA] = "ja", + [BPF_JMP_JEQ] = "jeq", + [BPF_JMP_JGT] = "jgt", + [BPF_JMP_JGE] = "jge", + [BPF_JMP_JSET] = "jset", + [BPF_ALU_ADD] = "add", + [BPF_ALU_SUB] = "sub", + [BPF_ALU_MUL] = "mul", + [BPF_ALU_DIV] = "div", + [BPF_ALU_MOD] = "mod", + [BPF_ALU_NEG] = "neg", + [BPF_ALU_AND] = "and", + [BPF_ALU_OR] = "or", + [BPF_ALU_XOR] = "xor", + [BPF_ALU_LSH] = "lsh", + [BPF_ALU_RSH] = "rsh", + [BPF_MISC_TAX] = "tax", + [BPF_MISC_TXA] = "txa", + [BPF_RET] = "ret", }; static __check_format_printf(1, 2) int rl_printf(const char *fmt, ...) @@ -823,7 +820,7 @@ do_div: r->A &= r->X; break; case BPF_ALU_AND | BPF_K: - r->A &= r->X; + r->A &= K; break; case BPF_ALU_OR | BPF_X: r->A |= r->X; @@ -1127,7 +1124,6 @@ static int cmd_step(char *num) static int cmd_select(char *num) { unsigned int which, i; - struct pcap_pkthdr *hdr; bool have_next = true; if (!pcap_loaded() || strlen(num) == 0) @@ -1144,7 +1140,7 @@ static int cmd_select(char *num) for (i = 0; i < which && (have_next = pcap_next_pkt()); i++) /* noop */; - if (!have_next || (hdr = pcap_curr_pkt()) == NULL) { + if (!have_next || pcap_curr_pkt() == NULL) { rl_printf("no packet #%u available!\n", which); pcap_reset_pkt(); return CMD_ERR; @@ -1177,9 +1173,8 @@ static int cmd_breakpoint(char *subcmd) static int cmd_run(char *num) { static uint32_t pass = 0, fail = 0; - struct pcap_pkthdr *hdr; bool has_limit = true; - int ret, pkts = 0, i = 0; + int pkts = 0, i = 0; if (!bpf_prog_loaded() || !pcap_loaded()) return CMD_ERR; @@ -1189,10 +1184,10 @@ static int cmd_run(char *num) has_limit = false; do { - hdr = pcap_curr_pkt(); - ret = bpf_run_all(bpf_image, bpf_prog_len, - (uint8_t *) hdr + sizeof(*hdr), - hdr->caplen, hdr->len); + struct pcap_pkthdr *hdr = pcap_curr_pkt(); + int ret = bpf_run_all(bpf_image, bpf_prog_len, + (uint8_t *) hdr + sizeof(*hdr), + hdr->caplen, hdr->len); if (ret > 0) pass++; else if (ret == 0) @@ -1245,14 +1240,14 @@ static int cmd_quit(char *dontcare) } static const struct shell_cmd cmds[] = { - CMD("load", cmd_load), - CMD("select", cmd_select), - CMD("step", cmd_step), - CMD("run", cmd_run), - CMD("breakpoint", cmd_breakpoint), - CMD("disassemble", cmd_disassemble), - CMD("dump", cmd_dump), - CMD("quit", cmd_quit), + { .name = "load", .func = cmd_load }, + { .name = "select", .func = cmd_select }, + { .name = "step", .func = cmd_step }, + { .name = "run", .func = cmd_run }, + { .name = "breakpoint", .func = cmd_breakpoint }, + { .name = "disassemble", .func = cmd_disassemble }, + { .name = "dump", .func = cmd_dump }, + { .name = "quit", .func = cmd_quit }, }; static int execf(char *arg) @@ -1280,7 +1275,6 @@ out: static char *shell_comp_gen(const char *buf, int state) { static int list_index, len; - const char *name; if (!state) { list_index = 0; @@ -1288,9 +1282,9 @@ static char *shell_comp_gen(const char *buf, int state) } for (; list_index < array_size(cmds); ) { - name = cmds[list_index].name; - list_index++; + const char *name = cmds[list_index].name; + list_index++; if (strncmp(name, buf, len) == 0) return strdup(name); } @@ -1322,16 +1316,9 @@ static void init_shell(FILE *fin, FILE *fout) { char file[128]; - memset(file, 0, sizeof(file)); - snprintf(file, sizeof(file) - 1, - "%s/.bpf_dbg_history", getenv("HOME")); - + snprintf(file, sizeof(file), "%s/.bpf_dbg_history", getenv("HOME")); read_history(file); - memset(file, 0, sizeof(file)); - snprintf(file, sizeof(file) - 1, - "%s/.bpf_dbg_init", getenv("HOME")); - rl_instream = fin; rl_outstream = fout; @@ -1348,37 +1335,41 @@ static void init_shell(FILE *fin, FILE *fout) rl_bind_key_in_map('\t', rl_complete, emacs_meta_keymap); rl_bind_key_in_map('\033', rl_complete, emacs_meta_keymap); + snprintf(file, sizeof(file), "%s/.bpf_dbg_init", getenv("HOME")); rl_read_init_file(file); + rl_prep_terminal(0); rl_set_signals(); signal(SIGINT, intr_shell); } -static void exit_shell(void) +static void exit_shell(FILE *fin, FILE *fout) { char file[128]; - memset(file, 0, sizeof(file)); - snprintf(file, sizeof(file) - 1, - "%s/.bpf_dbg_history", getenv("HOME")); - + snprintf(file, sizeof(file), "%s/.bpf_dbg_history", getenv("HOME")); write_history(file); + clear_history(); rl_deprep_terminal(); try_close_pcap(); + + if (fin != stdin) + fclose(fin); + if (fout != stdout) + fclose(fout); } static int run_shell_loop(FILE *fin, FILE *fout) { char *buf; - int ret; init_shell(fin, fout); while ((buf = readline("> ")) != NULL) { - ret = execf(buf); + int ret = execf(buf); if (ret == CMD_EX) break; if (ret == CMD_OK && strlen(buf) > 0) @@ -1387,7 +1378,7 @@ static int run_shell_loop(FILE *fin, FILE *fout) free(buf); } - exit_shell(); + exit_shell(fin, fout); return 0; } diff --git a/tools/perf/Documentation/perf-bench.txt b/tools/perf/Documentation/perf-bench.txt index 7065cd6fbdfc..4464ad770d51 100644 --- a/tools/perf/Documentation/perf-bench.txt +++ b/tools/perf/Documentation/perf-bench.txt @@ -48,6 +48,12 @@ SUBSYSTEM 'mem':: Memory access performance. +'numa':: + NUMA scheduling and MM benchmarks. + +'futex':: + Futex stressing benchmarks. + 'all':: All benchmark subsystems. @@ -187,6 +193,22 @@ Show only the result with page faults before memset. --no-prefault:: Show only the result without page faults before memset. +SUITES FOR 'numa' +~~~~~~~~~~~~~~~~~ +*mem*:: +Suite for evaluating NUMA workloads. + +SUITES FOR 'futex' +~~~~~~~~~~~~~~~~~~ +*hash*:: +Suite for evaluating hash tables. + +*wake*:: +Suite for evaluating wake calls. + +*requeue*:: +Suite for evaluating requeue calls. + SEE ALSO -------- linkperf:perf[1] diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt index cdd8d4946dba..976b00c6cdb1 100644 --- a/tools/perf/Documentation/perf-top.txt +++ b/tools/perf/Documentation/perf-top.txt @@ -87,7 +87,6 @@ Default is to monitor all CPUS. --realtime=<priority>:: Collect data with this RT SCHED_FIFO priority. --s <symbol>:: --sym-annotate=<symbol>:: Annotate this symbol. diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 50d875d970c4..895edd32930c 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -192,13 +192,13 @@ endif export PERL_PATH $(OUTPUT)util/parse-events-flex.c: util/parse-events.l $(OUTPUT)util/parse-events-bison.c - $(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/parse-events-flex.h $(PARSER_DEBUG_FLEX) -t util/parse-events.l > $(OUTPUT)util/parse-events-flex.c + $(QUIET_FLEX)$(FLEX) -o $@ --header-file=$(OUTPUT)util/parse-events-flex.h $(PARSER_DEBUG_FLEX) util/parse-events.l $(OUTPUT)util/parse-events-bison.c: util/parse-events.y $(QUIET_BISON)$(BISON) -v util/parse-events.y -d $(PARSER_DEBUG_BISON) -o $(OUTPUT)util/parse-events-bison.c -p parse_events_ $(OUTPUT)util/pmu-flex.c: util/pmu.l $(OUTPUT)util/pmu-bison.c - $(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/pmu-flex.h -t util/pmu.l > $(OUTPUT)util/pmu-flex.c + $(QUIET_FLEX)$(FLEX) -o $@ --header-file=$(OUTPUT)util/pmu-flex.h util/pmu.l $(OUTPUT)util/pmu-bison.c: util/pmu.y $(QUIET_BISON)$(BISON) -v util/pmu.y -d -o $(OUTPUT)util/pmu-bison.c -p perf_pmu_ @@ -589,7 +589,7 @@ $(GTK_OBJS): $(OUTPUT)%.o: %.c $(LIB_H) $(QUIET_CC)$(CC) -o $@ -c -fPIC $(CFLAGS) $(GTK_CFLAGS) $< $(OUTPUT)libperf-gtk.so: $(GTK_OBJS) $(PERFLIBS) - $(QUIET_LINK)$(CC) -o $@ -shared $(ALL_LDFLAGS) $(filter %.o,$^) $(GTK_LIBS) + $(QUIET_LINK)$(CC) -o $@ -shared $(LDFLAGS) $(filter %.o,$^) $(GTK_LIBS) $(OUTPUT)builtin-help.o: builtin-help.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \ diff --git a/tools/perf/arch/x86/tests/dwarf-unwind.c b/tools/perf/arch/x86/tests/dwarf-unwind.c index b602ad93ce63..83bc2385e6d3 100644 --- a/tools/perf/arch/x86/tests/dwarf-unwind.c +++ b/tools/perf/arch/x86/tests/dwarf-unwind.c @@ -23,9 +23,10 @@ static int sample_ustack(struct perf_sample *sample, sp = (unsigned long) regs[PERF_REG_X86_SP]; - map = map_groups__find(&thread->mg, MAP__FUNCTION, (u64) sp); + map = map_groups__find(&thread->mg, MAP__VARIABLE, (u64) sp); if (!map) { pr_debug("failed to get stack map\n"); + free(buf); return -1; } diff --git a/tools/perf/arch/x86/tests/regs_load.S b/tools/perf/arch/x86/tests/regs_load.S index 99167bf644ea..60875d5c556c 100644 --- a/tools/perf/arch/x86/tests/regs_load.S +++ b/tools/perf/arch/x86/tests/regs_load.S @@ -1,4 +1,3 @@ - #include <linux/linkage.h> #define AX 0 @@ -90,3 +89,10 @@ ENTRY(perf_regs_load) ret ENDPROC(perf_regs_load) #endif + +/* + * We need to provide note.GNU-stack section, saying that we want + * NOT executable stack. Otherwise the final linking will assume that + * the ELF stack should not be restricted at all and set it RWX. + */ +.section .note.GNU-stack,"",@progbits diff --git a/tools/perf/bench/numa.c b/tools/perf/bench/numa.c index 97d86d828190..ebfa163b80b5 100644 --- a/tools/perf/bench/numa.c +++ b/tools/perf/bench/numa.c @@ -1593,6 +1593,10 @@ static void init_params(struct params *p, const char *name, int argc, const char p->data_rand_walk = true; p->nr_loops = -1; p->init_random = true; + p->mb_global_str = "1"; + p->nr_proc = 1; + p->nr_threads = 1; + p->nr_secs = 5; p->run_all = argc == 1; } diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 21c164b8f9db..0f1e5a2f6ad7 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -404,6 +404,7 @@ static struct kvm_event *kvm_alloc_init_event(struct event_key *key) } event->key = *key; + init_stats(&event->total.stats); return event; } diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index eb524f91bffe..8ce62ef7f6c3 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -374,7 +374,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) session = perf_session__new(file, false, NULL); if (session == NULL) { - pr_err("Not enough memory for reading perf file header\n"); + pr_err("Perf session creation failed.\n"); return -1; } diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 8b0e1c9234d9..65a151e36067 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -174,13 +174,20 @@ static inline int perf_evsel__nr_cpus(struct perf_evsel *evsel) static void perf_evsel__reset_stat_priv(struct perf_evsel *evsel) { - memset(evsel->priv, 0, sizeof(struct perf_stat)); + int i; + struct perf_stat *ps = evsel->priv; + + for (i = 0; i < 3; i++) + init_stats(&ps->res_stats[i]); } static int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel) { evsel->priv = zalloc(sizeof(struct perf_stat)); - return evsel->priv == NULL ? -ENOMEM : 0; + if (evsel == NULL) + return -ENOMEM; + perf_evsel__reset_stat_priv(evsel); + return 0; } static void perf_evsel__free_stat_priv(struct perf_evsel *evsel) diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index c23418225c2c..802cf544202b 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -34,6 +34,14 @@ ifeq ($(ARCH),arm) LIBUNWIND_LIBS = -lunwind -lunwind-arm endif +# So far there's only x86 libdw unwind support merged in perf. +# Disable it on all other architectures in case libdw unwind +# support is detected in system. Add supported architectures +# to the check. +ifneq ($(ARCH),x86) + NO_LIBDW_DWARF_UNWIND := 1 +endif + ifeq ($(LIBUNWIND_LIBS),) NO_LIBUNWIND := 1 else @@ -65,10 +73,9 @@ ifndef NO_LIBELF ifdef LIBDW_DIR LIBDW_CFLAGS := -I$(LIBDW_DIR)/include LIBDW_LDFLAGS := -L$(LIBDW_DIR)/lib - - FEATURE_CHECK_CFLAGS-libdw-dwarf-unwind := $(LIBDW_CFLAGS) - FEATURE_CHECK_LDFLAGS-libdw-dwarf-unwind := $(LIBDW_LDFLAGS) -ldw endif + FEATURE_CHECK_CFLAGS-libdw-dwarf-unwind := $(LIBDW_CFLAGS) + FEATURE_CHECK_LDFLAGS-libdw-dwarf-unwind := $(LIBDW_LDFLAGS) -ldw endif # include ARCH specific config @@ -110,6 +117,10 @@ CFLAGS += -Wall CFLAGS += -Wextra CFLAGS += -std=gnu99 +# Enforce a non-executable stack, as we may regress (again) in the future by +# adding assembler files missing the .GNU-stack linker note. +LDFLAGS += -Wl,-z,noexecstack + EXTLIBS = -lelf -lpthread -lrt -lm -ldl ifneq ($(OUTPUT),) @@ -187,7 +198,10 @@ VF_FEATURE_TESTS = \ stackprotector-all \ timerfd \ libunwind-debug-frame \ - bionic + bionic \ + liberty \ + liberty-z \ + cplus-demangle # Set FEATURE_CHECK_(C|LD)FLAGS-all for all CORE_FEATURE_TESTS features. # If in the future we need per-feature checks/flags for features not @@ -278,6 +292,8 @@ else NO_LIBELF := 1 NO_DWARF := 1 NO_DEMANGLE := 1 + NO_LIBUNWIND := 1 + NO_LIBDW_DWARF_UNWIND := 1 else msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]/glibc-static); endif @@ -503,7 +519,21 @@ else endif ifeq ($(feature-libbfd), 1) - EXTLIBS += -lbfd -lz -liberty + EXTLIBS += -lbfd + + # call all detections now so we get correct + # status in VF output + $(call feature_check,liberty) + $(call feature_check,liberty-z) + $(call feature_check,cplus-demangle) + + ifeq ($(feature-liberty), 1) + EXTLIBS += -liberty + else + ifeq ($(feature-liberty-z), 1) + EXTLIBS += -liberty -lz + endif + endif endif ifdef NO_DEMANGLE @@ -514,15 +544,10 @@ else CFLAGS += -DHAVE_CPLUS_DEMANGLE_SUPPORT else ifneq ($(feature-libbfd), 1) - $(call feature_check,liberty) - ifeq ($(feature-liberty), 1) - EXTLIBS += -lbfd -liberty - else - $(call feature_check,liberty-z) - ifeq ($(feature-liberty-z), 1) - EXTLIBS += -lbfd -liberty -lz - else - $(call feature_check,cplus-demangle) + ifneq ($(feature-liberty), 1) + ifneq ($(feature-liberty-z), 1) + # we dont have neither HAVE_CPLUS_DEMANGLE_SUPPORT + # or any of 'bfd iberty z' trinity ifeq ($(feature-cplus-demangle), 1) EXTLIBS += -liberty CFLAGS += -DHAVE_CPLUS_DEMANGLE_SUPPORT diff --git a/tools/perf/config/Makefile.arch b/tools/perf/config/Makefile.arch index fef8ae922800..4b06719ee984 100644 --- a/tools/perf/config/Makefile.arch +++ b/tools/perf/config/Makefile.arch @@ -5,7 +5,8 @@ ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \ -e s/arm.*/arm/ -e s/sa110/arm/ \ -e s/s390x/s390/ -e s/parisc64/parisc/ \ -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \ - -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ ) + -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ \ + -e s/tile.*/tile/ ) # Additional ARCH settings for x86 ifeq ($(ARCH),i386) diff --git a/tools/perf/perf.h b/tools/perf/perf.h index e18a8b5e6953..5c11ecad02a9 100644 --- a/tools/perf/perf.h +++ b/tools/perf/perf.h @@ -145,6 +145,14 @@ #define CPUINFO_PROC "core ID" #endif +#ifdef __tile__ +#define mb() asm volatile ("mf" ::: "memory") +#define wmb() asm volatile ("mf" ::: "memory") +#define rmb() asm volatile ("mf" ::: "memory") +#define cpu_relax() asm volatile ("mfspr zero, PASS" ::: "memory") +#define CPUINFO_PROC "model name" +#endif + #define barrier() asm volatile ("" ::: "memory") #ifndef cpu_relax diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 653a8fe2db95..bfb186900ac0 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -504,6 +504,7 @@ static int do_test_code_reading(bool try_kcore) if (ret < 0) { if (!excl_kernel) { excl_kernel = true; + perf_evlist__set_maps(evlist, NULL, NULL); perf_evlist__delete(evlist); evlist = NULL; continue; diff --git a/tools/perf/tests/make b/tools/perf/tests/make index 5daeae1cb4c0..2f92d6e7ee00 100644 --- a/tools/perf/tests/make +++ b/tools/perf/tests/make @@ -46,6 +46,7 @@ make_install_man := install-man make_install_html := install-html make_install_info := install-info make_install_pdf := install-pdf +make_static := LDFLAGS=-static # all the NO_* variable combined make_minimal := NO_LIBPERL=1 NO_LIBPYTHON=1 NO_NEWT=1 NO_GTK2=1 @@ -87,6 +88,7 @@ run += make_install_bin # run += make_install_info # run += make_install_pdf run += make_minimal +run += make_static ifneq ($(call has,ctags),) run += make_tags diff --git a/tools/perf/util/data.c b/tools/perf/util/data.c index 1fbcd8bdc11b..55de44ecebef 100644 --- a/tools/perf/util/data.c +++ b/tools/perf/util/data.c @@ -86,10 +86,17 @@ static int open_file_read(struct perf_data_file *file) static int open_file_write(struct perf_data_file *file) { + int fd; + if (check_backup(file)) return -1; - return open(file->path, O_CREAT|O_RDWR|O_TRUNC, S_IRUSR|S_IWUSR); + fd = open(file->path, O_CREAT|O_RDWR|O_TRUNC, S_IRUSR|S_IWUSR); + + if (fd < 0) + pr_err("failed to open %s : %s\n", file->path, strerror(errno)); + + return fd; } static int open_file(struct perf_data_file *file) diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index a53cd0b8c151..27c2a5efe450 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -717,7 +717,7 @@ static char *get_kernel_version(const char *root_dir) } static int map_groups__set_modules_path_dir(struct map_groups *mg, - const char *dir_name) + const char *dir_name, int depth) { struct dirent *dent; DIR *dir = opendir(dir_name); @@ -742,7 +742,15 @@ static int map_groups__set_modules_path_dir(struct map_groups *mg, !strcmp(dent->d_name, "..")) continue; - ret = map_groups__set_modules_path_dir(mg, path); + /* Do not follow top-level source and build symlinks */ + if (depth == 0) { + if (!strcmp(dent->d_name, "source") || + !strcmp(dent->d_name, "build")) + continue; + } + + ret = map_groups__set_modules_path_dir(mg, path, + depth + 1); if (ret < 0) goto out; } else { @@ -786,11 +794,11 @@ static int machine__set_modules_path(struct machine *machine) if (!version) return -1; - snprintf(modules_path, sizeof(modules_path), "%s/lib/modules/%s/kernel", + snprintf(modules_path, sizeof(modules_path), "%s/lib/modules/%s", machine->root_dir, version); free(version); - return map_groups__set_modules_path_dir(&machine->kmaps, modules_path); + return map_groups__set_modules_path_dir(&machine->kmaps, modules_path, 0); } static int machine__create_module(void *arg, const char *name, u64 start) diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index df0238654698..562762117639 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -985,7 +985,7 @@ static int debuginfo__find_probes(struct debuginfo *dbg, #if _ELFUTILS_PREREQ(0, 142) /* Get the call frame information from this dwarf */ - pf->cfi = dwarf_getcfi(dbg->dbg); + pf->cfi = dwarf_getcfi_elf(dwarf_getelf(dbg->dbg)); #endif off = 0; @@ -1441,13 +1441,15 @@ static int line_range_walk_cb(const char *fname, int lineno, void *data) { struct line_finder *lf = data; + int err; if ((strtailcmp(fname, lf->fname) != 0) || (lf->lno_s > lineno || lf->lno_e < lineno)) return 0; - if (line_range_add_line(fname, lineno, lf->lr) < 0) - return -EINVAL; + err = line_range_add_line(fname, lineno, lf->lr); + if (err < 0 && err != -EEXIST) + return err; return 0; } @@ -1473,14 +1475,15 @@ static int find_line_range_by_line(Dwarf_Die *sp_die, struct line_finder *lf) static int line_range_inline_cb(Dwarf_Die *in_die, void *data) { - find_line_range_by_line(in_die, data); + int ret = find_line_range_by_line(in_die, data); /* * We have to check all instances of inlined function, because * some execution paths can be optimized out depends on the - * function argument of instances + * function argument of instances. However, if an error occurs, + * it should be handled by the caller. */ - return 0; + return ret < 0 ? ret : 0; } /* Search function definition from function name */ diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 3b7dbf51d4a9..6864661a79dd 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -6,6 +6,7 @@ #include <inttypes.h> #include "symbol.h" +#include "vdso.h" #include <symbol/kallsyms.h> #include "debug.h" @@ -618,6 +619,7 @@ int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name, GElf_Shdr shdr; ss->adjust_symbols = (ehdr.e_type == ET_EXEC || ehdr.e_type == ET_REL || + is_vdso_map(dso->short_name) || elf_section_by_name(elf, &ehdr, &shdr, ".gnu.prelink_undo", NULL) != NULL); diff --git a/tools/power/acpi/Makefile b/tools/power/acpi/Makefile index d9186a2fdf06..c2c0f20067a5 100644 --- a/tools/power/acpi/Makefile +++ b/tools/power/acpi/Makefile @@ -89,15 +89,6 @@ else STRIPCMD = $(STRIP) -s --remove-section=.note --remove-section=.comment endif -# if DEBUG is enabled, then we do not strip or optimize -ifeq ($(strip $(DEBUG)),true) - CFLAGS += -O1 -g -DDEBUG - STRIPCMD = /bin/true -Since_we_are_debugging -else - CFLAGS += $(OPTIMIZATION) -fomit-frame-pointer - STRIPCMD = $(STRIP) -s --remove-section=.note --remove-section=.comment -endif - # --- ACPIDUMP BEGIN --- vpath %.c \ @@ -128,7 +119,7 @@ clean: -rm -f $(OUTPUT)acpidump install-tools: - $(INSTALL) -d $(DESTDIR)${bindir} + $(INSTALL) -d $(DESTDIR)${sbindir} $(INSTALL_PROGRAM) $(OUTPUT)acpidump $(DESTDIR)${sbindir} install-man: diff --git a/tools/power/x86/turbostat/turbostat.8 b/tools/power/x86/turbostat/turbostat.8 index b4ddb748356c..56bfb523c5bb 100644 --- a/tools/power/x86/turbostat/turbostat.8 +++ b/tools/power/x86/turbostat/turbostat.8 @@ -47,21 +47,22 @@ displays the statistics gathered since it was forked. .PP .SH FIELD DESCRIPTIONS .nf -\fBpk\fP processor package number. -\fBcor\fP processor core number. +\fBPackage\fP processor package number. +\fBCore\fP processor core number. \fBCPU\fP Linux CPU (logical processor) number. Note that multiple CPUs per core indicate support for Intel(R) Hyper-Threading Technology. -\fB%c0\fP percent of the interval that the CPU retired instructions. -\fBGHz\fP average clock rate while the CPU was in c0 state. -\fBTSC\fP average GHz that the TSC ran during the entire interval. -\fB%c1, %c3, %c6, %c7\fP show the percentage residency in hardware core idle states. -\fBCTMP\fP Degrees Celsius reported by the per-core Digital Thermal Sensor. -\fBPTMP\fP Degrees Celsius reported by the per-package Package Thermal Monitor. -\fB%pc2, %pc3, %pc6, %pc7\fP percentage residency in hardware package idle states. -\fBPkg_W\fP Watts consumed by the whole package. -\fBCor_W\fP Watts consumed by the core part of the package. -\fBGFX_W\fP Watts consumed by the Graphics part of the package -- available only on client processors. -\fBRAM_W\fP Watts consumed by the DRAM DIMMS -- available only on server processors. +\fBAVG_MHz\fP number of cycles executed divided by time elapsed. +\fB%Buzy\fP percent of the interval that the CPU retired instructions, aka. % of time in "C0" state. +\fBBzy_MHz\fP average clock rate while the CPU was busy (in "c0" state). +\fBTSC_MHz\fP average MHz that the TSC ran during the entire interval. +\fBCPU%c1, CPU%c3, CPU%c6, CPU%c7\fP show the percentage residency in hardware core idle states. +\fBCoreTmp\fP Degrees Celsius reported by the per-core Digital Thermal Sensor. +\fBPkgTtmp\fP Degrees Celsius reported by the per-package Package Thermal Monitor. +\fBPkg%pc2, Pkg%pc3, Pkg%pc6, Pkg%pc7\fP percentage residency in hardware package idle states. +\fBPkgWatt\fP Watts consumed by the whole package. +\fBCorWatt\fP Watts consumed by the core part of the package. +\fBGFXWatt\fP Watts consumed by the Graphics part of the package -- available only on client processors. +\fBRAMWatt\fP Watts consumed by the DRAM DIMMS -- available only on server processors. \fBPKG_%\fP percent of the interval that RAPL throttling was active on the Package. \fBRAM_%\fP percent of the interval that RAPL throttling was active on DRAM. .fi @@ -78,29 +79,17 @@ For Watts columns, the summary is a system total. Subsequent rows show per-CPU statistics. .nf -[root@sandy]# ./turbostat -cor CPU %c0 GHz TSC %c1 %c3 %c6 %c7 CTMP PTMP %pc2 %pc3 %pc6 %pc7 Pkg_W Cor_W GFX_W - 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 - 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 - 0 4 0.03 0.80 2.29 0.12 - 1 1 0.04 0.80 2.29 0.25 0.01 0.00 99.71 40 - 1 5 0.16 0.80 2.29 0.13 - 2 2 0.05 0.80 2.29 0.06 0.01 0.00 99.88 40 - 2 6 0.03 0.80 2.29 0.08 - 3 3 0.05 0.80 2.29 0.08 0.00 0.00 99.87 47 - 3 7 0.04 0.84 2.29 0.09 -.fi -.SH SUMMARY EXAMPLE -The "-s" option prints the column headers just once, -and then the one line system summary for each sample interval. - -.nf -[root@wsm]# turbostat -S - %c0 GHz TSC %c1 %c3 %c6 CTMP %pc3 %pc6 - 1.40 2.81 3.38 10.78 43.47 44.35 42 13.67 2.09 - 1.34 2.90 3.38 11.48 58.96 28.23 41 19.89 0.15 - 1.55 2.72 3.38 26.73 37.66 34.07 42 2.53 2.80 - 1.37 2.83 3.38 16.95 60.05 21.63 42 5.76 0.20 +[root@ivy]# ./turbostat + Core CPU Avg_MHz %Busy Bzy_MHz TSC_MHz SMI CPU%c1 CPU%c3 CPU%c6 CPU%c7 CoreTmp PkgTmp Pkg%pc2 Pkg%pc3 Pkg%pc6 Pkg%pc7 PkgWatt CorWatt GFXWatt + - - 6 0.36 1596 3492 0 0.59 0.01 99.04 0.00 23 24 23.82 0.01 72.47 0.00 6.40 1.01 0.00 + 0 0 9 0.58 1596 3492 0 0.28 0.01 99.13 0.00 23 24 23.82 0.01 72.47 0.00 6.40 1.01 0.00 + 0 4 1 0.07 1596 3492 0 0.79 + 1 1 10 0.65 1596 3492 0 0.59 0.00 98.76 0.00 23 + 1 5 5 0.28 1596 3492 0 0.95 + 2 2 10 0.66 1596 3492 0 0.41 0.01 98.92 0.00 23 + 2 6 2 0.10 1597 3492 0 0.97 + 3 3 3 0.20 1596 3492 0 0.44 0.00 99.37 0.00 23 + 3 7 5 0.31 1596 3492 0 0.33 .fi .SH VERBOSE EXAMPLE The "-v" option adds verbosity to the output: @@ -154,55 +143,35 @@ eg. Here a cycle soaker is run on 1 CPU (see %c0) for a few seconds until ^C while the other CPUs are mostly idle: .nf -[root@x980 lenb]# ./turbostat cat /dev/zero > /dev/null +root@ivy: turbostat cat /dev/zero > /dev/null ^C -cor CPU %c0 GHz TSC %c1 %c3 %c6 %pc3 %pc6 - 8.86 3.61 3.38 15.06 31.19 44.89 0.00 0.00 - 0 0 1.46 3.22 3.38 16.84 29.48 52.22 0.00 0.00 - 0 6 0.21 3.06 3.38 18.09 - 1 2 0.53 3.33 3.38 2.80 46.40 50.27 - 1 8 0.89 3.47 3.38 2.44 - 2 4 1.36 3.43 3.38 9.04 23.71 65.89 - 2 10 0.18 2.86 3.38 10.22 - 8 1 0.04 2.87 3.38 99.96 0.01 0.00 - 8 7 99.72 3.63 3.38 0.27 - 9 3 0.31 3.21 3.38 7.64 56.55 35.50 - 9 9 0.08 2.95 3.38 7.88 - 10 5 1.42 3.43 3.38 2.14 30.99 65.44 - 10 11 0.16 2.88 3.38 3.40 + Core CPU Avg_MHz %Busy Bzy_MHz TSC_MHz SMI CPU%c1 CPU%c3 CPU%c6 CPU%c7 CoreTmp PkgTmp Pkg%pc2 Pkg%pc3 Pkg%pc6 Pkg%pc7 PkgWatt CorWatt GFXWatt + - - 496 12.75 3886 3492 0 13.16 0.04 74.04 0.00 36 36 0.00 0.00 0.00 0.00 23.15 17.65 0.00 + 0 0 22 0.57 3830 3492 0 0.83 0.02 98.59 0.00 27 36 0.00 0.00 0.00 0.00 23.15 17.65 0.00 + 0 4 9 0.24 3829 3492 0 1.15 + 1 1 4 0.09 3783 3492 0 99.91 0.00 0.00 0.00 36 + 1 5 3880 99.82 3888 3492 0 0.18 + 2 2 17 0.44 3813 3492 0 0.77 0.04 98.75 0.00 28 + 2 6 12 0.32 3823 3492 0 0.89 + 3 3 16 0.43 3844 3492 0 0.63 0.11 98.84 0.00 30 + 3 7 4 0.11 3827 3492 0 0.94 +30.372243 sec + .fi -Above the cycle soaker drives cpu7 up its 3.6 GHz turbo limit +Above the cycle soaker drives cpu5 up its 3.8 GHz turbo limit while the other processors are generally in various states of idle. -Note that cpu1 and cpu7 are HT siblings within core8. -As cpu7 is very busy, it prevents its sibling, cpu1, +Note that cpu1 and cpu5 are HT siblings within core1. +As cpu5 is very busy, it prevents its sibling, cpu1, from entering a c-state deeper than c1. -Note that turbostat reports average GHz of 3.63, while -the arithmetic average of the GHz column above is lower. -This is a weighted average, where the weight is %c0. ie. it is the total number of -un-halted cycles elapsed per time divided by the number of CPUs. -.SH SMI COUNTING EXAMPLE -On Intel Nehalem and newer processors, MSR 0x34 is a System Management Mode Interrupt (SMI) counter. -This counter is shown by default under the "SMI" column. -.nf -[root@x980 ~]# turbostat -cor CPU %c0 GHz TSC SMI %c1 %c3 %c6 CTMP %pc3 %pc6 - 0.11 1.91 3.38 0 1.84 0.26 97.79 29 0.82 83.87 - 0 0 0.40 1.63 3.38 0 10.27 0.12 89.20 20 0.82 83.88 - 0 6 0.06 1.63 3.38 0 10.61 - 1 2 0.37 2.63 3.38 0 0.02 0.10 99.51 22 - 1 8 0.01 1.62 3.38 0 0.39 - 2 4 0.07 1.62 3.38 0 0.04 0.07 99.82 23 - 2 10 0.02 1.62 3.38 0 0.09 - 8 1 0.23 1.64 3.38 0 0.10 1.07 98.60 24 - 8 7 0.02 1.64 3.38 0 0.31 - 9 3 0.03 1.62 3.38 0 0.03 0.05 99.89 29 - 9 9 0.02 1.62 3.38 0 0.05 - 10 5 0.07 1.62 3.38 0 0.08 0.12 99.73 27 - 10 11 0.03 1.62 3.38 0 0.13 -^C -.fi +Note that the Avg_MHz column reflects the total number of cycles executed +divided by the measurement interval. If the %Busy column is 100%, +then the processor was running at that speed the entire interval. +The Avg_MHz multiplied by the %Busy results in the Bzy_MHz -- +which is the average frequency while the processor was executing -- +not including any non-busy idle time. + .SH NOTES .B "turbostat " diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 77eb130168da..7c9d8e71eb9e 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -56,7 +56,7 @@ unsigned int do_slm_cstates; unsigned int use_c1_residency_msr; unsigned int has_aperf; unsigned int has_epb; -unsigned int units = 1000000000; /* Ghz etc */ +unsigned int units = 1000000; /* MHz etc */ unsigned int genuine_intel; unsigned int has_invariant_tsc; unsigned int do_nehalem_platform_info; @@ -264,88 +264,93 @@ int get_msr(int cpu, off_t offset, unsigned long long *msr) return 0; } +/* + * Example Format w/ field column widths: + * + * Package Core CPU Avg_MHz Bzy_MHz TSC_MHz SMI %Busy CPU_%c1 CPU_%c3 CPU_%c6 CPU_%c7 CoreTmp PkgTmp Pkg%pc2 Pkg%pc3 Pkg%pc6 Pkg%pc7 PkgWatt CorWatt GFXWatt + * 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 + */ + void print_header(void) { if (show_pkg) - outp += sprintf(outp, "pk"); - if (show_pkg) - outp += sprintf(outp, " "); + outp += sprintf(outp, "Package "); if (show_core) - outp += sprintf(outp, "cor"); + outp += sprintf(outp, " Core "); if (show_cpu) - outp += sprintf(outp, " CPU"); - if (show_pkg || show_core || show_cpu) - outp += sprintf(outp, " "); + outp += sprintf(outp, " CPU "); + if (has_aperf) + outp += sprintf(outp, "Avg_MHz "); if (do_nhm_cstates) - outp += sprintf(outp, " %%c0"); + outp += sprintf(outp, " %%Busy "); if (has_aperf) - outp += sprintf(outp, " GHz"); - outp += sprintf(outp, " TSC"); + outp += sprintf(outp, "Bzy_MHz "); + outp += sprintf(outp, "TSC_MHz "); if (do_smi) - outp += sprintf(outp, " SMI"); + outp += sprintf(outp, " SMI "); if (extra_delta_offset32) - outp += sprintf(outp, " count 0x%03X", extra_delta_offset32); + outp += sprintf(outp, " count 0x%03X ", extra_delta_offset32); if (extra_delta_offset64) - outp += sprintf(outp, " COUNT 0x%03X", extra_delta_offset64); + outp += sprintf(outp, " COUNT 0x%03X ", extra_delta_offset64); if (extra_msr_offset32) - outp += sprintf(outp, " MSR 0x%03X", extra_msr_offset32); + outp += sprintf(outp, " MSR 0x%03X ", extra_msr_offset32); if (extra_msr_offset64) - outp += sprintf(outp, " MSR 0x%03X", extra_msr_offset64); + outp += sprintf(outp, " MSR 0x%03X ", extra_msr_offset64); if (do_nhm_cstates) - outp += sprintf(outp, " %%c1"); + outp += sprintf(outp, " CPU%%c1 "); if (do_nhm_cstates && !do_slm_cstates) - outp += sprintf(outp, " %%c3"); + outp += sprintf(outp, " CPU%%c3 "); if (do_nhm_cstates) - outp += sprintf(outp, " %%c6"); + outp += sprintf(outp, " CPU%%c6 "); if (do_snb_cstates) - outp += sprintf(outp, " %%c7"); + outp += sprintf(outp, " CPU%%c7 "); if (do_dts) - outp += sprintf(outp, " CTMP"); + outp += sprintf(outp, "CoreTmp "); if (do_ptm) - outp += sprintf(outp, " PTMP"); + outp += sprintf(outp, " PkgTmp "); if (do_snb_cstates) - outp += sprintf(outp, " %%pc2"); + outp += sprintf(outp, "Pkg%%pc2 "); if (do_nhm_cstates && !do_slm_cstates) - outp += sprintf(outp, " %%pc3"); + outp += sprintf(outp, "Pkg%%pc3 "); if (do_nhm_cstates && !do_slm_cstates) - outp += sprintf(outp, " %%pc6"); + outp += sprintf(outp, "Pkg%%pc6 "); if (do_snb_cstates) - outp += sprintf(outp, " %%pc7"); + outp += sprintf(outp, "Pkg%%pc7 "); if (do_c8_c9_c10) { - outp += sprintf(outp, " %%pc8"); - outp += sprintf(outp, " %%pc9"); - outp += sprintf(outp, " %%pc10"); + outp += sprintf(outp, "Pkg%%pc8 "); + outp += sprintf(outp, "Pkg%%pc9 "); + outp += sprintf(outp, "Pk%%pc10 "); } if (do_rapl && !rapl_joules) { if (do_rapl & RAPL_PKG) - outp += sprintf(outp, " Pkg_W"); + outp += sprintf(outp, "PkgWatt "); if (do_rapl & RAPL_CORES) - outp += sprintf(outp, " Cor_W"); + outp += sprintf(outp, "CorWatt "); if (do_rapl & RAPL_GFX) - outp += sprintf(outp, " GFX_W"); + outp += sprintf(outp, "GFXWatt "); if (do_rapl & RAPL_DRAM) - outp += sprintf(outp, " RAM_W"); + outp += sprintf(outp, "RAMWatt "); if (do_rapl & RAPL_PKG_PERF_STATUS) - outp += sprintf(outp, " PKG_%%"); + outp += sprintf(outp, " PKG_%% "); if (do_rapl & RAPL_DRAM_PERF_STATUS) - outp += sprintf(outp, " RAM_%%"); + outp += sprintf(outp, " RAM_%% "); } else { if (do_rapl & RAPL_PKG) - outp += sprintf(outp, " Pkg_J"); + outp += sprintf(outp, " Pkg_J "); if (do_rapl & RAPL_CORES) - outp += sprintf(outp, " Cor_J"); + outp += sprintf(outp, " Cor_J "); if (do_rapl & RAPL_GFX) - outp += sprintf(outp, " GFX_J"); + outp += sprintf(outp, " GFX_J "); if (do_rapl & RAPL_DRAM) - outp += sprintf(outp, " RAM_W"); + outp += sprintf(outp, " RAM_W "); if (do_rapl & RAPL_PKG_PERF_STATUS) - outp += sprintf(outp, " PKG_%%"); + outp += sprintf(outp, " PKG_%% "); if (do_rapl & RAPL_DRAM_PERF_STATUS) - outp += sprintf(outp, " RAM_%%"); - outp += sprintf(outp, " time"); + outp += sprintf(outp, " RAM_%% "); + outp += sprintf(outp, " time "); } outp += sprintf(outp, "\n"); @@ -410,25 +415,12 @@ int dump_counters(struct thread_data *t, struct core_data *c, /* * column formatting convention & formats - * package: "pk" 2 columns %2d - * core: "cor" 3 columns %3d - * CPU: "CPU" 3 columns %3d - * Pkg_W: %6.2 - * Cor_W: %6.2 - * GFX_W: %5.2 - * RAM_W: %5.2 - * GHz: "GHz" 3 columns %3.2 - * TSC: "TSC" 3 columns %3.2 - * SMI: "SMI" 4 columns %4d - * percentage " %pc3" %6.2 - * Perf Status percentage: %5.2 - * "CTMP" 4 columns %4d */ int format_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) { double interval_float; - char *fmt5, *fmt6; + char *fmt8; /* if showing only 1st thread in core and this isn't one, bail out */ if (show_core_only && !(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) @@ -443,65 +435,52 @@ int format_counters(struct thread_data *t, struct core_data *c, /* topo columns, print blanks on 1st (average) line */ if (t == &average.threads) { if (show_pkg) - outp += sprintf(outp, " "); - if (show_pkg && show_core) - outp += sprintf(outp, " "); + outp += sprintf(outp, " -"); if (show_core) - outp += sprintf(outp, " "); + outp += sprintf(outp, " -"); if (show_cpu) - outp += sprintf(outp, " " " "); + outp += sprintf(outp, " -"); } else { if (show_pkg) { if (p) - outp += sprintf(outp, "%2d", p->package_id); + outp += sprintf(outp, "%8d", p->package_id); else - outp += sprintf(outp, " "); + outp += sprintf(outp, " -"); } - if (show_pkg && show_core) - outp += sprintf(outp, " "); if (show_core) { if (c) - outp += sprintf(outp, "%3d", c->core_id); + outp += sprintf(outp, "%8d", c->core_id); else - outp += sprintf(outp, " "); + outp += sprintf(outp, " -"); } if (show_cpu) - outp += sprintf(outp, " %3d", t->cpu_id); + outp += sprintf(outp, "%8d", t->cpu_id); } + + /* AvgMHz */ + if (has_aperf) + outp += sprintf(outp, "%8.0f", + 1.0 / units * t->aperf / interval_float); + /* %c0 */ if (do_nhm_cstates) { - if (show_pkg || show_core || show_cpu) - outp += sprintf(outp, " "); if (!skip_c0) - outp += sprintf(outp, "%6.2f", 100.0 * t->mperf/t->tsc); + outp += sprintf(outp, "%8.2f", 100.0 * t->mperf/t->tsc); else - outp += sprintf(outp, " ****"); + outp += sprintf(outp, "********"); } - /* GHz */ - if (has_aperf) { - if (!aperf_mperf_unstable) { - outp += sprintf(outp, " %3.2f", - 1.0 * t->tsc / units * t->aperf / - t->mperf / interval_float); - } else { - if (t->aperf > t->tsc || t->mperf > t->tsc) { - outp += sprintf(outp, " ***"); - } else { - outp += sprintf(outp, "%3.1f*", - 1.0 * t->tsc / - units * t->aperf / - t->mperf / interval_float); - } - } - } + /* BzyMHz */ + if (has_aperf) + outp += sprintf(outp, "%8.0f", + 1.0 * t->tsc / units * t->aperf / t->mperf / interval_float); /* TSC */ - outp += sprintf(outp, "%5.2f", 1.0 * t->tsc/units/interval_float); + outp += sprintf(outp, "%8.0f", 1.0 * t->tsc/units/interval_float); /* SMI */ if (do_smi) - outp += sprintf(outp, "%4d", t->smi_count); + outp += sprintf(outp, "%8d", t->smi_count); /* delta */ if (extra_delta_offset32) @@ -520,9 +499,9 @@ int format_counters(struct thread_data *t, struct core_data *c, if (do_nhm_cstates) { if (!skip_c1) - outp += sprintf(outp, " %6.2f", 100.0 * t->c1/t->tsc); + outp += sprintf(outp, "%8.2f", 100.0 * t->c1/t->tsc); else - outp += sprintf(outp, " ****"); + outp += sprintf(outp, "********"); } /* print per-core data only for 1st thread in core */ @@ -530,79 +509,76 @@ int format_counters(struct thread_data *t, struct core_data *c, goto done; if (do_nhm_cstates && !do_slm_cstates) - outp += sprintf(outp, " %6.2f", 100.0 * c->c3/t->tsc); + outp += sprintf(outp, "%8.2f", 100.0 * c->c3/t->tsc); if (do_nhm_cstates) - outp += sprintf(outp, " %6.2f", 100.0 * c->c6/t->tsc); + outp += sprintf(outp, "%8.2f", 100.0 * c->c6/t->tsc); if (do_snb_cstates) - outp += sprintf(outp, " %6.2f", 100.0 * c->c7/t->tsc); + outp += sprintf(outp, "%8.2f", 100.0 * c->c7/t->tsc); if (do_dts) - outp += sprintf(outp, " %4d", c->core_temp_c); + outp += sprintf(outp, "%8d", c->core_temp_c); /* print per-package data only for 1st core in package */ if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) goto done; if (do_ptm) - outp += sprintf(outp, " %4d", p->pkg_temp_c); + outp += sprintf(outp, "%8d", p->pkg_temp_c); if (do_snb_cstates) - outp += sprintf(outp, " %6.2f", 100.0 * p->pc2/t->tsc); + outp += sprintf(outp, "%8.2f", 100.0 * p->pc2/t->tsc); if (do_nhm_cstates && !do_slm_cstates) - outp += sprintf(outp, " %6.2f", 100.0 * p->pc3/t->tsc); + outp += sprintf(outp, "%8.2f", 100.0 * p->pc3/t->tsc); if (do_nhm_cstates && !do_slm_cstates) - outp += sprintf(outp, " %6.2f", 100.0 * p->pc6/t->tsc); + outp += sprintf(outp, "%8.2f", 100.0 * p->pc6/t->tsc); if (do_snb_cstates) - outp += sprintf(outp, " %6.2f", 100.0 * p->pc7/t->tsc); + outp += sprintf(outp, "%8.2f", 100.0 * p->pc7/t->tsc); if (do_c8_c9_c10) { - outp += sprintf(outp, " %6.2f", 100.0 * p->pc8/t->tsc); - outp += sprintf(outp, " %6.2f", 100.0 * p->pc9/t->tsc); - outp += sprintf(outp, " %6.2f", 100.0 * p->pc10/t->tsc); + outp += sprintf(outp, "%8.2f", 100.0 * p->pc8/t->tsc); + outp += sprintf(outp, "%8.2f", 100.0 * p->pc9/t->tsc); + outp += sprintf(outp, "%8.2f", 100.0 * p->pc10/t->tsc); } /* * If measurement interval exceeds minimum RAPL Joule Counter range, * indicate that results are suspect by printing "**" in fraction place. */ - if (interval_float < rapl_joule_counter_range) { - fmt5 = " %5.2f"; - fmt6 = " %6.2f"; - } else { - fmt5 = " %3.0f**"; - fmt6 = " %4.0f**"; - } + if (interval_float < rapl_joule_counter_range) + fmt8 = "%8.2f"; + else + fmt8 = " %6.0f**"; if (do_rapl && !rapl_joules) { if (do_rapl & RAPL_PKG) - outp += sprintf(outp, fmt6, p->energy_pkg * rapl_energy_units / interval_float); + outp += sprintf(outp, fmt8, p->energy_pkg * rapl_energy_units / interval_float); if (do_rapl & RAPL_CORES) - outp += sprintf(outp, fmt6, p->energy_cores * rapl_energy_units / interval_float); + outp += sprintf(outp, fmt8, p->energy_cores * rapl_energy_units / interval_float); if (do_rapl & RAPL_GFX) - outp += sprintf(outp, fmt5, p->energy_gfx * rapl_energy_units / interval_float); + outp += sprintf(outp, fmt8, p->energy_gfx * rapl_energy_units / interval_float); if (do_rapl & RAPL_DRAM) - outp += sprintf(outp, fmt5, p->energy_dram * rapl_energy_units / interval_float); + outp += sprintf(outp, fmt8, p->energy_dram * rapl_energy_units / interval_float); if (do_rapl & RAPL_PKG_PERF_STATUS) - outp += sprintf(outp, fmt5, 100.0 * p->rapl_pkg_perf_status * rapl_time_units / interval_float); + outp += sprintf(outp, fmt8, 100.0 * p->rapl_pkg_perf_status * rapl_time_units / interval_float); if (do_rapl & RAPL_DRAM_PERF_STATUS) - outp += sprintf(outp, fmt5, 100.0 * p->rapl_dram_perf_status * rapl_time_units / interval_float); + outp += sprintf(outp, fmt8, 100.0 * p->rapl_dram_perf_status * rapl_time_units / interval_float); } else { if (do_rapl & RAPL_PKG) - outp += sprintf(outp, fmt6, + outp += sprintf(outp, fmt8, p->energy_pkg * rapl_energy_units); if (do_rapl & RAPL_CORES) - outp += sprintf(outp, fmt6, + outp += sprintf(outp, fmt8, p->energy_cores * rapl_energy_units); if (do_rapl & RAPL_GFX) - outp += sprintf(outp, fmt5, + outp += sprintf(outp, fmt8, p->energy_gfx * rapl_energy_units); if (do_rapl & RAPL_DRAM) - outp += sprintf(outp, fmt5, + outp += sprintf(outp, fmt8, p->energy_dram * rapl_energy_units); if (do_rapl & RAPL_PKG_PERF_STATUS) - outp += sprintf(outp, fmt5, 100.0 * p->rapl_pkg_perf_status * rapl_time_units / interval_float); + outp += sprintf(outp, fmt8, 100.0 * p->rapl_pkg_perf_status * rapl_time_units / interval_float); if (do_rapl & RAPL_DRAM_PERF_STATUS) - outp += sprintf(outp, fmt5, 100.0 * p->rapl_dram_perf_status * rapl_time_units / interval_float); - outp += sprintf(outp, fmt5, interval_float); + outp += sprintf(outp, fmt8, 100.0 * p->rapl_dram_perf_status * rapl_time_units / interval_float); + outp += sprintf(outp, fmt8, interval_float); } done: @@ -1516,6 +1492,9 @@ int has_nehalem_turbo_ratio_limit(unsigned int family, unsigned int model) case 0x46: /* HSW */ case 0x37: /* BYT */ case 0x4D: /* AVN */ + case 0x3D: /* BDW */ + case 0x4F: /* BDX */ + case 0x56: /* BDX-DE */ return 1; case 0x2E: /* Nehalem-EX Xeon - Beckton */ case 0x2F: /* Westmere-EX Xeon - Eagleton */ @@ -1629,9 +1608,12 @@ void rapl_probe(unsigned int family, unsigned int model) case 0x3C: /* HSW */ case 0x45: /* HSW */ case 0x46: /* HSW */ + case 0x3D: /* BDW */ do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_GFX | RAPL_PKG_POWER_INFO; break; case 0x3F: /* HSX */ + case 0x4F: /* BDX */ + case 0x56: /* BDX-DE */ do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO; break; case 0x2D: @@ -1875,6 +1857,9 @@ int is_snb(unsigned int family, unsigned int model) case 0x3F: /* HSW */ case 0x45: /* HSW */ case 0x46: /* HSW */ + case 0x3D: /* BDW */ + case 0x4F: /* BDX */ + case 0x56: /* BDX-DE */ return 1; } return 0; @@ -1886,7 +1871,8 @@ int has_c8_c9_c10(unsigned int family, unsigned int model) return 0; switch (model) { - case 0x45: + case 0x45: /* HSW */ + case 0x3D: /* BDW */ return 1; } return 0; @@ -2455,7 +2441,7 @@ int main(int argc, char **argv) cmdline(argc, argv); if (verbose) - fprintf(stderr, "turbostat v3.6 Dec 2, 2013" + fprintf(stderr, "turbostat v3.7 Feb 6, 2014" " - Len Brown <lenb@kernel.org>\n"); turbostat_init(); diff --git a/tools/testing/ktest/examples/kvm.conf b/tools/testing/ktest/examples/kvm.conf index 831c7c5395f1..fbc134f9ac6e 100644 --- a/tools/testing/ktest/examples/kvm.conf +++ b/tools/testing/ktest/examples/kvm.conf @@ -10,6 +10,10 @@ MACHINE = Guest # Use virsh to read the serial console of the guest CONSOLE = virsh console ${MACHINE} +# Use SIGKILL to terminate virsh console. We can't kill virsh console +# by the default signal, SIGINT. +CLOSE_CONSOLE_SIGNAL = KILL + #*************************************# # This part is the same as test.conf # #*************************************# diff --git a/tools/vm/page-types.c b/tools/vm/page-types.c index f9be24d9efac..05654f5e48d5 100644 --- a/tools/vm/page-types.c +++ b/tools/vm/page-types.c @@ -19,7 +19,8 @@ * Authors: Wu Fengguang <fengguang.wu@intel.com> */ -#define _LARGEFILE64_SOURCE +#define _FILE_OFFSET_BITS 64 +#define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -29,11 +30,14 @@ #include <getopt.h> #include <limits.h> #include <assert.h> +#include <ftw.h> +#include <time.h> #include <sys/types.h> #include <sys/errno.h> #include <sys/fcntl.h> #include <sys/mount.h> #include <sys/statfs.h> +#include <sys/mman.h> #include "../../include/uapi/linux/magic.h" #include "../../include/uapi/linux/kernel-page-flags.h" #include <api/fs/debugfs.h> @@ -158,6 +162,7 @@ static int opt_raw; /* for kernel developers */ static int opt_list; /* list pages (in ranges) */ static int opt_no_summary; /* don't show summary */ static pid_t opt_pid; /* process to walk */ +const char * opt_file; #define MAX_ADDR_RANGES 1024 static int nr_addr_ranges; @@ -253,12 +258,7 @@ static unsigned long do_u64_read(int fd, char *name, if (index > ULONG_MAX / 8) fatal("index overflow: %lu\n", index); - if (lseek(fd, index * 8, SEEK_SET) < 0) { - perror(name); - exit(EXIT_FAILURE); - } - - bytes = read(fd, buf, count * 8); + bytes = pread(fd, buf, count * 8, (off_t)index * 8); if (bytes < 0) { perror(name); exit(EXIT_FAILURE); @@ -343,8 +343,8 @@ static char *page_flag_longname(uint64_t flags) * page list and summary */ -static void show_page_range(unsigned long voffset, - unsigned long offset, uint64_t flags) +static void show_page_range(unsigned long voffset, unsigned long offset, + unsigned long size, uint64_t flags) { static uint64_t flags0; static unsigned long voff; @@ -352,14 +352,16 @@ static void show_page_range(unsigned long voffset, static unsigned long count; if (flags == flags0 && offset == index + count && - (!opt_pid || voffset == voff + count)) { - count++; + size && voffset == voff + count) { + count += size; return; } if (count) { if (opt_pid) printf("%lx\t", voff); + if (opt_file) + printf("%lu\t", voff); printf("%lx\t%lx\t%s\n", index, count, page_flag_name(flags0)); } @@ -367,7 +369,12 @@ static void show_page_range(unsigned long voffset, flags0 = flags; index = offset; voff = voffset; - count = 1; + count = size; +} + +static void flush_page_range(void) +{ + show_page_range(0, 0, 0, 0); } static void show_page(unsigned long voffset, @@ -375,6 +382,8 @@ static void show_page(unsigned long voffset, { if (opt_pid) printf("%lx\t", voffset); + if (opt_file) + printf("%lu\t", voffset); printf("%lx\t%s\n", offset, page_flag_name(flags)); } @@ -565,7 +574,7 @@ static void add_page(unsigned long voffset, unpoison_page(offset); if (opt_list == 1) - show_page_range(voffset, offset, flags); + show_page_range(voffset, offset, 1, flags); else if (opt_list == 2) show_page(voffset, offset, flags); @@ -667,7 +676,7 @@ static void walk_addr_ranges(void) for (i = 0; i < nr_addr_ranges; i++) if (!opt_pid) - walk_pfn(0, opt_offset[i], opt_size[i], 0); + walk_pfn(opt_offset[i], opt_offset[i], opt_size[i], 0); else walk_task(opt_offset[i], opt_size[i]); @@ -699,9 +708,7 @@ static void usage(void) " -a|--addr addr-spec Walk a range of pages\n" " -b|--bits bits-spec Walk pages with specified bits\n" " -p|--pid pid Walk process address space\n" -#if 0 /* planned features */ " -f|--file filename Walk file address space\n" -#endif " -l|--list Show page details in ranges\n" " -L|--list-each Show page details one by one\n" " -N|--no-summary Don't show summary info\n" @@ -799,8 +806,130 @@ static void parse_pid(const char *str) fclose(file); } +static void show_file(const char *name, const struct stat *st) +{ + unsigned long long size = st->st_size; + char atime[64], mtime[64]; + long now = time(NULL); + + printf("%s\tInode: %u\tSize: %llu (%llu pages)\n", + name, (unsigned)st->st_ino, + size, (size + page_size - 1) / page_size); + + strftime(atime, sizeof(atime), "%c", localtime(&st->st_atime)); + strftime(mtime, sizeof(mtime), "%c", localtime(&st->st_mtime)); + + printf("Modify: %s (%ld seconds ago)\nAccess: %s (%ld seconds ago)\n", + mtime, now - st->st_mtime, + atime, now - st->st_atime); +} + +static void walk_file(const char *name, const struct stat *st) +{ + uint8_t vec[PAGEMAP_BATCH]; + uint64_t buf[PAGEMAP_BATCH], flags; + unsigned long nr_pages, pfn, i; + int fd; + off_t off; + ssize_t len; + void *ptr; + int first = 1; + + fd = checked_open(name, O_RDONLY|O_NOATIME|O_NOFOLLOW); + + for (off = 0; off < st->st_size; off += len) { + nr_pages = (st->st_size - off + page_size - 1) / page_size; + if (nr_pages > PAGEMAP_BATCH) + nr_pages = PAGEMAP_BATCH; + len = nr_pages * page_size; + + ptr = mmap(NULL, len, PROT_READ, MAP_SHARED, fd, off); + if (ptr == MAP_FAILED) + fatal("mmap failed: %s", name); + + /* determine cached pages */ + if (mincore(ptr, len, vec)) + fatal("mincore failed: %s", name); + + /* turn off readahead */ + if (madvise(ptr, len, MADV_RANDOM)) + fatal("madvice failed: %s", name); + + /* populate ptes */ + for (i = 0; i < nr_pages ; i++) { + if (vec[i] & 1) + (void)*(volatile int *)(ptr + i * page_size); + } + + /* turn off harvesting reference bits */ + if (madvise(ptr, len, MADV_SEQUENTIAL)) + fatal("madvice failed: %s", name); + + if (pagemap_read(buf, (unsigned long)ptr / page_size, + nr_pages) != nr_pages) + fatal("cannot read pagemap"); + + munmap(ptr, len); + + for (i = 0; i < nr_pages; i++) { + pfn = pagemap_pfn(buf[i]); + if (!pfn) + continue; + if (!kpageflags_read(&flags, pfn, 1)) + continue; + if (first && opt_list) { + first = 0; + flush_page_range(); + show_file(name, st); + } + add_page(off / page_size + i, pfn, flags, buf[i]); + } + } + + close(fd); +} + +int walk_tree(const char *name, const struct stat *st, int type, struct FTW *f) +{ + (void)f; + switch (type) { + case FTW_F: + if (S_ISREG(st->st_mode)) + walk_file(name, st); + break; + case FTW_DNR: + fprintf(stderr, "cannot read dir: %s\n", name); + break; + } + return 0; +} + +static void walk_page_cache(void) +{ + struct stat st; + + kpageflags_fd = checked_open(PROC_KPAGEFLAGS, O_RDONLY); + pagemap_fd = checked_open("/proc/self/pagemap", O_RDONLY); + + if (stat(opt_file, &st)) + fatal("stat failed: %s\n", opt_file); + + if (S_ISREG(st.st_mode)) { + walk_file(opt_file, &st); + } else if (S_ISDIR(st.st_mode)) { + /* do not follow symlinks and mountpoints */ + if (nftw(opt_file, walk_tree, 64, FTW_MOUNT | FTW_PHYS) < 0) + fatal("nftw failed: %s\n", opt_file); + } else + fatal("unhandled file type: %s\n", opt_file); + + close(kpageflags_fd); + close(pagemap_fd); +} + static void parse_file(const char *name) { + opt_file = name; } static void parse_addr_range(const char *optarg) @@ -991,15 +1120,20 @@ int main(int argc, char *argv[]) if (opt_list && opt_pid) printf("voffset\t"); + if (opt_list && opt_file) + printf("foffset\t"); if (opt_list == 1) printf("offset\tlen\tflags\n"); if (opt_list == 2) printf("offset\tflags\n"); - walk_addr_ranges(); + if (opt_file) + walk_page_cache(); + else + walk_addr_ranges(); if (opt_list == 1) - show_page_range(0, 0, 0); /* drain the buffer */ + flush_page_range(); if (opt_no_summary) return 0; |