Commit 6155bc14315763cf0f1989b3636ccc2f3e57f0d6

Authored by Linus Torvalds

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

Showing 13 changed files Side-by-side Diff

arch/x86/kernel/cpu/perf_event_intel.c
... ... @@ -2431,6 +2431,7 @@
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));
arch/x86/kernel/cpu/perf_event_intel_rapl.c
... ... @@ -142,7 +142,7 @@
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)
arch/x86/kernel/cpu/perf_event_intel_uncore.c
... ... @@ -840,7 +840,6 @@
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);
847 846  
... ... @@ -1004,10 +1003,8 @@
1004 1003 pmu = &type->pmus[j];
1005 1004 box = *per_cpu_ptr(pmu->box, cpu);
1006 1005 /* called by uncore_cpu_init? */
1007   - if (box && box->phys_id >= 0) {
1008   - uncore_box_init(box);
  1006 + if (box && box->phys_id >= 0)
1009 1007 continue;
1010   - }
1011 1008  
1012 1009 for_each_online_cpu(k) {
1013 1010 exist = *per_cpu_ptr(pmu->box, k);
1014 1011  
... ... @@ -1023,10 +1020,8 @@
1023 1020 }
1024 1021 }
1025 1022  
1026   - if (box) {
  1023 + if (box)
1027 1024 box->phys_id = phys_id;
1028   - uncore_box_init(box);
1029   - }
1030 1025 }
1031 1026 }
1032 1027 return 0;
arch/x86/kernel/cpu/perf_event_intel_uncore.h
... ... @@ -257,6 +257,14 @@
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)
... ... @@ -265,6 +273,8 @@
265 273  
266 274 static inline void uncore_enable_box(struct intel_uncore_box *box)
267 275 {
  276 + uncore_box_init(box);
  277 +
268 278 if (box->pmu->type->ops->enable_box)
269 279 box->pmu->type->ops->enable_box(box);
270 280 }
... ... @@ -285,14 +295,6 @@
285 295 struct perf_event *event)
286 296 {
287 297 return box->pmu->type->ops->read_counter(box, event);
288   -}
289   -
290   -static inline void uncore_box_init(struct intel_uncore_box *box)
291   -{
292   - if (!test_and_set_bit(UNCORE_BOX_FLAG_INITIATED, &box->flags)) {
293   - if (box->pmu->type->ops->init_box)
294   - box->pmu->type->ops->init_box(box);
295   - }
296 298 }
297 299  
298 300 static inline bool uncore_box_is_fake(struct intel_uncore_box *box)
include/linux/perf_event.h
... ... @@ -450,11 +450,6 @@
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 *
... ... @@ -462,7 +457,6 @@
462 457 */
463 458 struct perf_event_context {
464 459 struct pmu *pmu;
465   - enum perf_event_context_type type;
466 460 /*
467 461 * Protect the states of the events in the list,
468 462 * nr_active, and the list:
kernel/events/core.c
... ... @@ -6776,7 +6776,6 @@
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);
... ... @@ -7420,7 +7419,19 @@
7420 7419 * task or CPU context:
7421 7420 */
7422 7421 if (move_group) {
7423   - if (group_leader->ctx->type != ctx->type)
  7422 + /*
  7423 + * Make sure we're both on the same task, or both
  7424 + * per-cpu events.
  7425 + */
  7426 + if (group_leader->ctx->task != ctx->task)
  7427 + goto err_context;
  7428 +
  7429 + /*
  7430 + * Make sure we're both events for the same CPU;
  7431 + * grouping events for different CPUs is broken; since
  7432 + * you can never concurrently schedule them anyhow.
  7433 + */
  7434 + if (group_leader->cpu != event->cpu)
7424 7435 goto err_context;
7425 7436 } else {
7426 7437 if (group_leader->ctx != ctx)
tools/perf/scripts/perl/Perf-Trace-Util/Context.c
... ... @@ -5,7 +5,10 @@
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.
tools/perf/util/annotate.c
... ... @@ -177,14 +177,17 @@
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  
... ... @@ -208,6 +211,13 @@
208 211  
209 212 static void lock__delete(struct ins_operands *ops)
210 213 {
  214 + struct ins *ins = ops->locked.ins;
  215 +
  216 + if (ins && ins->ops->free)
  217 + ins->ops->free(ops->locked.ops);
  218 + else
  219 + ins__delete(ops->locked.ops);
  220 +
211 221 zfree(&ops->locked.ops);
212 222 zfree(&ops->target.raw);
213 223 zfree(&ops->target.name);
... ... @@ -531,8 +541,8 @@
531 541 if (!dl->ins->ops)
532 542 return;
533 543  
534   - if (dl->ins->ops->parse)
535   - dl->ins->ops->parse(&dl->ops);
  544 + if (dl->ins->ops->parse && dl->ins->ops->parse(&dl->ops) < 0)
  545 + dl->ins = NULL;
536 546 }
537 547  
538 548 static int disasm_line__parse(char *line, char **namep, char **rawp)
tools/perf/util/evlist.c
... ... @@ -1445,7 +1445,7 @@
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;
tools/perf/util/map.h
... ... @@ -116,6 +116,22 @@
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,
tools/perf/util/probe-event.c
... ... @@ -446,7 +446,7 @@
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;
453 453  
454 454  
... ... @@ -2193,18 +2193,17 @@
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) \
2211 2210  
... ... @@ -2222,10 +2221,10 @@
2222 2221 struct kmap *kmap = NULL;
2223 2222 struct ref_reloc_sym *reloc_sym = NULL;
2224 2223 struct symbol *sym;
2225   - struct rb_node *nd;
2226 2224 struct probe_trace_event *tev;
2227 2225 struct perf_probe_point *pp = &pev->point;
2228 2226 struct probe_trace_point *tp;
  2227 + int num_matched_functions;
2229 2228 int ret, i;
2230 2229  
2231 2230 /* Init maps of given executable or kernel */
... ... @@ -2242,10 +2241,8 @@
2242 2241 * Load matched symbols: Since the different local symbols may have
2243 2242 * same name but different addresses, this lists all the symbols.
2244 2243 */
2245   - num_matched_functions = 0;
2246   - looking_function_name = pp->function;
2247   - ret = map__load(map, probe_function_filter);
2248   - if (ret || num_matched_functions == 0) {
  2244 + num_matched_functions = find_probe_functions(map, pp->function);
  2245 + if (num_matched_functions == 0) {
2249 2246 pr_err("Failed to find symbol %s in %s\n", pp->function,
2250 2247 target ? : "kernel");
2251 2248 ret = -ENOENT;
... ... @@ -2257,7 +2254,7 @@
2257 2254 goto out;
2258 2255 }
2259 2256  
2260   - if (!pev->uprobes) {
  2257 + if (!pev->uprobes && !pp->retprobe) {
2261 2258 kmap = map__kmap(map);
2262 2259 reloc_sym = kmap->ref_reloc_sym;
2263 2260 if (!reloc_sym) {
... ... @@ -2275,7 +2272,8 @@
2275 2272 }
2276 2273  
2277 2274 ret = 0;
2278   - map__for_each_symbol(map, sym, nd) {
  2275 +
  2276 + map__for_each_symbol_by_name(map, pp->function, sym) {
2279 2277 tev = (*tevs) + ret;
2280 2278 tp = &tev->point;
2281 2279 if (ret == num_matched_functions) {
tools/perf/util/symbol.c
... ... @@ -396,6 +396,7 @@
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;
... ... @@ -403,7 +404,6 @@
403 404 n = symbols->rb_node;
404 405  
405 406 while (n) {
406   - struct symbol_name_rb_node *s;
407 407 int cmp;
408 408  
409 409 s = rb_entry(n, struct symbol_name_rb_node, rb_node);
410 410  
... ... @@ -414,10 +414,24 @@
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,
... ... @@ -436,6 +450,17 @@
436 450 return symbols__next(sym);
437 451 }
438 452  
  453 +struct symbol *symbol__next_by_name(struct symbol *sym)
  454 +{
  455 + struct symbol_name_rb_node *s = container_of(sym, struct symbol_name_rb_node, sym);
  456 + struct rb_node *n = rb_next(&s->rb_node);
  457 +
  458 + return n ? &rb_entry(n, struct symbol_name_rb_node, rb_node)->sym : NULL;
  459 +}
  460 +
  461 + /*
  462 + * Teturns first symbol that matched with @name.
  463 + */
439 464 struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type,
440 465 const char *name)
441 466 {
tools/perf/util/symbol.h
... ... @@ -231,6 +231,7 @@
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);