Commit ca21b9b3 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'perf-urgent-2020-02-09' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull perf fixes from Thomas Gleixner:
 "A set of fixes and improvements for the perf subsystem:

  Kernel fixes:

   - Install cgroup events to the correct CPU context to prevent a
     potential list double add

   - Prevent an integer underflow in the perf mlock accounting

   - Add a missing prototype for arch_perf_update_userpage()

  Tooling:

   - Add a missing unlock in the error path of maps__insert() in perf
     maps.

   - Fix the build with the latest libbfd

   - Fix the perf parser so it does not delete parse event terms, which
     caused a regression for using perf with the ARM CoreSight as the
     sink configuration was missing due to the deletion.

   - Fix the double free in the perf CPU map merging test case

   - Add the missing ustring support for the perf probe command"

* tag 'perf-urgent-2020-02-09' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  perf maps: Add missing unlock to maps__insert() error case
  perf probe: Add ustring support for perf probe command
  perf: Make perf able to build with latest libbfd
  perf test: Fix test case Merge cpu map
  perf parse: Copy string to perf_evsel_config_term
  perf parse: Refactor 'struct perf_evsel_config_term'
  kernel/events: Add a missing prototype for arch_perf_update_userpage()
  perf/cgroups: Install cgroup events to correct cpuctx
  perf/core: Fix mlock accounting in perf_mmap()
parents 2fbc23c7 45f03574
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -1544,4 +1544,8 @@ int perf_event_exit_cpu(unsigned int cpu);
#define perf_event_exit_cpu	NULL
#endif

extern void __weak arch_perf_update_userpage(struct perf_event *event,
					     struct perf_event_mmap_page *userpg,
					     u64 now);

#endif /* _LINUX_PERF_EVENT_H */
+13 −4
Original line number Diff line number Diff line
@@ -951,9 +951,9 @@ list_update_cgroup_event(struct perf_event *event,

	/*
	 * Because cgroup events are always per-cpu events,
	 * this will always be called from the right CPU.
	 * @ctx == &cpuctx->ctx.
	 */
	cpuctx = __get_cpu_context(ctx);
	cpuctx = container_of(ctx, struct perf_cpu_context, ctx);

	/*
	 * Since setting cpuctx->cgrp is conditional on the current @cgrp
@@ -979,7 +979,8 @@ list_update_cgroup_event(struct perf_event *event,

	cpuctx_entry = &cpuctx->cgrp_cpuctx_entry;
	if (add)
		list_add(cpuctx_entry, this_cpu_ptr(&cgrp_cpuctx_list));
		list_add(cpuctx_entry,
			 per_cpu_ptr(&cgrp_cpuctx_list, event->cpu));
	else
		list_del(cpuctx_entry);
}
@@ -5916,7 +5917,15 @@ accounting:
	 */
	user_lock_limit *= num_online_cpus();

	user_locked = atomic_long_read(&user->locked_vm) + user_extra;
	user_locked = atomic_long_read(&user->locked_vm);

	/*
	 * sysctl_perf_event_mlock may have changed, so that
	 *     user->locked_vm > user_lock_limit
	 */
	if (user_locked > user_lock_limit)
		user_locked = user_lock_limit;
	user_locked += user_extra;

	if (user_locked > user_lock_limit) {
		/*
+1 −1
Original line number Diff line number Diff line
@@ -226,7 +226,7 @@ static int cs_etm_set_sink_attr(struct perf_pmu *pmu,
		if (term->type != PERF_EVSEL__CONFIG_TERM_DRV_CFG)
			continue;

		sink = term->val.drv_cfg;
		sink = term->val.str;
		snprintf(path, PATH_MAX, "sinks/%s", sink);

		ret = perf_pmu__scan_file(pmu, path, "%x", &hash);
+0 −1
Original line number Diff line number Diff line
@@ -131,7 +131,6 @@ int test__cpu_map_merge(struct test *test __maybe_unused, int subtest __maybe_un
	TEST_ASSERT_VAL("failed to merge map: bad nr", c->nr == 5);
	cpu_map__snprint(c, buf, sizeof(buf));
	TEST_ASSERT_VAL("failed to merge map: bad result", !strcmp(buf, "1-2,4-5,7"));
	perf_cpu_map__put(a);
	perf_cpu_map__put(b);
	perf_cpu_map__put(c);
	return 0;
+5 −3
Original line number Diff line number Diff line
@@ -808,12 +808,12 @@ static void apply_config_terms(struct evsel *evsel,
				perf_evsel__reset_sample_bit(evsel, TIME);
			break;
		case PERF_EVSEL__CONFIG_TERM_CALLGRAPH:
			callgraph_buf = term->val.callgraph;
			callgraph_buf = term->val.str;
			break;
		case PERF_EVSEL__CONFIG_TERM_BRANCH:
			if (term->val.branch && strcmp(term->val.branch, "no")) {
			if (term->val.str && strcmp(term->val.str, "no")) {
				perf_evsel__set_sample_bit(evsel, BRANCH_STACK);
				parse_branch_str(term->val.branch,
				parse_branch_str(term->val.str,
						 &attr->branch_sample_type);
			} else
				perf_evsel__reset_sample_bit(evsel, BRANCH_STACK);
@@ -1265,6 +1265,8 @@ static void perf_evsel__free_config_terms(struct evsel *evsel)

	list_for_each_entry_safe(term, h, &evsel->config_terms, list) {
		list_del_init(&term->list);
		if (term->free_str)
			zfree(&term->val.str);
		free(term);
	}
}
Loading