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

perf/x86/intel: Optimize intel_get_excl_constraints()



Avoid the POPCNT  by noting we can decrement the weight for each
cleared bit.

Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: default avatarStephane Eranian <eranian@google.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vince Weaver <vincent.weaver@maine.edu>
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent 1f6a1e2d
Loading
Loading
Loading
Loading
+13 −9
Original line number Diff line number Diff line
@@ -2838,7 +2838,7 @@ intel_get_excl_constraints(struct cpu_hw_events *cpuc, struct perf_event *event,
	struct intel_excl_cntrs *excl_cntrs = cpuc->excl_cntrs;
	struct intel_excl_states *xlo;
	int tid = cpuc->excl_thread_id;
	int is_excl, i;
	int is_excl, i, w;

	/*
	 * validating a group does not require
@@ -2894,36 +2894,40 @@ intel_get_excl_constraints(struct cpu_hw_events *cpuc, struct perf_event *event,
	 * SHARED   : sibling counter measuring non-exclusive event
	 * UNUSED   : sibling counter unused
	 */
	w = c->weight;
	for_each_set_bit(i, c->idxmsk, X86_PMC_IDX_MAX) {
		/*
		 * exclusive event in sibling counter
		 * our corresponding counter cannot be used
		 * regardless of our event
		 */
		if (xlo->state[i] == INTEL_EXCL_EXCLUSIVE)
		if (xlo->state[i] == INTEL_EXCL_EXCLUSIVE) {
			__clear_bit(i, c->idxmsk);
			w--;
			continue;
		}
		/*
		 * if measuring an exclusive event, sibling
		 * measuring non-exclusive, then counter cannot
		 * be used
		 */
		if (is_excl && xlo->state[i] == INTEL_EXCL_SHARED)
		if (is_excl && xlo->state[i] == INTEL_EXCL_SHARED) {
			__clear_bit(i, c->idxmsk);
			w--;
			continue;
		}
	}

	/*
	 * recompute actual bit weight for scheduling algorithm
	 */
	c->weight = hweight64(c->idxmsk64);

	/*
	 * if we return an empty mask, then switch
	 * back to static empty constraint to avoid
	 * the cost of freeing later on
	 */
	if (c->weight == 0)
	if (!w)
		c = &emptyconstraint;

	c->weight = w;

	return c;
}