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

Commit 850bc73f authored by Peter Zijlstra's avatar Peter Zijlstra Committed by Ingo Molnar
Browse files

perf_counter: Do not throttle single swcounter events



We can have swcounter events that contribute more than a single
count per event, when used with a non-zero period, those can
generate multiple events, which is when we need throttling.

However, swcounter that contribute only a single count per event
can only come as fast as we can run code, hence don't throttle
them.

Signed-off-by: default avatarPeter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <new-submission>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 0ec04e16
Loading
Loading
Loading
Loading
+13 −4
Original line number Original line Diff line number Diff line
@@ -3494,14 +3494,15 @@ static void perf_log_throttle(struct perf_counter *counter, int enable)
 * Generic counter overflow handling, sampling.
 * Generic counter overflow handling, sampling.
 */
 */


int perf_counter_overflow(struct perf_counter *counter, int nmi,
static int __perf_counter_overflow(struct perf_counter *counter, int nmi,
			  struct perf_sample_data *data)
				   int throttle, struct perf_sample_data *data)
{
{
	int events = atomic_read(&counter->event_limit);
	int events = atomic_read(&counter->event_limit);
	int throttle = counter->pmu->unthrottle != NULL;
	struct hw_perf_counter *hwc = &counter->hw;
	struct hw_perf_counter *hwc = &counter->hw;
	int ret = 0;
	int ret = 0;


	throttle = (throttle && counter->pmu->unthrottle != NULL);

	if (!throttle) {
	if (!throttle) {
		hwc->interrupts++;
		hwc->interrupts++;
	} else {
	} else {
@@ -3554,6 +3555,12 @@ int perf_counter_overflow(struct perf_counter *counter, int nmi,
	return ret;
	return ret;
}
}


int perf_counter_overflow(struct perf_counter *counter, int nmi,
			  struct perf_sample_data *data)
{
	return __perf_counter_overflow(counter, nmi, 1, data);
}

/*
/*
 * Generic software counter infrastructure
 * Generic software counter infrastructure
 */
 */
@@ -3592,6 +3599,7 @@ static void perf_swcounter_overflow(struct perf_counter *counter,
				    int nmi, struct perf_sample_data *data)
				    int nmi, struct perf_sample_data *data)
{
{
	struct hw_perf_counter *hwc = &counter->hw;
	struct hw_perf_counter *hwc = &counter->hw;
	int throttle = 0;
	u64 overflow;
	u64 overflow;


	data->period = counter->hw.last_period;
	data->period = counter->hw.last_period;
@@ -3601,13 +3609,14 @@ static void perf_swcounter_overflow(struct perf_counter *counter,
		return;
		return;


	for (; overflow; overflow--) {
	for (; overflow; overflow--) {
		if (perf_counter_overflow(counter, nmi, data)) {
		if (__perf_counter_overflow(counter, nmi, throttle, data)) {
			/*
			/*
			 * We inhibit the overflow from happening when
			 * We inhibit the overflow from happening when
			 * hwc->interrupts == MAX_INTERRUPTS.
			 * hwc->interrupts == MAX_INTERRUPTS.
			 */
			 */
			break;
			break;
		}
		}
		throttle = 0;
	}
	}
}
}