All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sagar Arun Kamble <sagar.a.kamble@intel.com>
To: intel-gfx@lists.freedesktop.org
Cc: Sourab Gupta <sourab.gupta@intel.com>
Subject: [PATCH i-g-t 1/1] igt/dapc: Test Driver Assisted Performance Capture (DAPC)
Date: Mon, 28 Aug 2017 15:23:03 +0530	[thread overview]
Message-ID: <1503913983-3502-1-git-send-email-sagar.a.kamble@intel.com> (raw)

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=yes, Size: 26651 bytes --]

This test verifies different i915 perf sampling options for fields like
PID, CTX ID, Timestamp, OA Report, TAG, MMIO.

Cc: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Signed-off-by: Sourab Gupta <sourab.gupta@intel.com>
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
---
 tests/Makefile.sources |    1 +
 tests/dapc.c           | 1017 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 1018 insertions(+)
 create mode 100644 tests/dapc.c

diff --git a/tests/Makefile.sources b/tests/Makefile.sources
index bb013c7..61feb0d 100644
--- a/tests/Makefile.sources
+++ b/tests/Makefile.sources
@@ -26,6 +26,7 @@ TESTS_progs = \
 	core_getversion \
 	core_prop_blob \
 	core_setmaster_vs_auth \
+	dapc \
 	debugfs_test \
 	drm_import_export \
 	drm_mm \
