Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull perf fixes from Ingo Molnar:
"Mostly tooling fixes, but also an event groups fix, two PMU driver
fixes and a CPU model variant addition"

* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
perf: Tighten (and fix) the grouping condition
perf/x86/intel: Add model number for Airmont
perf/rapl: Fix crash in rapl_scale()
perf/x86/intel/uncore: Move uncore_box_init() out of driver initialization
perf probe: Fix probing kretprobes
perf symbols: Introduce 'for' method to iterate over the symbols with a given name
perf probe: Do not rely on map__load() filter to find symbols
perf symbols: Introduce method to iterate symbols ordered by name
perf symbols: Return the first entry with a given name in find_by_name method
perf annotate: Fix memory leaks in LOCK handling
perf annotate: Handle ins parsing failures
perf scripting perl: Force to use stdbool
perf evlist: Remove extraneous 'was' on error message

+107 -51
+1
arch/x86/kernel/cpu/perf_event_intel.c
··· 2431 2431 break; 2432 2432 2433 2433 case 55: /* 22nm Atom "Silvermont" */ 2434 + case 76: /* 14nm Atom "Airmont" */ 2434 2435 case 77: /* 22nm Atom "Silvermont Avoton/Rangely" */ 2435 2436 memcpy(hw_cache_event_ids, slm_hw_cache_event_ids, 2436 2437 sizeof(hw_cache_event_ids));
+1 -1
arch/x86/kernel/cpu/perf_event_intel_rapl.c
··· 142 142 * or use ldexp(count, -32). 143 143 * Watts = Joules/Time delta 144 144 */ 145 - return v << (32 - __this_cpu_read(rapl_pmu->hw_unit)); 145 + return v << (32 - __this_cpu_read(rapl_pmu)->hw_unit); 146 146 } 147 147 148 148 static u64 rapl_event_update(struct perf_event *event)
+2 -7
arch/x86/kernel/cpu/perf_event_intel_uncore.c
··· 840 840 box->phys_id = phys_id; 841 841 box->pci_dev = pdev; 842 842 box->pmu = pmu; 843 - uncore_box_init(box); 844 843 pci_set_drvdata(pdev, box); 845 844 846 845 raw_spin_lock(&uncore_box_lock); ··· 1003 1004 pmu = &type->pmus[j]; 1004 1005 box = *per_cpu_ptr(pmu->box, cpu); 1005 1006 /* called by uncore_cpu_init? */ 1006 - if (box && box->phys_id >= 0) { 1007 - uncore_box_init(box); 1007 + if (box && box->phys_id >= 0) 1008 1008 continue; 1009 - } 1010 1009 1011 1010 for_each_online_cpu(k) { 1012 1011 exist = *per_cpu_ptr(pmu->box, k); ··· 1020 1023 } 1021 1024 } 1022 1025 1023 - if (box) { 1026 + if (box) 1024 1027 box->phys_id = phys_id; 1025 - uncore_box_init(box); 1026 - } 1027 1028 } 1028 1029 } 1029 1030 return 0;
+10 -8
arch/x86/kernel/cpu/perf_event_intel_uncore.h
··· 257 257 return box->pmu->type->num_counters; 258 258 } 259 259 260 + static inline void uncore_box_init(struct intel_uncore_box *box) 261 + { 262 + if (!test_and_set_bit(UNCORE_BOX_FLAG_INITIATED, &box->flags)) { 263 + if (box->pmu->type->ops->init_box) 264 + box->pmu->type->ops->init_box(box); 265 + } 266 + } 267 + 260 268 static inline void uncore_disable_box(struct intel_uncore_box *box) 261 269 { 262 270 if (box->pmu->type->ops->disable_box) ··· 273 265 274 266 static inline void uncore_enable_box(struct intel_uncore_box *box) 275 267 { 268 + uncore_box_init(box); 269 + 276 270 if (box->pmu->type->ops->enable_box) 277 271 box->pmu->type->ops->enable_box(box); 278 272 } ··· 295 285 struct perf_event *event) 296 286 { 297 287 return box->pmu->type->ops->read_counter(box, event); 298 - } 299 - 300 - static inline void uncore_box_init(struct intel_uncore_box *box) 301 - { 302 - if (!test_and_set_bit(UNCORE_BOX_FLAG_INITIATED, &box->flags)) { 303 - if (box->pmu->type->ops->init_box) 304 - box->pmu->type->ops->init_box(box); 305 - } 306 288 } 307 289 308 290 static inline bool uncore_box_is_fake(struct intel_uncore_box *box)
-6
include/linux/perf_event.h
··· 450 450 #endif /* CONFIG_PERF_EVENTS */ 451 451 }; 452 452 453 - enum perf_event_context_type { 454 - task_context, 455 - cpu_context, 456 - }; 457 - 458 453 /** 459 454 * struct perf_event_context - event context structure 460 455 * ··· 457 462 */ 458 463 struct perf_event_context { 459 464 struct pmu *pmu; 460 - enum perf_event_context_type type; 461 465 /* 462 466 * Protect the states of the events in the list, 463 467 * nr_active, and the list:
+13 -2
kernel/events/core.c
··· 6776 6776 __perf_event_init_context(&cpuctx->ctx); 6777 6777 lockdep_set_class(&cpuctx->ctx.mutex, &cpuctx_mutex); 6778 6778 lockdep_set_class(&cpuctx->ctx.lock, &cpuctx_lock); 6779 - cpuctx->ctx.type = cpu_context; 6780 6779 cpuctx->ctx.pmu = pmu; 6781 6780 6782 6781 __perf_cpu_hrtimer_init(cpuctx, cpu); ··· 7419 7420 * task or CPU context: 7420 7421 */ 7421 7422 if (move_group) { 7422 - if (group_leader->ctx->type != ctx->type) 7423 + /* 7424 + * Make sure we're both on the same task, or both 7425 + * per-cpu events. 7426 + */ 7427 + if (group_leader->ctx->task != ctx->task) 7428 + goto err_context; 7429 + 7430 + /* 7431 + * Make sure we're both events for the same CPU; 7432 + * grouping events for different CPUs is broken; since 7433 + * you can never concurrently schedule them anyhow. 7434 + */ 7435 + if (group_leader->cpu != event->cpu) 7423 7436 goto err_context; 7424 7437 } else { 7425 7438 if (group_leader->ctx != ctx)
+4 -1
tools/perf/scripts/perl/Perf-Trace-Util/Context.c
··· 5 5 * ANY CHANGES MADE HERE WILL BE LOST! 6 6 * 7 7 */ 8 - 8 + #include <stdbool.h> 9 + #ifndef HAS_BOOL 10 + # define HAS_BOOL 1 11 + #endif 9 12 #line 1 "Context.xs" 10 13 /* 11 14 * Context.xs. XS interfaces for perf script.
+14 -4
tools/perf/util/annotate.c
··· 177 177 goto out_free_ops; 178 178 179 179 ops->locked.ins = ins__find(name); 180 + free(name); 181 + 180 182 if (ops->locked.ins == NULL) 181 183 goto out_free_ops; 182 184 183 185 if (!ops->locked.ins->ops) 184 186 return 0; 185 187 186 - if (ops->locked.ins->ops->parse) 187 - ops->locked.ins->ops->parse(ops->locked.ops); 188 + if (ops->locked.ins->ops->parse && 189 + ops->locked.ins->ops->parse(ops->locked.ops) < 0) 190 + goto out_free_ops; 188 191 189 192 return 0; 190 193 ··· 211 208 212 209 static void lock__delete(struct ins_operands *ops) 213 210 { 211 + struct ins *ins = ops->locked.ins; 212 + 213 + if (ins && ins->ops->free) 214 + ins->ops->free(ops->locked.ops); 215 + else 216 + ins__delete(ops->locked.ops); 217 + 214 218 zfree(&ops->locked.ops); 215 219 zfree(&ops->target.raw); 216 220 zfree(&ops->target.name); ··· 541 531 if (!dl->ins->ops) 542 532 return; 543 533 544 - if (dl->ins->ops->parse) 545 - dl->ins->ops->parse(&dl->ops); 534 + if (dl->ins->ops->parse && dl->ins->ops->parse(&dl->ops) < 0) 535 + dl->ins = NULL; 546 536 } 547 537 548 538 static int disasm_line__parse(char *line, char **namep, char **rawp)
+1 -1
tools/perf/util/evlist.c
··· 1445 1445 case ENOENT: 1446 1446 scnprintf(buf, size, "%s", 1447 1447 "Error:\tUnable to find debugfs\n" 1448 - "Hint:\tWas your kernel was compiled with debugfs support?\n" 1448 + "Hint:\tWas your kernel compiled with debugfs support?\n" 1449 1449 "Hint:\tIs the debugfs filesystem mounted?\n" 1450 1450 "Hint:\tTry 'sudo mount -t debugfs nodev /sys/kernel/debug'"); 1451 1451 break;
+16
tools/perf/util/map.h
··· 116 116 #define map__for_each_symbol(map, pos, n) \ 117 117 dso__for_each_symbol(map->dso, pos, n, map->type) 118 118 119 + /* map__for_each_symbol_with_name - iterate over the symbols in the given map 120 + * that have the given name 121 + * 122 + * @map: the 'struct map *' in which symbols itereated 123 + * @sym_name: the symbol name 124 + * @pos: the 'struct symbol *' to use as a loop cursor 125 + * @filter: to use when loading the DSO 126 + */ 127 + #define __map__for_each_symbol_by_name(map, sym_name, pos, filter) \ 128 + for (pos = map__find_symbol_by_name(map, sym_name, filter); \ 129 + pos && strcmp(pos->name, sym_name) == 0; \ 130 + pos = symbol__next_by_name(pos)) 131 + 132 + #define map__for_each_symbol_by_name(map, sym_name, pos) \ 133 + __map__for_each_symbol_by_name(map, sym_name, (pos), NULL) 134 + 119 135 typedef int (*symbol_filter_t)(struct map *map, struct symbol *sym); 120 136 121 137 void map__init(struct map *map, enum map_type type,
+16 -18
tools/perf/util/probe-event.c
··· 446 446 } 447 447 448 448 for (i = 0; i < ntevs; i++) { 449 - if (tevs[i].point.address) { 449 + if (tevs[i].point.address && !tevs[i].point.retprobe) { 450 450 tmp = strdup(reloc_sym->name); 451 451 if (!tmp) 452 452 return -ENOMEM; ··· 2193 2193 return ret; 2194 2194 } 2195 2195 2196 - static char *looking_function_name; 2197 - static int num_matched_functions; 2198 - 2199 - static int probe_function_filter(struct map *map __maybe_unused, 2200 - struct symbol *sym) 2196 + static int find_probe_functions(struct map *map, char *name) 2201 2197 { 2202 - if ((sym->binding == STB_GLOBAL || sym->binding == STB_LOCAL) && 2203 - strcmp(looking_function_name, sym->name) == 0) { 2204 - num_matched_functions++; 2205 - return 0; 2198 + int found = 0; 2199 + struct symbol *sym; 2200 + 2201 + map__for_each_symbol_by_name(map, name, sym) { 2202 + if (sym->binding == STB_GLOBAL || sym->binding == STB_LOCAL) 2203 + found++; 2206 2204 } 2207 - return 1; 2205 + 2206 + return found; 2208 2207 } 2209 2208 2210 2209 #define strdup_or_goto(str, label) \ ··· 2221 2222 struct kmap *kmap = NULL; 2222 2223 struct ref_reloc_sym *reloc_sym = NULL; 2223 2224 struct symbol *sym; 2224 - struct rb_node *nd; 2225 2225 struct probe_trace_event *tev; 2226 2226 struct perf_probe_point *pp = &pev->point; 2227 2227 struct probe_trace_point *tp; 2228 + int num_matched_functions; 2228 2229 int ret, i; 2229 2230 2230 2231 /* Init maps of given executable or kernel */ ··· 2241 2242 * Load matched symbols: Since the different local symbols may have 2242 2243 * same name but different addresses, this lists all the symbols. 2243 2244 */ 2244 - num_matched_functions = 0; 2245 - looking_function_name = pp->function; 2246 - ret = map__load(map, probe_function_filter); 2247 - if (ret || num_matched_functions == 0) { 2245 + num_matched_functions = find_probe_functions(map, pp->function); 2246 + if (num_matched_functions == 0) { 2248 2247 pr_err("Failed to find symbol %s in %s\n", pp->function, 2249 2248 target ? : "kernel"); 2250 2249 ret = -ENOENT; ··· 2254 2257 goto out; 2255 2258 } 2256 2259 2257 - if (!pev->uprobes) { 2260 + if (!pev->uprobes && !pp->retprobe) { 2258 2261 kmap = map__kmap(map); 2259 2262 reloc_sym = kmap->ref_reloc_sym; 2260 2263 if (!reloc_sym) { ··· 2272 2275 } 2273 2276 2274 2277 ret = 0; 2275 - map__for_each_symbol(map, sym, nd) { 2278 + 2279 + map__for_each_symbol_by_name(map, pp->function, sym) { 2276 2280 tev = (*tevs) + ret; 2277 2281 tp = &tev->point; 2278 2282 if (ret == num_matched_functions) {
+28 -3
tools/perf/util/symbol.c
··· 396 396 const char *name) 397 397 { 398 398 struct rb_node *n; 399 + struct symbol_name_rb_node *s; 399 400 400 401 if (symbols == NULL) 401 402 return NULL; ··· 404 403 n = symbols->rb_node; 405 404 406 405 while (n) { 407 - struct symbol_name_rb_node *s; 408 406 int cmp; 409 407 410 408 s = rb_entry(n, struct symbol_name_rb_node, rb_node); ··· 414 414 else if (cmp > 0) 415 415 n = n->rb_right; 416 416 else 417 - return &s->sym; 417 + break; 418 418 } 419 419 420 - return NULL; 420 + if (n == NULL) 421 + return NULL; 422 + 423 + /* return first symbol that has same name (if any) */ 424 + for (n = rb_prev(n); n; n = rb_prev(n)) { 425 + struct symbol_name_rb_node *tmp; 426 + 427 + tmp = rb_entry(n, struct symbol_name_rb_node, rb_node); 428 + if (strcmp(tmp->sym.name, s->sym.name)) 429 + break; 430 + 431 + s = tmp; 432 + } 433 + 434 + return &s->sym; 421 435 } 422 436 423 437 struct symbol *dso__find_symbol(struct dso *dso, ··· 450 436 return symbols__next(sym); 451 437 } 452 438 439 + struct symbol *symbol__next_by_name(struct symbol *sym) 440 + { 441 + struct symbol_name_rb_node *s = container_of(sym, struct symbol_name_rb_node, sym); 442 + struct rb_node *n = rb_next(&s->rb_node); 443 + 444 + return n ? &rb_entry(n, struct symbol_name_rb_node, rb_node)->sym : NULL; 445 + } 446 + 447 + /* 448 + * Teturns first symbol that matched with @name. 449 + */ 453 450 struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type, 454 451 const char *name) 455 452 {
+1
tools/perf/util/symbol.h
··· 231 231 u64 addr); 232 232 struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type, 233 233 const char *name); 234 + struct symbol *symbol__next_by_name(struct symbol *sym); 234 235 235 236 struct symbol *dso__first_symbol(struct dso *dso, enum map_type type); 236 237 struct symbol *dso__next_symbol(struct symbol *sym);