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:
"Two core subsystem fixes, plus a handful of tooling fixes"

* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
perf: Fix race in swevent hash
perf: Fix race in perf_event_exec()
perf list: Robustify event printing routine
perf list: Add support for PERF_COUNT_SW_BPF_OUT
perf hists browser: Fix segfault if use symbol filter in cmdline
perf hists browser: Reset selection when refresh
perf hists browser: Add NULL pointer check to prevent crash
perf buildid-list: Fix return value of perf buildid-list -k
perf buildid-list: Show running kernel build id fix

+21 -32
+6 -29
kernel/events/core.c
··· 3154 3154 * Enable all of a task's events that have been marked enable-on-exec. 3155 3155 * This expects task == current. 3156 3156 */ 3157 - static void perf_event_enable_on_exec(struct perf_event_context *ctx) 3157 + static void perf_event_enable_on_exec(int ctxn) 3158 3158 { 3159 - struct perf_event_context *clone_ctx = NULL; 3159 + struct perf_event_context *ctx, *clone_ctx = NULL; 3160 3160 struct perf_event *event; 3161 3161 unsigned long flags; 3162 3162 int enabled = 0; 3163 3163 int ret; 3164 3164 3165 3165 local_irq_save(flags); 3166 + ctx = current->perf_event_ctxp[ctxn]; 3166 3167 if (!ctx || !ctx->nr_events) 3167 3168 goto out; 3168 3169 ··· 3206 3205 3207 3206 void perf_event_exec(void) 3208 3207 { 3209 - struct perf_event_context *ctx; 3210 3208 int ctxn; 3211 3209 3212 3210 rcu_read_lock(); 3213 - for_each_task_context_nr(ctxn) { 3214 - ctx = current->perf_event_ctxp[ctxn]; 3215 - if (!ctx) 3216 - continue; 3217 - 3218 - perf_event_enable_on_exec(ctx); 3219 - } 3211 + for_each_task_context_nr(ctxn) 3212 + perf_event_enable_on_exec(ctxn); 3220 3213 rcu_read_unlock(); 3221 3214 } 3222 3215 ··· 6488 6493 6489 6494 /* Recursion avoidance in each contexts */ 6490 6495 int recursion[PERF_NR_CONTEXTS]; 6491 - 6492 - /* Keeps track of cpu being initialized/exited */ 6493 - bool online; 6494 6496 }; 6495 6497 6496 6498 static DEFINE_PER_CPU(struct swevent_htable, swevent_htable); ··· 6745 6753 hwc->state = !(flags & PERF_EF_START); 6746 6754 6747 6755 head = find_swevent_head(swhash, event); 6748 - if (!head) { 6749 - /* 6750 - * We can race with cpu hotplug code. Do not 6751 - * WARN if the cpu just got unplugged. 6752 - */ 6753 - WARN_ON_ONCE(swhash->online); 6756 + if (WARN_ON_ONCE(!head)) 6754 6757 return -EINVAL; 6755 - } 6756 6758 6757 6759 hlist_add_head_rcu(&event->hlist_entry, head); 6758 6760 perf_event_update_userpage(event); ··· 6814 6828 int err = 0; 6815 6829 6816 6830 mutex_lock(&swhash->hlist_mutex); 6817 - 6818 6831 if (!swevent_hlist_deref(swhash) && cpu_online(cpu)) { 6819 6832 struct swevent_hlist *hlist; 6820 6833 ··· 9276 9291 struct swevent_htable *swhash = &per_cpu(swevent_htable, cpu); 9277 9292 9278 9293 mutex_lock(&swhash->hlist_mutex); 9279 - swhash->online = true; 9280 9294 if (swhash->hlist_refcount > 0) { 9281 9295 struct swevent_hlist *hlist; 9282 9296 ··· 9317 9333 9318 9334 static void perf_event_exit_cpu(int cpu) 9319 9335 { 9320 - struct swevent_htable *swhash = &per_cpu(swevent_htable, cpu); 9321 - 9322 9336 perf_event_exit_cpu_context(cpu); 9323 - 9324 - mutex_lock(&swhash->hlist_mutex); 9325 - swhash->online = false; 9326 - swevent_hlist_release(swhash); 9327 - mutex_unlock(&swhash->hlist_mutex); 9328 9337 } 9329 9338 #else 9330 9339 static inline void perf_event_exit_cpu(int cpu) { }
+1 -1
tools/perf/builtin-buildid-list.c
··· 110 110 setup_pager(); 111 111 112 112 if (show_kernel) 113 - return sysfs__fprintf_build_id(stdout); 113 + return !(sysfs__fprintf_build_id(stdout) > 0); 114 114 115 115 return perf_session__list_build_ids(force, with_hits); 116 116 }
+8
tools/perf/ui/browsers/hists.c
··· 298 298 struct callchain_list *cl = container_of(ms, struct callchain_list, ms); 299 299 bool has_children; 300 300 301 + if (!he || !ms) 302 + return false; 303 + 301 304 if (ms == &he->ms) 302 305 has_children = hist_entry__toggle_fold(he); 303 306 else ··· 931 928 } 932 929 933 930 ui_browser__hists_init_top(browser); 931 + hb->he_selection = NULL; 932 + hb->selection = NULL; 934 933 935 934 for (nd = browser->top; nd; nd = rb_next(nd)) { 936 935 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); ··· 1038 1033 * and stop when we printed enough lines to fill the screen. 1039 1034 */ 1040 1035 do_offset: 1036 + if (!nd) 1037 + return; 1038 + 1041 1039 if (offset > 0) { 1042 1040 do { 1043 1041 h = rb_entry(nd, struct hist_entry, rb_node);
+1 -1
tools/perf/util/build-id.c
··· 91 91 bid += 2; 92 92 } 93 93 94 - return raw - build_id; 94 + return (bid - bf) + 1; 95 95 } 96 96 97 97 int sysfs__sprintf_build_id(const char *root_dir, char *sbuild_id)
+5 -1
tools/perf/util/parse-events.c
··· 124 124 .symbol = "dummy", 125 125 .alias = "", 126 126 }, 127 + [PERF_COUNT_SW_BPF_OUTPUT] = { 128 + .symbol = "bpf-output", 129 + .alias = "", 130 + }, 127 131 }; 128 132 129 133 #define __PERF_EVENT_FIELD(config, name) \ ··· 1883 1879 1884 1880 for (i = 0; i < max; i++, syms++) { 1885 1881 1886 - if (event_glob != NULL && 1882 + if (event_glob != NULL && syms->symbol != NULL && 1887 1883 !(strglobmatch(syms->symbol, event_glob) || 1888 1884 (syms->alias && strglobmatch(syms->alias, event_glob)))) 1889 1885 continue;