diff --git a/tests/dapc.c b/tests/dapc.c
new file mode 100644
index 0000000..f49b1cd
--- /dev/null
+++ b/tests/dapc.c
@@ -0,0 +1,1017 @@
+/*
+ * Copyright © 2017 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * dapc: Driver Assisted Performance Capture
+ *	 This tests the i915 perf functionality to sample various metrics by
+ *	 associating with the CS stream or just standalone periodic OA samples.
+ *	 Verifies fields like PID, CTX ID, Timestamp, OA Report, MMIO, Tags are
+ *	 generated properly for each sample.
+ *
+ * Authors:
+ *   Sourab Gupta <sourab.gupta@intel.com>
+ *   Sagar Arun Kamble <sagar.a.kamble@intel.com>
+ *
+ */
+#define _GNU_SOURCE
+#include "xf86drm.h"
+#include "i915_drm.h"
+#include "igt_core.h"
+#include <linux/perf_event.h>
+#include <asm/unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include <dirent.h>
+#include <limits.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <assert.h>
+#include <time.h>
+
+#define COLLECT_DATA { \
+	printf("(%s) Collecting data. ", __func__); \
+	printf("Press enter to continue...\n"); \
+	getc(stdin); \
+}
+
+#define OA_SAMPLE_SIZE_MAX	(8 +	/* drm_i915_perf_record_header */ \
+				 8 +	/* source info */ \
+				 8 +	/* ctx ID */ \
+				 8 +	/* Pid */ \
+				 8 +	/* Tag */ \
+				 256) /* raw OA counter snapshot */
+
+#define TS_SAMPLE_SIZE_MAX	(8 +	/* drm_i915_perf_record_header */ \
+				 8 +	/* ctx ID */ \
+				 8 +	/* Pid */ \
+				 8 +	/* Tag */ \
+				 8)	/* Timestamp */ \
+
+#define TS_MMIO_SAMPLE_SIZE_MAX	(8 +   /* drm_i915_perf_record_header */ \
+				 8 +   /* ctx ID */ \
+				 8 +   /* Pid */ \
+				 8 +   /* Tag */ \
+				 8 +   /* Timestamp */ \
+				 4*I915_PERF_MMIO_NUM_MAX)	/* MMIO reg */
+
+#define OA_TS_MMIO_SAMPLE_SIZE_MAX (8 +   /* drm_i915_perf_record_header */ \
+				    8 +   /* source info */ \
+				    8 +   /* ctx ID */ \
+				    8 +   /* Pid */ \
+				    8 +   /* Tag */ \
+				    8 +   /* Timestamp */ \
+				    (4*I915_PERF_MMIO_NUM_MAX) + /* MMIO reg*/ \
+				    256) /* raw OA counter snapshot */
+
+#define READ_OA_BUF_SIZE_MAX		(100*OA_SAMPLE_SIZE_MAX)
+#define READ_TS_BUF_SIZE_MAX		(100*TS_SAMPLE_SIZE_MAX)
+#define READ_TS_MMIO_BUF_SIZE_MAX	(100*TS_MMIO_SAMPLE_SIZE_MAX)
+#define READ_OA_TS_MMIO_BUF_SIZE_MAX	(100*OA_TS_MMIO_SAMPLE_SIZE_MAX)
+
+#define SAMPLE_OA	(1<<0)
+#define SAMPLE_TS	(1<<1)
+#define SAMPLE_MMIO	(1<<2)
+
+struct intel_device {
+	uint32_t device;
+	uint32_t subsystem_device;
+	uint32_t subsystem_vendor;
+};
+
+enum platform {
+	ARCH_HSW,
+	ARCH_BDW,
+	ARCH_SKL,
+} arch;
+
+/* DAPC OA samples read() from i915 perf */
+struct dapc_oa_sample {
+	struct drm_i915_perf_record_header header;
+	uint64_t source_info;
+	uint64_t ctx_id;
+	uint64_t pid;
+	uint64_t tag;
+	uint8_t oa_report[];
+};
+
+/* DAPC timestamp samples read() from i915 perf */
+struct dapc_ts_sample {
+	struct drm_i915_perf_record_header header;
+	uint64_t ctx_id;
+	uint64_t pid;
+	uint64_t tag;
+	uint64_t timestamp;
+};
+
+/* DAPC timestamp + mmio samples read() from i915 perf */
+struct dapc_ts_mmio_sample {
+	struct drm_i915_perf_record_header header;
+	uint64_t ctx_id;
+	uint64_t pid;
+	uint64_t tag;
+	uint64_t timestamp;
+	uint32_t mmio[2];
+};
+
+/* DAPC OA + timestamp + mmio samples read() from i915 perf */
+struct dapc_oa_ts_mmio_sample {
+	struct drm_i915_perf_record_header header;
+	uint64_t source_info;
+	uint64_t ctx_id;
+	uint64_t pid;
+	uint64_t tag;
+	uint64_t timestamp;
+
+	/*
+	 * Hardcoding 2 here since the array size would depend on no. of mmio
+	 * values queried. TODO: Find a better way to do this.
+	 */
+	uint32_t mmio[2];
+	uint8_t oa_report[];
+};
+
+struct i915_oa_format {
+	int format;
+	int size;
+};
+
+static struct i915_oa_format hsw_oa_formats[I915_OA_FORMAT_MAX] = {
+	[I915_OA_FORMAT_A13]	    = { 0, 64 },
+	[I915_OA_FORMAT_A29]	    = { 1, 128 },
+	[I915_OA_FORMAT_A13_B8_C8]  = { 2, 128 },
+	/* A29_B8_C8 Disallowed as 192 bytes doesn't factor into buffer size */
+	[I915_OA_FORMAT_B4_C8]	    = { 4, 64 },
+	[I915_OA_FORMAT_A45_B8_C8]  = { 5, 256 },
+	[I915_OA_FORMAT_B4_C8_A16]  = { 6, 128 },
+	[I915_OA_FORMAT_C4_B8]	    = { 7, 64 },
+};
+
+static struct i915_oa_format gen8_plus_oa_formats[I915_OA_FORMAT_MAX] = {
+	[I915_OA_FORMAT_A12]		    = { 0, 64 },
+	[I915_OA_FORMAT_A12_B8_C8]	    = { 2, 128 },
+	[I915_OA_FORMAT_A32u40_A4u32_B8_C8] = { 5, 256 },
+	[I915_OA_FORMAT_C4_B8]		    = { 7, 64 },
+};
+
+static const char * const hsw_guids[] = {
+	"403d8832-1a27-4aa6-a64e-f5389ce7b212",
+	"39ad14bc-2380-45c4-91eb-fbcb3aa7ae7b",
+	"3865be28-6982-49fe-9494-e4d1b4795413",
+	"bb5ed49b-2497-4095-94f6-26ba294db88a",
+	"3358d639-9b5f-45ab-976d-9b08cbfc6240",
+	"bc274488-b4b6-40c7-90da-b77d7ad16189",
+};
+
+/*
+ * Need to update GUID based on latest i915 configuration. Currently
+ * first GUID is being tested.
+ */
+static const char * const skl_guids[] = {
+	"1651949f-0ac0-4cb1-a06f-dafd74a407d1",
+	"f519e481-24d2-4d42-87c9-3fdd12c00202",
+	"fdfc01cc-e28e-423a-aae0-b5ed5d4d7a9f",
+	"c9c7ace5-614a-4f8e-90c7-30064c36cad2",
+	"99797dc2-b48f-4d83-b973-613cff01202b",
+	"afa148ea-77fb-48ee-b8f8-e5e971ecf589",
+	"bfce7061-e6f1-4a78-bed8-c9cc69af70f9",
+	"c35ddcab-b1f2-452f-969a-a8209d531a00",
+	"2b0d0c83-706a-4cb6-b55e-d6bcf51fa6d3",
+	"d084f6a9-f706-4b74-b98c-65daa5340517",
+	"c7ed493c-54ff-4152-baf4-07e31e7a24cb",
+	"43ad9300-198a-4734-8f3a-2a2151b9dab6",
+	"ccfce3f2-6c63-4630-a043-f2a0243fed8f",
+	"2e564b28-98fa-42a0-8bbc-7915de3cc03c",
+	"a305533f-7e36-4fb6-8749-c6280bce3457",
+	"34ecd59f-6b52-4004-916f-afe9530a0442",
+	"ee1990d9-6e93-4c7c-aa9e-b40e1ec4d41b",
+};
+
+static struct intel_device intel_dev;
+static int drm_fd = -1;
+static int drm_card = -1;
+static int perf_event_fd_rcs = -1;
+
+static uint64_t read_file_uint64(const char *file)
+{
+	char buf[32];
+	int fd, n;
+
+	fd = open(file, 0);
+	if (fd < 0)
+		return 0;
+	n = read(fd, buf, sizeof(buf) - 1);
+	close(fd);
+	if (n < 0)
+		return 0;
+
+	buf[n] = '\0';
+	return strtoull(buf, 0, 0);
+}
+
+static uint32_t read_device_param(int id, const char *param)
+{
+	char *name;
+	int ret = asprintf(&name, "/sys/class/drm/renderD%u/device/%s",
+			   id, param);
+	uint32_t value;
+
+	assert(ret != -1);
+
+	value = read_file_uint64(name);
+	free(name);
+
+	return value;
+}
+
+static int get_card_for_fd(int fd)
+{
+	struct stat sb;
+	int mjr, mnr;
+	char buffer[128];
+	DIR *drm_dir;
+	int entry_size;
+	struct dirent *entry1, *entry2;
+	int name_max;
+
+	if (fstat(fd, &sb)) {
+		printf("Failed to stat DRM fd\n");
+		return -1;
+	}
+
+	mjr = major(sb.st_rdev);
+	mnr = minor(sb.st_rdev);
+
+	snprintf(buffer, sizeof(buffer), "/sys/dev/char/%d:%d/device/drm",
+		 mjr, mnr);
+
+	drm_dir = opendir(buffer);
+	assert(drm_dir != NULL);
+
+	name_max = pathconf(buffer, _PC_NAME_MAX);
+
+	if (name_max == -1)
+		name_max = 255;
+
+	entry_size = 256;
+	entry1 = alloca(entry_size);
+
+	while ((readdir_r(drm_dir, entry1, &entry2) == 0) && entry2 != NULL)
+		if (entry2->d_type == DT_DIR &&
+		    strncmp(entry2->d_name, "card", 4) == 0)
+			return strtoull(entry2->d_name + 4, NULL, 10);
+
+	return -1;
+}
+
+
+static int open_render_node(struct intel_device *dev)
+{
+	char *name;
+	int i, fd;
+
+	for (i = 128; i < (128 + 16); i++) {
+		int ret;
+
+		ret = asprintf(&name, "/dev/dri/renderD%u", i);
+		assert(ret != -1);
+
+		fd = open(name, O_RDWR);
+		free(name);
+
+		if (fd == -1)
+			continue;
+
+		if (read_device_param(i, "vendor") != 0x8086) {
+			close(fd);
+			fd = -1;
+			continue;
+		}
+
+		dev->device = read_device_param(i, "device");
+		dev->subsystem_device = read_device_param(i,
+							  "subsystem_device");
+		dev->subsystem_vendor = read_device_param(i,
+							  "subsystem_vendor");
+
+		return fd;
+	}
+
+	return fd;
+}
+
+/* Handle restarting ioctl if interrupted... */
+static int perf_ioctl(int fd, unsigned long request, void *arg)
+{
+	int ret;
+
+	do {
+		ret = ioctl(fd, request, arg);
+	} while (ret == -1 && (errno == EINTR || errno == EAGAIN));
+
+	return ret;
+}
+
+int read_perf_dapc_samples(uint8_t *temp_buf, uint8_t *out_data,
+			   uint8_t sample_flags, int fd)
+{
+	int count, max_read_size = 16*1024*1024, size_copied = 0, offset = 0;
+
+	if (sample_flags & SAMPLE_OA)
+		max_read_size = READ_OA_BUF_SIZE_MAX;
+	else if (sample_flags & SAMPLE_TS)
+		max_read_size = READ_TS_BUF_SIZE_MAX;
+	else if (sample_flags & (SAMPLE_TS|SAMPLE_MMIO))
+		max_read_size = READ_TS_MMIO_BUF_SIZE_MAX;
+	else if (sample_flags & (SAMPLE_OA|SAMPLE_TS|SAMPLE_MMIO)) {
+		max_read_size = READ_OA_TS_MMIO_BUF_SIZE_MAX;
+	} else {
+		printf("Unknown sample flags: %d\n", sample_flags);
+		return -1;
+	}
+
+	count = read(fd, temp_buf, max_read_size);
+
+	if (count < 0) {
+		printf("Error reading i915 OA event stream. Errno:%d", errno);
+		perror("Error : ");
+		return count;
+	}
+
+	if (count == 0)
+		return 0;
+
+	while (offset < count) {
+		struct drm_i915_perf_record_header *header =
+		(struct drm_i915_perf_record_header *)(temp_buf + offset);
+
+		if (header->size == 0) {
+			printf("Spurious header size == 0\n");
+			/* XXX: How should we handle this instead of exiting()*/
+			exit(1);
+		}
+
+		offset += header->size;
+
+		switch (header->type) {
+		case DRM_I915_PERF_RECORD_OA_BUFFER_LOST:
+			printf("i915_oa: OA buffer overflow\n");
+			break;
+		case DRM_I915_PERF_RECORD_OA_REPORT_LOST:
+			printf("i915_oa: OA report lost\n");
+			break;
+		case DRM_I915_PERF_RECORD_SAMPLE:
+			if (sample_flags & SAMPLE_OA) {
+				struct dapc_oa_sample *sample =
+					(struct dapc_oa_sample *)header;
+
+				if (sample->source_info ==
+				    I915_PERF_SAMPLE_OA_SOURCE_RCS) {
+					/* DAPC sample */
+					printf("DAPC OA sample\n");
+				} else {
+					/* Periodic sample. No need to copy */
+					printf("Periodic sample\n");
+					continue;
+				}
+			}
+			memcpy(out_data + size_copied, header, header->size);
+			size_copied += header->size;
+			break;
+		default:
+			printf("i915_oa: Spurious header type = %d\n",
+			       header->type);
+		}
+	}
+
+	return size_copied;
+}
+
+bool read_metrics_id_from_sysfs(int *metrics_id)
+{
+	char buffer[128];
+	const char *guid;
+
+	assert(drm_card >= 0);
+
+	/*
+	 * Select render basic metrics ID - i.e. first guid, from the arch
+	 * specific guids.
+	 */
+	switch (arch) {
+	case ARCH_HSW:
+		guid = hsw_guids[0];
+		break;
+	case ARCH_SKL:
+		guid = skl_guids[0];
+		break;
+	default:
+		printf("guid not found for the arch\n");
+		return false;
+	}
+
+	snprintf(buffer, sizeof(buffer),
+		 "/sys/class/drm/card%d/metrics/%s/id",
+		 drm_card, guid);
+	*metrics_id = read_file_uint64(buffer);
+
+	return true;
+}
+
+static void open_i915_rcs_oa_stream(int report_format, int metrics_id)
+{
+	int period_exponent = 16;//0;
+	int ring_id = I915_EXEC_RENDER; /* RCS */
+	struct drm_i915_perf_open_param param;
+	uint64_t properties[] = {
+		DRM_I915_PERF_PROP_SAMPLE_OA, true,
+		DRM_I915_PERF_PROP_OA_METRICS_SET, metrics_id,
+		DRM_I915_PERF_PROP_OA_FORMAT, report_format,
+		DRM_I915_PERF_PROP_OA_EXPONENT, period_exponent,
+		DRM_I915_PERF_PROP_ENGINE, ring_id,
+		DRM_I915_PERF_PROP_SAMPLE_OA_SOURCE, true,
+		DRM_I915_PERF_PROP_SAMPLE_CTX_ID, true,
+		DRM_I915_PERF_PROP_SAMPLE_PID, true,
+		DRM_I915_PERF_PROP_SAMPLE_TAG, true,
+	};
+	int fd;
+
+	memset(&param, 0, sizeof(param));
+
+	param.flags = 0;
+	param.flags |= I915_PERF_FLAG_FD_CLOEXEC;
+	param.flags |= I915_PERF_FLAG_FD_NONBLOCK;
+
+	param.properties_ptr = (uint64_t)properties;
+	param.num_properties = sizeof(properties) / 16;
+
+	fd = perf_ioctl(drm_fd, DRM_IOCTL_I915_PERF_OPEN, &param);
+
+	if (fd == -1) {
+		perror("Error opening i915 perf event : ");
+		return;
+	}
+
+	printf("Opened i915 perf event.\n");
+	perf_event_fd_rcs = fd;
+}
+
+static void open_i915_rcs_ts_stream(void)
+{
+	struct drm_i915_perf_open_param param;
+	int ring_id = I915_EXEC_RENDER; /* RCS */
+	uint64_t properties[] = {
+		DRM_I915_PERF_PROP_ENGINE, ring_id,
+		DRM_I915_PERF_PROP_SAMPLE_TS, true,
+		DRM_I915_PERF_PROP_SAMPLE_CTX_ID, true,
+		DRM_I915_PERF_PROP_SAMPLE_PID, true,
+		DRM_I915_PERF_PROP_SAMPLE_TAG, true,
+	};
+	int fd;
+
+	memset(&param, 0, sizeof(param));
+
+	param.flags = 0;
+	param.flags |= I915_PERF_FLAG_FD_CLOEXEC;
+	param.flags |= I915_PERF_FLAG_FD_NONBLOCK;
+
+	param.properties_ptr = (uint64_t)properties;
+	param.num_properties = sizeof(properties) / 16;
+
+	fd = perf_ioctl(drm_fd, DRM_IOCTL_I915_PERF_OPEN, &param);
+
+	if (fd == -1) {
+		perror("Error opening i915 perf event : ");
+		return;
+	}
+
+	printf("Opened i915 perf event.\n");
+	perf_event_fd_rcs = fd;
+}
+
+static void open_i915_rcs_ts_mmio_stream(
+			struct drm_i915_perf_mmio_list *mmio_list)
+{
+	struct drm_i915_perf_open_param param;
+	int ring_id = I915_EXEC_RENDER; /* RCS */
+	uint64_t properties[] = {
+		DRM_I915_PERF_PROP_ENGINE, ring_id,
+		DRM_I915_PERF_PROP_SAMPLE_TS, true,
+		DRM_I915_PERF_PROP_SAMPLE_MMIO, (uint64_t)mmio_list,
+		DRM_I915_PERF_PROP_SAMPLE_CTX_ID, true,
+		DRM_I915_PERF_PROP_SAMPLE_PID, true,
+		DRM_I915_PERF_PROP_SAMPLE_TAG, true,
+	};
+	int fd;
+
+	memset(&param, 0, sizeof(param));
+
+	param.flags = 0;
+	param.flags |= I915_PERF_FLAG_FD_CLOEXEC;
+	param.flags |= I915_PERF_FLAG_FD_NONBLOCK;
+
+	param.properties_ptr = (uint64_t)properties;
+	param.num_properties = sizeof(properties) / 16;
+
+	fd = perf_ioctl(drm_fd, DRM_IOCTL_I915_PERF_OPEN, &param);
+
+	if (fd == -1) {
+		perror("Error opening i915 perf event : ");
+		return;
+	}
+
+	printf("Opened i915 perf event.\n");
+	perf_event_fd_rcs = fd;
+}
+
+static void open_i915_rcs_oa_ts_mmio_stream(int report_format, int metrics_id,
+			struct drm_i915_perf_mmio_list *mmio_list)
+{
+	int period_exponent = 16;//0;
+	int ring_id = I915_EXEC_RENDER; /* RCS */
+	struct drm_i915_perf_open_param param;
+	uint64_t properties[] = {
+		DRM_I915_PERF_PROP_SAMPLE_OA, true,
+		DRM_I915_PERF_PROP_OA_METRICS_SET, metrics_id,
+		DRM_I915_PERF_PROP_OA_FORMAT, report_format,
+		DRM_I915_PERF_PROP_OA_EXPONENT, period_exponent,
+		DRM_I915_PERF_PROP_ENGINE, ring_id,
+		DRM_I915_PERF_PROP_SAMPLE_OA_SOURCE, true,
+		DRM_I915_PERF_PROP_SAMPLE_TS, true,
+		DRM_I915_PERF_PROP_SAMPLE_MMIO, (uint64_t)mmio_list,
+		DRM_I915_PERF_PROP_SAMPLE_CTX_ID, true,
+		DRM_I915_PERF_PROP_SAMPLE_PID, true,
+		DRM_I915_PERF_PROP_SAMPLE_TAG, true,
+	};
+	int fd;
+
+	memset(&param, 0, sizeof(param));
+
+	param.flags = 0;
+	param.flags |= I915_PERF_FLAG_FD_CLOEXEC;
+	param.flags |= I915_PERF_FLAG_FD_NONBLOCK;
+
+	param.properties_ptr = (uint64_t)properties;
+	param.num_properties = sizeof(properties) / 16;
+
+	fd = perf_ioctl(drm_fd, DRM_IOCTL_I915_PERF_OPEN, &param);
+
+	if (fd == -1) {
+		perror("Error opening i915 perf event : ");
+		return;
+	}
+
+	printf("Opened i915 perf event.\n");
+	perf_event_fd_rcs = fd;
+}
+
+static void open_i915_periodic_oa_stream(int report_format, int metrics_id)
+{
+	int period_exponent = 16;//0;
+	struct drm_i915_perf_open_param param;
+	uint64_t properties[] = {
+		DRM_I915_PERF_PROP_SAMPLE_OA, true,
+		DRM_I915_PERF_PROP_OA_METRICS_SET, metrics_id,
+		DRM_I915_PERF_PROP_OA_FORMAT, report_format,
+		DRM_I915_PERF_PROP_OA_EXPONENT, period_exponent,
+		DRM_I915_PERF_PROP_SAMPLE_OA_SOURCE, true,
+	};
+	int fd;
+
+	memset(&param, 0, sizeof(param));
+
+	param.flags = 0;
+	param.flags |= I915_PERF_FLAG_FD_CLOEXEC;
+	param.flags |= I915_PERF_FLAG_FD_NONBLOCK;
+
+	param.properties_ptr = (uint64_t)properties;
+	param.num_properties = sizeof(properties) / 16;
+
+	fd = perf_ioctl(drm_fd, DRM_IOCTL_I915_PERF_OPEN, &param);
+
+	if (fd == -1) {
+		perror("Error opening i915 perf event : ");
+		return;
+	}
+
+	printf("Opened i915 perf event.\n");
+	perf_event_fd_rcs = fd;
+}
+
+static void close_i915_perf_stream(void)
+{
+	if (perf_event_fd_rcs != -1) {
+		close(perf_event_fd_rcs);
+		perf_event_fd_rcs = -1;
+	}
+}
+
+static void test_perf_dapc_rcs_oa(void)
+{
+	uint64_t report_format;
+	int metrics_id;
+	int size, report_size, current_size = 0;
+	uint8_t *dapc_data, *temp_buffer, *current_hdr;
+	int ret = 0;
+
+	if (arch == ARCH_HSW) {
+		report_format = I915_OA_FORMAT_A29;
+		report_size = hsw_oa_formats[report_format].size;
+	} else {
+		report_format = I915_OA_FORMAT_A12;
+		report_size = gen8_plus_oa_formats[report_format].size;
+	}
+
+	if (report_size < 0)
+		return;
+
+	dapc_data = malloc(READ_OA_BUF_SIZE_MAX);
+	temp_buffer = malloc(READ_OA_BUF_SIZE_MAX);
+
+	ret = read_metrics_id_from_sysfs(&metrics_id);
+	if (!ret) {
+		printf("Reading metrics id from sysfs failed\n");
+		return;
+	}
+
+	open_i915_rcs_oa_stream(report_format, metrics_id);
+
+	/* Collect samples */
+	COLLECT_DATA;
+
+	/* Read samples */
+	size = read_perf_dapc_samples(temp_buffer, dapc_data, SAMPLE_OA,
+				      perf_event_fd_rcs);
+
+	current_hdr = dapc_data;
+
+	printf("size retrieved = %d\n", size);
+	/* Verify the sanity of DAPC node headers */
+	while (current_size < size) {
+		struct dapc_oa_sample *sample = (struct dapc_oa_sample *)
+					(current_hdr + current_size);
+
+		igt_assert(sample->pid != 0);
+		printf("pid = %lu, ctx_id = %lu, OA(first 8 bytes):0x%llx, "
+		       "oa ts=0x%x\n",
+			sample->pid, sample->ctx_id,
+			*(unsigned long long int *)sample->oa_report,
+			*(uint32_t *)(sample->oa_report + 4));
+
+		current_size += sample->header.size;
+	}
+	close_i915_perf_stream();
+
+	free(dapc_data);
+	free(temp_buffer);
+}
+
+static void test_perf_dapc_rcs_ts(void)
+{
+
+	uint64_t prev_ts = 0, init_ts = 0;
+	int size, current_size = 0;
+	uint8_t *dapc_data, *temp_buffer, *current_hdr;
+
+	dapc_data = malloc(READ_TS_BUF_SIZE_MAX);
+	temp_buffer = malloc(READ_TS_BUF_SIZE_MAX);
+
+	memset(dapc_data, 0, READ_TS_BUF_SIZE_MAX);
+	memset(temp_buffer, 0, READ_TS_BUF_SIZE_MAX);
+
+	open_i915_rcs_ts_stream();
+
+	/* Collect samples */
+	COLLECT_DATA;
+
+	/* Read samples */
+	size = read_perf_dapc_samples(temp_buffer, dapc_data, SAMPLE_TS,
+				      perf_event_fd_rcs);
+
+	current_hdr = dapc_data;
+
+	printf("size collected = %d\n", size);
+
+	/* Verify the sanity of DAPC data */
+	while (current_size < size) {
+		struct dapc_ts_sample *sample = (struct dapc_ts_sample *)
+						(current_hdr + current_size);
+		uint64_t ts = sample->timestamp;
+
+		igt_assert(sample->pid != 0);
+		printf("pid = %lu, ctx_id = %lu, tag=%lu, ts=0x%llx\n",
+			sample->pid, sample->ctx_id, sample->tag,
+			(unsigned long long)ts);
+
+		igt_assert(ts > init_ts);
+		igt_assert(ts > prev_ts);
+		prev_ts = ts;
+
+		current_size += sample->header.size;
+	}
+
+	printf("total size read = %d\n", current_size);
+	close_i915_perf_stream();
+
+	free(dapc_data);
+	free(temp_buffer);
+}
+
+
+static void test_perf_dapc_rcs_ts_mmio(void)
+{
+
+	uint64_t prev_ts = 0, init_ts = 0;
+	int r, size, current_size = 0;
+	uint8_t *dapc_data, *temp_buffer, *current_hdr;
+	struct drm_i915_perf_mmio_list mmio;
+
+	dapc_data = malloc(READ_TS_MMIO_BUF_SIZE_MAX);
+	temp_buffer = malloc(READ_TS_MMIO_BUF_SIZE_MAX);
+
+	memset(&mmio, 0, sizeof(mmio));
+
+#define GEN6_GT_GFX_RC6				0x138108
+#define GEN6_GT_GFX_RC6p			0x13810C
+	mmio.mmio_list[0] = GEN6_GT_GFX_RC6;
+	mmio.mmio_list[1] = GEN6_GT_GFX_RC6p;
+	mmio.num_mmio = 2;
+
+	open_i915_rcs_ts_mmio_stream(&mmio);
+
+	/* Collect samples */
+	COLLECT_DATA;
+
+	/* Read samples */
+	size = read_perf_dapc_samples(temp_buffer, dapc_data,
+				      SAMPLE_TS|SAMPLE_MMIO, perf_event_fd_rcs);
+
+	current_hdr = dapc_data;
+
+	printf("size collected = %d\n", size);
+	/* Verify the sanity of DAPC data */
+	while (current_size < size) {
+		struct dapc_ts_mmio_sample *sample =
+						(struct dapc_ts_mmio_sample *)
+						(current_hdr + current_size);
+		uint64_t ts = sample->timestamp;
+
+		igt_assert(sample->pid != 0);
+		printf("pid = %lu, ctx_id = %lu, ts=0x%llx\n",
+			sample->pid, sample->ctx_id,
+			(unsigned long long)ts);
+
+		igt_assert(ts > init_ts);
+		igt_assert(ts > prev_ts);
+		prev_ts = ts;
+
+		for (r = 0; r < mmio.num_mmio; r++) {
+			printf("mmio 0x%08X = 0x%08X\n",
+			mmio.mmio_list[r],
+			sample->mmio[r]);
+		}
+
+		current_size += sample->header.size;
+	}
+
+	printf("total size read = %d\n", current_size);
+	close_i915_perf_stream();
+
+	free(dapc_data);
+	free(temp_buffer);
+}
+
+static void test_perf_dapc_rcs_oa_ts_mmio(void)
+{
+
+	uint64_t report_format;
+	uint64_t prev_ts = 0, init_ts = 0;
+	int r, report_size, size, metrics_id, current_size = 0;
+	uint8_t *dapc_data, *temp_buffer, *current_hdr;
+	struct drm_i915_perf_mmio_list mmio;
+	int ret = 0;
+
+	if (arch == ARCH_HSW) {
+		report_format = I915_OA_FORMAT_A29;
+		report_size = hsw_oa_formats[report_format].size;
+	} else {
+		report_format = I915_OA_FORMAT_A12;
+		report_size = gen8_plus_oa_formats[report_format].size;
+	}
+
+	if (report_size < 0)
+		return;
+
+	dapc_data = malloc(READ_OA_TS_MMIO_BUF_SIZE_MAX);
+	temp_buffer = malloc(READ_OA_TS_MMIO_BUF_SIZE_MAX);
+
+	memset(&mmio, 0, sizeof(mmio));
+
+#define GEN6_GT_GFX_RC6				0x138108
+#define GEN6_GT_GFX_RC6p			0x13810C
+	mmio.mmio_list[0] = GEN6_GT_GFX_RC6;
+	mmio.mmio_list[1] = GEN6_GT_GFX_RC6p;
+	mmio.num_mmio = 2;
+
+	ret = read_metrics_id_from_sysfs(&metrics_id);
+	if (!ret) {
+		printf("Reading metrics id from sysfs failed\n");
+		return;
+	}
+
+	open_i915_rcs_oa_ts_mmio_stream(report_format, metrics_id, &mmio);
+
+	/* Collect samples */
+	COLLECT_DATA;
+
+	/* Read samples */
+	size = read_perf_dapc_samples(temp_buffer, dapc_data,
+				      SAMPLE_OA|SAMPLE_TS|SAMPLE_MMIO,
+				      perf_event_fd_rcs);
+
+	current_hdr = dapc_data;
+
+	printf("size collected = %d\n", size);
+	/* Verify the sanity of DAPC data */
+	while (current_size < size) {
+		struct dapc_oa_ts_mmio_sample *sample =
+				(struct dapc_oa_ts_mmio_sample *)
+						(current_hdr + current_size);
+		uint64_t ts = sample->timestamp;
+
+		igt_assert(sample->pid != 0);
+		printf("pid = %lu, ctx_id = %lu, ts=0x%llx\n",
+			sample->pid, sample->ctx_id,
+			(unsigned long long)ts);
+
+		igt_assert(ts > init_ts);
+		igt_assert(ts > prev_ts);
+		prev_ts = ts;
+
+		for (r = 0; r < mmio.num_mmio; r++) {
+			printf("mmio 0x%08X = 0x%08X\n",
+			mmio.mmio_list[r], sample->mmio[r]);
+		}
+
+		current_size += sample->header.size;
+		printf("current size = %d\n", current_size);
+	}
+
+	printf("total size read = %d\n", current_size);
+	close_i915_perf_stream();
+
+	free(dapc_data);
+	free(temp_buffer);
+}
+
+static void test_perf_dapc_periodic_oa(void)
+{
+	uint64_t report_format;
+	int size, report_size, metrics_id;
+	uint8_t *dapc_data, *temp_buffer;
+	int ret = 0;
+
+	if (arch == ARCH_HSW) {
+		report_format = I915_OA_FORMAT_A29;
+		report_size = hsw_oa_formats[report_format].size;
+	} else {
+		report_format = I915_OA_FORMAT_A12;
+		report_size = gen8_plus_oa_formats[report_format].size;
+	}
+
+	if (report_size < 0)
+		return;
+
+	dapc_data = malloc(READ_OA_BUF_SIZE_MAX);
+	temp_buffer = malloc(READ_OA_BUF_SIZE_MAX);
+
+	ret = read_metrics_id_from_sysfs(&metrics_id);
+	if (!ret) {
+		printf("Reading metrics id from sysfs failed\n");
+		return;
+	}
+
+	open_i915_periodic_oa_stream(report_format, metrics_id);
+
+	/* Collect samples */
+	COLLECT_DATA;
+
+	/* Read samples */
+	size = read_perf_dapc_samples(temp_buffer, dapc_data, SAMPLE_OA,
+				      perf_event_fd_rcs);
+
+	close_i915_perf_stream();
+
+	free(dapc_data);
+	free(temp_buffer);
+}
+
+static bool
+initialize(void)
+{
+
+	if (intel_dev.device)
+		return true;
+
+	drm_fd = open_render_node(&intel_dev);
+	if (drm_fd < 0) {
+		printf("Failed to open render node\n");
+		return false;
+	}
+
+	drm_card = get_card_for_fd(drm_fd);
+	if (drm_card < 0) {
+		printf("Failed to get drm card info\n");
+		return false;
+	}
+
+	return true;
+}
+
+int main(int argc, char **argv)
+{
+	bool ret;
+	int option;
+	int platform;
+
+	if (argc != 3) {
+		printf("Usage: \n./dapc <Platform> <Test_mode>\
+		\nPlatform: 0-HSW, 1-BDW, 2-SKL\n\
+		\nTest_mode:\n\
+		\t0 - RCS OA mode\n\
+		\t1 - RCS TS mode\n\
+		\t2 - RCS TS+MMIO mode\n\
+		\t3 - RCS OA+TS+MMIO mode\n\
+		\t4 - Periodic OA mode\n");
+		return 0;
+	}
+
+	ret = initialize();
+	if (!ret)
+		return -1;
+
+	platform = atoi(argv[1]);
+	switch (platform) {
+	case 0:
+		arch = ARCH_HSW;
+		break;
+	case 1:
+		arch = ARCH_BDW;
+		break;
+	case 2:
+		arch = ARCH_SKL;
+		break;
+	default:
+		fprintf(stderr, "Invalid platform:%d\n", platform);
+		return -1;
+	}
+
+	option = atoi(argv[2]);
+	switch (option) {
+	case 0:
+		test_perf_dapc_rcs_oa();
+		break;
+	case 1:
+		test_perf_dapc_rcs_ts();
+		break;
+	case 2:
+		test_perf_dapc_rcs_ts_mmio();
+		break;
+	case 3:
+		test_perf_dapc_rcs_oa_ts_mmio();
+		break;
+	case 4:
+		test_perf_dapc_periodic_oa();
+		break;
+	default:
+		fprintf(stderr, "Invalid Option:%d\n", option);
+		return -1;
+	}
+
+	return 0;
+}
-- 
1.9.1


[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

             reply	other threads:[~2017-08-28  9:49 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-08-28  9:53 Sagar Arun Kamble [this message]
2017-08-28 11:51 ` ✗ Fi.CI.BAT: failure for series starting with [1/1] igt/dapc: Test Driver Assisted Performance Capture (DAPC) Patchwork
2017-08-29  8:51 ` [PATCH i-g-t 1/1] " Lionel Landwerlin
2017-08-30 11:17   ` Kamble, Sagar A
2017-08-30  9:39 ` Daniel Vetter
2017-08-30  9:43   ` Lionel Landwerlin
2017-08-30 12:21     ` Daniel Vetter
2017-08-30 11:04   ` Kamble, Sagar A

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1503913983-3502-1-git-send-email-sagar.a.kamble@intel.com \
    --to=sagar.a.kamble@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=sourab.gupta@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.