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

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

perf: Optimize perf_output_copy()



Reduce the clutter in perf_output_copy() by keeping
an interator in perf_output_handle.

Signed-off-by: default avatarPeter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Steven Rostedt <rostedt@goodmis.org>
LKML-Reference: <20100521090710.742809176@chello.nl>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent adb8e118
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -806,6 +806,9 @@ struct perf_output_handle {
	unsigned long			head;
	unsigned long			offset;
	unsigned long			wakeup;
	unsigned long			size;
	void				*addr;
	int				page;
	int				nmi;
	int				sample;
};
+26 −28
Original line number Diff line number Diff line
@@ -2961,39 +2961,30 @@ static void perf_output_put_handle(struct perf_output_handle *handle)
void perf_output_copy(struct perf_output_handle *handle,
		      const void *buf, unsigned int len)
{
	unsigned int pages_mask;
	unsigned long offset;
	unsigned int size;
	void **pages;
	handle->offset += len;

	offset		= handle->offset;
	pages_mask	= handle->data->nr_pages - 1;
	pages		= handle->data->data_pages;
	/*
	 * Check we didn't copy past our reservation window, taking the
	 * possible unsigned int wrap into account.
	 */
	if (WARN_ON_ONCE(((long)(handle->head - handle->offset)) < 0))
		return;

	do {
		unsigned long page_offset;
		unsigned long page_size;
		int nr;
		unsigned long size = min(handle->size, len);

		nr	    = (offset >> PAGE_SHIFT) & pages_mask;
		page_size   = 1UL << (handle->data->data_order + PAGE_SHIFT);
		page_offset = offset & (page_size - 1);
		size	    = min_t(unsigned int, page_size - page_offset, len);

		memcpy(pages[nr] + page_offset, buf, size);
		memcpy(handle->addr, buf, size);

		len -= size;
		buf	    += size;
		offset	    += size;
		handle->addr += size;
		handle->size -= size;
		if (!handle->size) {
			handle->page++;
			handle->page &= handle->data->nr_pages - 1;
			handle->addr = handle->data->data_pages[handle->page];
			handle->size = PAGE_SIZE << handle->data->data_order;
		}
	} while (len);

	handle->offset = offset;

	/*
	 * Check we didn't copy past our reservation window, taking the
	 * possible unsigned int wrap into account.
	 */
	WARN_ON_ONCE(((long)(handle->head - handle->offset)) < 0);
}

int perf_output_begin(struct perf_output_handle *handle,
@@ -3059,6 +3050,13 @@ int perf_output_begin(struct perf_output_handle *handle,
	if (head - local_read(&data->wakeup) > data->watermark)
		local_add(data->watermark, &data->wakeup);

	handle->page = handle->offset >> (PAGE_SHIFT + data->data_order);
	handle->page &= data->nr_pages - 1;
	handle->size = handle->offset & ((PAGE_SIZE << data->data_order) - 1);
	handle->addr = data->data_pages[handle->page];
	handle->addr += handle->size;
	handle->size = (PAGE_SIZE << data->data_order) - handle->size;

	if (have_lost) {
		lost_event.header.type = PERF_RECORD_LOST;
		lost_event.header.misc = 0;