Commit d68e6799 authored by Alexander Shishkin's avatar Alexander Shishkin Committed by Peter Zijlstra
Browse files

perf: Cap allocation order at aux_watermark



Currently, we start allocating AUX pages half the size of the total
requested AUX buffer size, ignoring the attr.aux_watermark setting. This,
in turn, makes intel_pt driver disregard the watermark also, as it uses
page order for its SG (ToPA) configuration.

Now, this can be fixed in the intel_pt PMU driver, but seeing as it's the
only one currently making use of high order allocations, there is no
reason not to fix the allocator instead. This way, any other driver
wishing to add this support would not have to worry about this.

Signed-off-by: default avatarAlexander Shishkin <alexander.shishkin@linux.intel.com>
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/20210414154955.49603-2-alexander.shishkin@linux.intel.com
parent cface032
Loading
Loading
Loading
Loading
+18 −16
Original line number Original line Diff line number Diff line
@@ -674,21 +674,26 @@ int rb_alloc_aux(struct perf_buffer *rb, struct perf_event *event,
	if (!has_aux(event))
	if (!has_aux(event))
		return -EOPNOTSUPP;
		return -EOPNOTSUPP;


	if (!overwrite) {
		/*
		/*
	 * We need to start with the max_order that fits in nr_pages,
		 * Watermark defaults to half the buffer, and so does the
	 * not the other way around, hence ilog2() and not get_order.
		 * max_order, to aid PMU drivers in double buffering.
		 */
		 */
	max_order = ilog2(nr_pages);
		if (!watermark)
			watermark = nr_pages << (PAGE_SHIFT - 1);


		/*
		/*
	 * PMU requests more than one contiguous chunks of memory
		 * Use aux_watermark as the basis for chunking to
	 * for SW double buffering
		 * help PMU drivers honor the watermark.
		 */
		 */
	if (!overwrite) {
		max_order = get_order(watermark);
		if (!max_order)
	} else {
			return -EINVAL;
		/*

		 * We need to start with the max_order that fits in nr_pages,
		max_order--;
		 * not the other way around, hence ilog2() and not get_order.
		 */
		max_order = ilog2(nr_pages);
		watermark = 0;
	}
	}


	rb->aux_pages = kcalloc_node(nr_pages, sizeof(void *), GFP_KERNEL,
	rb->aux_pages = kcalloc_node(nr_pages, sizeof(void *), GFP_KERNEL,
@@ -743,9 +748,6 @@ int rb_alloc_aux(struct perf_buffer *rb, struct perf_event *event,
	rb->aux_overwrite = overwrite;
	rb->aux_overwrite = overwrite;
	rb->aux_watermark = watermark;
	rb->aux_watermark = watermark;


	if (!rb->aux_watermark && !rb->aux_overwrite)
		rb->aux_watermark = nr_pages << (PAGE_SHIFT - 1);

out:
out:
	if (!ret)
	if (!ret)
		rb->aux_pgoff = pgoff;
		rb->aux_pgoff = pgoff;