summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-04-02 11:06:34 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2018-04-02 11:06:34 -0700
commit486adcea4a63bec206cba6f0d7f301fb945ae9d3 (patch)
tree1cdf7fed3628390186b5493087612f3681e9e912 /drivers
parent701f3b314905ac05f09fc052c87b022825d831f2 (diff)
parent1159e09476536250c2a0173d4298d15114df7a89 (diff)
downloadlinux-486adcea4a63bec206cba6f0d7f301fb945ae9d3.tar.bz2
Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf updates from Ingo Molnar: "The main kernel side changes were: - Modernize the kprobe and uprobe creation/destruction tooling ABIs: The existing text based APIs (kprobe_events and uprobe_events in tracefs), are naive, limited ABIs in that they require user-space to clean up after themselves, which is both difficult and fragile if the tool is buggy or exits unexpectedly. In other words they are not really suited for modern, robust tooling. So introduce a modern, file descriptor based ABI that does not have these limitations: introduce the 'perf_kprobe' and 'perf_uprobe' PMUs and extend the perf_event_open() syscall to create events with a kprobe/uprobe attached to them. These [k,u]probe are associated with this file descriptor, so they are not available in tracefs. (Song Liu) - Intel Cannon Lake CPU support (Harry Pan) - Intel PT cleanups (Alexander Shishkin) - Improve the performance of pinned/flexible event groups by using RB trees (Alexey Budankov) - Add PERF_EVENT_IOC_MODIFY_ATTRIBUTES which allows the modification of hardware breakpoints, which new ABI variant massively speeds up existing tooling that uses hardware breakpoints to instrument (and debug) memory usage. (Milind Chabbi, Jiri Olsa) - Various Intel PEBS handling fixes and improvements, and other Intel PMU improvements (Kan Liang) - Various perf core improvements and optimizations (Peter Zijlstra) - ... misc cleanups, fixes and updates. There's over 200 tooling commits, here's an (imperfect) list of highlights: - 'perf annotate' improvements: * Recognize and handle jumps to other functions as calls, which improves the navigation along jumps and back. (Arnaldo Carvalho de Melo) * Add the 'P' hotkey in TUI annotation to dump annotation output into a file, to ease e-mail reporting of annotation details. (Arnaldo Carvalho de Melo) * Add an IPC/cycles column to the TUI (Jin Yao) * Improve s390 assembly annotation (Thomas Richter) * Refactor the output formatting logic to better separate it into interactive and non-interactive features and add the --stdio2 output variant to demonstrate this. (Arnaldo Carvalho de Melo) - 'perf script' improvements: * Add Python 3 support (Jaroslav Škarvada) * Add --show-round-event (Jiri Olsa) - 'perf c2c' improvements: * Add NUMA analysis support (Jiri Olsa) - 'perf trace' improvements: * Improve PowerPC support (Ravi Bangoria) - 'perf inject' improvements: * Integrate ARM CoreSight traces (Robert Walker) - 'perf stat' improvements: * Add the --interval-count option (yuzhoujian) * Add the --timeout option (yuzhoujian) - 'perf sched' improvements (Changbin Du) - Vendor events improvements : * Add IBM s390 vendor events (Thomas Richter) * Add and improve arm64 vendor events (John Garry, Ganapatrao Kulkarni) * Update POWER9 vendor events (Sukadev Bhattiprolu) - Intel PT tooling improvements (Adrian Hunter) - PMU handling improvements (Agustin Vega-Frias) - Record machine topology in perf.data (Jiri Olsa) - Various overwrite related cleanups (Kan Liang) - Add arm64 dwarf post unwind support (Kim Phillips, Jean Pihet) - ... and lots of other changes, cleanups and fixes, see the shortlog and Git history for details" * 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (262 commits) perf/x86/intel: Enable C-state residency events for Cannon Lake perf/x86/intel: Add Cannon Lake support for RAPL profiling perf/x86/pt, coresight: Clean up address filter structure perf vendor events s390: Add JSON files for IBM z14 perf vendor events s390: Add JSON files for IBM z13 perf vendor events s390: Add JSON files for IBM zEC12 zBC12 perf vendor events s390: Add JSON files for IBM z196 perf vendor events s390: Add JSON files for IBM z10EC z10BC perf mmap: Be consistent when checking for an unmaped ring buffer perf mmap: Fix accessing unmapped mmap in perf_mmap__read_done() perf build: Fix check-headers.sh opts assignment perf/x86: Update rdpmc_always_available static key to the modern API perf annotate: Use absolute addresses to calculate jump target offsets perf annotate: Defer searching for comma in raw line till it is needed perf annotate: Support jumping from one function to another perf annotate: Add "_local" to jump/offset validation routines perf python: Reference Py_None before returning it perf annotate: Mark jumps to outher functions with the call arrow perf annotate: Pass function descriptor to its instruction parsing routines perf annotate: No need to calculate notes->start twice ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/bus/arm-cci.c2
-rw-r--r--drivers/bus/arm-ccn.c4
-rw-r--r--drivers/hwtracing/coresight/coresight-etm-perf.c59
-rw-r--r--drivers/perf/arm_dsu_pmu.c2
-rw-r--r--drivers/perf/arm_pmu.c2
-rw-r--r--drivers/perf/hisilicon/hisi_uncore_pmu.c3
-rw-r--r--drivers/perf/qcom_l2_pmu.c7
-rw-r--r--drivers/perf/qcom_l3_pmu.c2
-rw-r--r--drivers/perf/xgene_pmu.c4
9 files changed, 38 insertions, 47 deletions
diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c
index 5426c04fe24b..c4c0c8560cce 100644
--- a/drivers/bus/arm-cci.c
+++ b/drivers/bus/arm-cci.c
@@ -1311,7 +1311,7 @@ validate_group(struct perf_event *event)
if (!validate_event(event->pmu, &fake_pmu, leader))
return -EINVAL;
- list_for_each_entry(sibling, &leader->sibling_list, group_entry) {
+ for_each_sibling_event(sibling, leader) {
if (!validate_event(event->pmu, &fake_pmu, sibling))
return -EINVAL;
}
diff --git a/drivers/bus/arm-ccn.c b/drivers/bus/arm-ccn.c
index b52332e52ca5..65b7e4042ece 100644
--- a/drivers/bus/arm-ccn.c
+++ b/drivers/bus/arm-ccn.c
@@ -846,11 +846,11 @@ static int arm_ccn_pmu_event_init(struct perf_event *event)
!is_software_event(event->group_leader))
return -EINVAL;
- list_for_each_entry(sibling, &event->group_leader->sibling_list,
- group_entry)
+ for_each_sibling_event(sibling, event->group_leader) {
if (sibling->pmu != event->pmu &&
!is_software_event(sibling))
return -EINVAL;
+ }
return 0;
}
diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
index 8a0ad77574e7..4e5ed6597f2f 100644
--- a/drivers/hwtracing/coresight/coresight-etm-perf.c
+++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
@@ -393,35 +393,26 @@ static int etm_addr_filters_validate(struct list_head *filters)
if (++index > ETM_ADDR_CMP_MAX)
return -EOPNOTSUPP;
+ /* filter::size==0 means single address trigger */
+ if (filter->size) {
+ /*
+ * The existing code relies on START/STOP filters
+ * being address filters.
+ */
+ if (filter->action == PERF_ADDR_FILTER_ACTION_START ||
+ filter->action == PERF_ADDR_FILTER_ACTION_STOP)
+ return -EOPNOTSUPP;
+
+ range = true;
+ } else
+ address = true;
+
/*
- * As taken from the struct perf_addr_filter documentation:
- * @range: 1: range, 0: address
- *
* At this time we don't allow range and start/stop filtering
* to cohabitate, they have to be mutually exclusive.
*/
- if ((filter->range == 1) && address)
+ if (range && address)
return -EOPNOTSUPP;
-
- if ((filter->range == 0) && range)
- return -EOPNOTSUPP;
-
- /*
- * For range filtering, the second address in the address
- * range comparator needs to be higher than the first.
- * Invalid otherwise.
- */
- if (filter->range && filter->size == 0)
- return -EINVAL;
-
- /*
- * Everything checks out with this filter, record what we've
- * received before moving on to the next one.
- */
- if (filter->range)
- range = true;
- else
- address = true;
}
return 0;
@@ -441,18 +432,20 @@ static void etm_addr_filters_sync(struct perf_event *event)
stop = start + filter->size;
etm_filter = &filters->etm_filter[i];
- if (filter->range == 1) {
+ switch (filter->action) {
+ case PERF_ADDR_FILTER_ACTION_FILTER:
etm_filter->start_addr = start;
etm_filter->stop_addr = stop;
etm_filter->type = ETM_ADDR_TYPE_RANGE;
- } else {
- if (filter->filter == 1) {
- etm_filter->start_addr = start;
- etm_filter->type = ETM_ADDR_TYPE_START;
- } else {
- etm_filter->stop_addr = stop;
- etm_filter->type = ETM_ADDR_TYPE_STOP;
- }
+ break;
+ case PERF_ADDR_FILTER_ACTION_START:
+ etm_filter->start_addr = start;
+ etm_filter->type = ETM_ADDR_TYPE_START;
+ break;
+ case PERF_ADDR_FILTER_ACTION_STOP:
+ etm_filter->stop_addr = stop;
+ etm_filter->type = ETM_ADDR_TYPE_STOP;
+ break;
}
i++;
}
diff --git a/drivers/perf/arm_dsu_pmu.c b/drivers/perf/arm_dsu_pmu.c
index 38f2cc2a6c74..660cb8ac886a 100644
--- a/drivers/perf/arm_dsu_pmu.c
+++ b/drivers/perf/arm_dsu_pmu.c
@@ -536,7 +536,7 @@ static bool dsu_pmu_validate_group(struct perf_event *event)
memset(fake_hw.used_mask, 0, sizeof(fake_hw.used_mask));
if (!dsu_pmu_validate_event(event->pmu, &fake_hw, leader))
return false;
- list_for_each_entry(sibling, &leader->sibling_list, group_entry) {
+ for_each_sibling_event(sibling, leader) {
if (!dsu_pmu_validate_event(event->pmu, &fake_hw, sibling))
return false;
}
diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
index f63db346c219..1a0d340b65cf 100644
--- a/drivers/perf/arm_pmu.c
+++ b/drivers/perf/arm_pmu.c
@@ -311,7 +311,7 @@ validate_group(struct perf_event *event)
if (!validate_event(event->pmu, &fake_pmu, leader))
return -EINVAL;
- list_for_each_entry(sibling, &leader->sibling_list, group_entry) {
+ for_each_sibling_event(sibling, leader) {
if (!validate_event(event->pmu, &fake_pmu, sibling))
return -EINVAL;
}
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
index 7ed24b954422..44df61397a38 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
@@ -82,8 +82,7 @@ static bool hisi_validate_event_group(struct perf_event *event)
counters++;
}
- list_for_each_entry(sibling, &event->group_leader->sibling_list,
- group_entry) {
+ for_each_sibling_event(sibling, event->group_leader) {
if (is_software_event(sibling))
continue;
if (sibling->pmu != event->pmu)
diff --git a/drivers/perf/qcom_l2_pmu.c b/drivers/perf/qcom_l2_pmu.c
index 4fdc8486a8e4..842135cf35a3 100644
--- a/drivers/perf/qcom_l2_pmu.c
+++ b/drivers/perf/qcom_l2_pmu.c
@@ -534,14 +534,14 @@ static int l2_cache_event_init(struct perf_event *event)
return -EINVAL;
}
- list_for_each_entry(sibling, &event->group_leader->sibling_list,
- group_entry)
+ for_each_sibling_event(sibling, event->group_leader) {
if (sibling->pmu != event->pmu &&
!is_software_event(sibling)) {
dev_dbg_ratelimited(&l2cache_pmu->pdev->dev,
"Can't create mixed PMU group\n");
return -EINVAL;
}
+ }
cluster = get_cluster_pmu(l2cache_pmu, event->cpu);
if (!cluster) {
@@ -571,8 +571,7 @@ static int l2_cache_event_init(struct perf_event *event)
return -EINVAL;
}
- list_for_each_entry(sibling, &event->group_leader->sibling_list,
- group_entry) {
+ for_each_sibling_event(sibling, event->group_leader) {
if ((sibling != event) &&
!is_software_event(sibling) &&
(L2_EVT_GROUP(sibling->attr.config) ==
diff --git a/drivers/perf/qcom_l3_pmu.c b/drivers/perf/qcom_l3_pmu.c
index 7f6b62b29e9d..2dc63d61f2ea 100644
--- a/drivers/perf/qcom_l3_pmu.c
+++ b/drivers/perf/qcom_l3_pmu.c
@@ -468,7 +468,7 @@ static bool qcom_l3_cache__validate_event_group(struct perf_event *event)
counters = event_num_counters(event);
counters += event_num_counters(leader);
- list_for_each_entry(sibling, &leader->sibling_list, group_entry) {
+ for_each_sibling_event(sibling, leader) {
if (is_software_event(sibling))
continue;
if (sibling->pmu != event->pmu)
diff --git a/drivers/perf/xgene_pmu.c b/drivers/perf/xgene_pmu.c
index eb23311bc70c..6bdb1dad805f 100644
--- a/drivers/perf/xgene_pmu.c
+++ b/drivers/perf/xgene_pmu.c
@@ -949,11 +949,11 @@ static int xgene_perf_event_init(struct perf_event *event)
!is_software_event(event->group_leader))
return -EINVAL;
- list_for_each_entry(sibling, &event->group_leader->sibling_list,
- group_entry)
+ for_each_sibling_event(sibling, event->group_leader) {
if (sibling->pmu != event->pmu &&
!is_software_event(sibling))
return -EINVAL;
+ }
return 0;
}