Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6854daa0 authored by Ingo Molnar's avatar Ingo Molnar
Browse files

Merge tag 'perf-core-for-mingo-5.1-20190206' of...

Merge tag 'perf-core-for-mingo-5.1-20190206' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux

 into perf/core

Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo:

Hardware tracing:

  Adrian Hunter:

  - Handle calls optimized into jumps to a different symbol
    in the thread stack routines used to process hardware traces (Adrian Hunter)

Intel PT:

  Adrian Hunter:

  - Fix overlap calculation for padding.

  - Fix CYC timestamp calculation after OVF.

  - Packet splitting can only happen in 32-bit.

  - Add timestamp to auxtrace errors.

ARM CoreSight:

  Leo Yan:

  - Add last instruction information in packet

  - Set sample flags for instruction range, exception and
    return packets and for a trace discontinuity.

  - Add exception number in exception packet

  - Change tuple from traceID-CPU# to traceID-metadata

  - Add traceID in packet

  Mathieu Poirier:

  - Add "sinks" group to PMU directory

  - Use event attributes to send sink information to kernel

  - Remove set_drv_config() API, no longer used.

perf annotate:

  Jiri Olsa:

  - Delay symbol annotation to the resort phase, speeding up 'perf report'
    startup.

perf record:

  Alexey Budankov:

  - Allow binding userspace buffers to NUMA nodes.

Symbols:

  Adrian Hunter:

  - Fix calculating of symbol sizes when splitting kallsyms into
    maps for kcore processing.

Vendor events:

  William Cohen:

  - Intel: Fix Load_Miss_Real_Latency on CLX

Misc:

  Arnaldo Carvalho de Melo:

  - Streamline headers, removing includes when all that is needed are
    just forward declarations, fixup the fallout for cases where headers
    should have been explicitely included but were instead obtained
    indirectly, by sheer luck.

  - Add fallback versions for CPU_{OR,EQUAL}(), so that code using it
    continue to build on older systems where those were not yet introduced
    or in systems using some other libc than the GNU one where those
    helpers aren't present.

Documentation:

  Changbin Du:

  - Add documentation for BPF event selection.

Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parents 9821517a 16bd4321
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -1600,7 +1600,7 @@ static void aux_sdb_init(unsigned long sdb)

/*
 * aux_buffer_setup() - Setup AUX buffer for diagnostic mode sampling
 * @cpu:	On which to allocate, -1 means current
 * @event:	Event the buffer is setup for, event->cpu == -1 means current
 * @pages:	Array of pointers to buffer pages passed from perf core
 * @nr_pages:	Total pages
 * @snapshot:	Flag for snapshot mode
@@ -1612,8 +1612,8 @@ static void aux_sdb_init(unsigned long sdb)
 *
 * Return the private AUX buffer structure if success or NULL if fails.
 */
static void *aux_buffer_setup(int cpu, void **pages, int nr_pages,
			      bool snapshot)
static void *aux_buffer_setup(struct perf_event *event, void **pages,
			      int nr_pages, bool snapshot)
{
	struct sf_buffer *sfb;
	struct aux_buffer *aux;
+3 −1
Original line number Diff line number Diff line
@@ -77,10 +77,12 @@ static size_t buf_size(struct page *page)
}

