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

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

Merge branch 'perf-fixes-for-linus' of...

Merge branch 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  perf tools: Remove -Wcast-align
  perf tools: Fix compatibility with libelf 0.8 and autodetect
  perf events: Don't generate events for the idle task when exclude_idle is set
  perf events: Fix swevent hrtimer sampling by keeping track of remaining time when enabling/disabling swevent hrtimers
parents a5e3013d ec29b8d2
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -471,8 +471,8 @@ struct hw_perf_event {
			unsigned long	event_base;
			int		idx;
		};
		union { /* software */
			atomic64_t	count;
		struct { /* software */
			s64		remaining;
			struct hrtimer	hrtimer;
		};
	};
+44 −22
Original line number Diff line number Diff line
@@ -3959,6 +3959,7 @@ static enum hrtimer_restart perf_swevent_hrtimer(struct hrtimer *hrtimer)
		regs = task_pt_regs(current);

	if (regs) {
		if (!(event->attr.exclude_idle && current->pid == 0))
			if (perf_event_overflow(event, 0, &data, regs))
				ret = HRTIMER_NORESTART;
	}
@@ -3969,6 +3970,42 @@ static enum hrtimer_restart perf_swevent_hrtimer(struct hrtimer *hrtimer)
	return ret;
}

static void perf_swevent_start_hrtimer(struct perf_event *event)
{
	struct hw_perf_event *hwc = &event->hw;

	hrtimer_init(&hwc->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	hwc->hrtimer.function = perf_swevent_hrtimer;
	if (hwc->sample_period) {
		u64 period;

		if (hwc->remaining) {
			if (hwc->remaining < 0)
				period = 10000;
			else
				period = hwc->remaining;
			hwc->remaining = 0;
		} else {
			period = max_t(u64, 10000, hwc->sample_period);
		}
		__hrtimer_start_range_ns(&hwc->hrtimer,
				ns_to_ktime(period), 0,
				HRTIMER_MODE_REL, 0);
	}
}

static void perf_swevent_cancel_hrtimer(struct perf_event *event)
{
	struct hw_perf_event *hwc = &event->hw;

	if (hwc->sample_period) {
		ktime_t remaining = hrtimer_get_remaining(&hwc->hrtimer);
		hwc->remaining = ktime_to_ns(remaining);

		hrtimer_cancel(&hwc->hrtimer);
	}
}

/*
 * Software event: cpu wall time clock
 */
@@ -3991,22 +4028,14 @@ static int cpu_clock_perf_event_enable(struct perf_event *event)
	int cpu = raw_smp_processor_id();

	atomic64_set(&hwc->prev_count, cpu_clock(cpu));
	hrtimer_init(&hwc->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	hwc->hrtimer.function = perf_swevent_hrtimer;
	if (hwc->sample_period) {
		u64 period = max_t(u64, 10000, hwc->sample_period);
		__hrtimer_start_range_ns(&hwc->hrtimer,
				ns_to_ktime(period), 0,
				HRTIMER_MODE_REL, 0);
	}
	perf_swevent_start_hrtimer(event);

	return 0;
}

static void cpu_clock_perf_event_disable(struct perf_event *event)
{
	if (event->hw.sample_period)
		hrtimer_cancel(&event->hw.hrtimer);
	perf_swevent_cancel_hrtimer(event);
	cpu_clock_perf_event_update(event);
}

@@ -4043,22 +4072,15 @@ static int task_clock_perf_event_enable(struct perf_event *event)
	now = event->ctx->time;

	atomic64_set(&hwc->prev_count, now);
	hrtimer_init(&hwc->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	hwc->hrtimer.function = perf_swevent_hrtimer;
	if (hwc->sample_period) {
		u64 period = max_t(u64, 10000, hwc->sample_period);
		__hrtimer_start_range_ns(&hwc->hrtimer,
				ns_to_ktime(period), 0,
				HRTIMER_MODE_REL, 0);
	}

	perf_swevent_start_hrtimer(event);

	return 0;
}

static void task_clock_perf_event_disable(struct perf_event *event)
{
	if (event->hw.sample_period)
		hrtimer_cancel(&event->hw.hrtimer);
	perf_swevent_cancel_hrtimer(event);
	task_clock_perf_event_update(event, event->ctx->time);

}
+6 −3
Original line number Diff line number Diff line
@@ -177,8 +177,7 @@ endif
# Include saner warnings here, which can catch bugs:
#

EXTRA_WARNINGS := -Wcast-align
EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wformat
EXTRA_WARNINGS := -Wformat
EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wformat-security
EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wformat-y2k
EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wshadow
@@ -422,7 +421,11 @@ ifeq ($(uname_S),Darwin)
	PTHREAD_LIBS =
endif

ifeq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o /dev/null $(ALL_LDFLAGS) > /dev/null 2>&1 && echo y"), y)
	ifneq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ_MMAP, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o /dev/null $(ALL_LDFLAGS) > /dev/null 2>&1 && echo y"), y)
		BASIC_CFLAGS += -DLIBELF_NO_MMAP
	endif
else
	msg := $(error No libelf.h/libelf found, please install libelf-dev/elfutils-libelf-devel and glibc-dev[el]);
endif

+3 −3
Original line number Diff line number Diff line
@@ -413,7 +413,7 @@ static int dso__synthesize_plt_symbols(struct dso *self, int v)
	if (fd < 0)
		goto out;

	elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
	elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
	if (elf == NULL)
		goto out_close;

@@ -533,7 +533,7 @@ static int dso__load_sym(struct dso *self, int fd, const char *name,
	Elf *elf;
	int nr = 0, kernel = !strcmp("[kernel]", self->name);

	elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
	elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
	if (elf == NULL) {
		if (v)
			fprintf(stderr, "%s: cannot read %s ELF file.\n",
@@ -675,7 +675,7 @@ static char *dso__read_build_id(struct dso *self, int v)
	if (fd < 0)
		goto out;

	elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
	elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
	if (elf == NULL) {
		if (v)
			fprintf(stderr, "%s: cannot read %s ELF file.\n",
+10 −0
Original line number Diff line number Diff line
@@ -27,6 +27,16 @@ static inline char *bfd_demangle(void __used *v, const char __used *c,
#endif
#endif

/*
 * libelf 0.8.x and earlier do not support ELF_C_READ_MMAP;
 * for newer versions we can use mmap to reduce memory usage:
 */
#ifdef LIBELF_NO_MMAP
# define PERF_ELF_C_READ_MMAP ELF_C_READ
#else
# define PERF_ELF_C_READ_MMAP ELF_C_READ_MMAP
#endif

#ifndef DMGL_PARAMS
#define DMGL_PARAMS      (1 << 0)       /* Include function args */
#define DMGL_ANSI        (1 << 1)       /* Include const, volatile, etc */