static void *
bts_buffer_setup_aux(int cpu, void **pages, int nr_pages, bool overwrite)
bts_buffer_setup_aux(struct perf_event *event, void **pages,
		     int nr_pages, bool overwrite)
{
	struct bts_buffer *buf;
	struct page *page;
	int cpu = event->cpu;
	int node = (cpu == -1) ? cpu : cpu_to_node(cpu);
	unsigned long offset;
	size_t size = nr_pages << PAGE_SHIFT;
+3 −2
Original line number Diff line number Diff line
@@ -1114,10 +1114,11 @@ static int pt_buffer_init_topa(struct pt_buffer *buf, unsigned long nr_pages,
 * Return:	Our private PT buffer structure.
 */
static void *
pt_buffer_setup_aux(int cpu, void **pages, int nr_pages, bool snapshot)
pt_buffer_setup_aux(struct perf_event *event, void **pages,
		    int nr_pages, bool snapshot)
{
	struct pt_buffer *buf;
	int node, ret;
	int node, ret, cpu = event->cpu;

	if (!nr_pages)
		return NULL;
+97 −15
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
#include <linux/perf_event.h>
#include <linux/percpu-defs.h>
#include <linux/slab.h>
#include <linux/stringhash.h>
#include <linux/types.h>
#include <linux/workqueue.h>

@@ -30,11 +31,14 @@ static DEFINE_PER_CPU(struct coresight_device *, csdev_src);
PMU_FORMAT_ATTR(cycacc,		"config:" __stringify(ETM_OPT_CYCACC));
PMU_FORMAT_ATTR(timestamp,	"config:" __stringify(ETM_OPT_TS));
PMU_FORMAT_ATTR(retstack,	"config:" __stringify(ETM_OPT_RETSTK));
/* Sink ID - same for all ETMs */
PMU_FORMAT_ATTR(sinkid,		"config2:0-31");

static struct attribute *etm_config_formats_attr[] = {
	&format_attr_cycacc.attr,
	&format_attr_timestamp.attr,
	&format_attr_retstack.attr,
	&format_attr_sinkid.attr,
	NULL,
};

@@ -43,8 +47,18 @@ static const struct attribute_group etm_pmu_format_group = {
	.attrs  = etm_config_formats_attr,
};

static struct attribute *etm_config_sinks_attr[] = {
	NULL,
};

static const struct attribute_group etm_pmu_sinks_group = {
	.name   = "sinks",
	.attrs  = etm_config_sinks_attr,
};

static const struct attribute_group *etm_pmu_attr_groups[] = {
	&etm_pmu_format_group,
	&etm_pmu_sinks_group,
	NULL,
};

@@ -177,31 +191,28 @@ static void etm_free_aux(void *data)
	schedule_work(&event_data->work);
}

static void *etm_setup_aux(int event_cpu, void **pages,
static void *etm_setup_aux(struct perf_event *event, void **pages,
			   int nr_pages, bool overwrite)
{
	int cpu;
	u32 id;
	int cpu = event->cpu;
	cpumask_t *mask;
	struct coresight_device *sink;
	struct etm_event_data *event_data = NULL;

	event_data = alloc_event_data(event_cpu);
	event_data = alloc_event_data(cpu);
	if (!event_data)
		return NULL;
	INIT_WORK(&event_data->work, free_event_data);

	/*
	 * In theory nothing prevent tracers in a trace session from being
	 * associated with different sinks, nor having a sink per tracer.  But
	 * until we have HW with this kind of topology we need to assume tracers
	 * in a trace session are using the same sink.  Therefore go through
	 * the coresight bus and pick the first enabled sink.
	 *
	 * When operated from sysFS users are responsible to enable the sink
	 * while from perf, the perf tools will do it based on the choice made
	 * on the cmd line.  As such the "enable_sink" flag in sysFS is reset.
	 */
	/* First get the selected sink from user space. */
	if (event->attr.config2) {
		id = (u32)event->attr.config2;
		sink = coresight_get_sink_by_id(id);
	} else {
		sink = coresight_get_enabled_sink(true);
	}

	if (!sink || !sink_ops(sink)->alloc_buffer)
		goto err;

@@ -479,6 +490,77 @@ int etm_perf_symlink(struct coresight_device *csdev, bool link)
	return 0;
}

static ssize_t etm_perf_sink_name_show(struct device *dev,
				       struct device_attribute *dattr,
				       char *buf)
{
	struct dev_ext_attribute *ea;

	ea = container_of(dattr, struct dev_ext_attribute, attr);
	return scnprintf(buf, PAGE_SIZE, "0x%lx\n", (unsigned long)(ea->var));
}

int etm_perf_add_symlink_sink(struct coresight_device *csdev)
{
	int ret;
	unsigned long hash;
	const char *name;
	struct device *pmu_dev = etm_pmu.dev;
	struct device *pdev = csdev->dev.parent;
	struct dev_ext_attribute *ea;

	if (csdev->type != CORESIGHT_DEV_TYPE_SINK &&
	    csdev->type != CORESIGHT_DEV_TYPE_LINKSINK)
		return -EINVAL;

	if (csdev->ea != NULL)
		return -EINVAL;

	if (!etm_perf_up)
		return -EPROBE_DEFER;

	ea = devm_kzalloc(pdev, sizeof(*ea), GFP_KERNEL);
	if (!ea)
		return -ENOMEM;

	name = dev_name(pdev);
	/* See function coresight_get_sink_by_id() to know where this is used */
	hash = hashlen_hash(hashlen_string(NULL, name));

	ea->attr.attr.name = devm_kstrdup(pdev, name, GFP_KERNEL);
	if (!ea->attr.attr.name)
		return -ENOMEM;

	ea->attr.attr.mode = 0444;
	ea->attr.show = etm_perf_sink_name_show;
	ea->var = (unsigned long *)hash;

	ret = sysfs_add_file_to_group(&pmu_dev->kobj,
				      &ea->attr.attr, "sinks");

	if (!ret)
		csdev->ea = ea;

	return ret;
}

void etm_perf_del_symlink_sink(struct coresight_device *csdev)
{
	struct device *pmu_dev = etm_pmu.dev;
	struct dev_ext_attribute *ea = csdev->ea;

	if (csdev->type != CORESIGHT_DEV_TYPE_SINK &&
	    csdev->type != CORESIGHT_DEV_TYPE_LINKSINK)
		return;

	if (!ea)
		return;

	sysfs_remove_file_from_group(&pmu_dev->kobj,
				     &ea->attr.attr, "sinks");
	csdev->ea = NULL;
}

static int __init etm_perf_init(void)
{
	int ret;
+5 −1
Original line number Diff line number Diff line
@@ -59,6 +59,8 @@ struct etm_event_data {

#ifdef CONFIG_CORESIGHT
int etm_perf_symlink(struct coresight_device *csdev, bool link);
int etm_perf_add_symlink_sink(struct coresight_device *csdev);
void etm_perf_del_symlink_sink(struct coresight_device *csdev);
static inline void *etm_perf_sink_config(struct perf_output_handle *handle)
{
	struct etm_event_data *data = perf_get_aux(handle);
@@ -70,7 +72,9 @@ static inline void *etm_perf_sink_config(struct perf_output_handle *handle)
#else
static inline int etm_perf_symlink(struct coresight_device *csdev, bool link)
{ return -EINVAL; }

int etm_perf_add_symlink_sink(struct coresight_device *csdev)
{ return -EINVAL; }
void etm_perf_del_symlink_sink(struct coresight_device *csdev) {}
static inline void *etm_perf_sink_config(struct perf_output_handle *handle)
{
	return NULL;
Loading