[igt-dev] [PATCH i-g-t 2/2] tools: display pnp loads with socwatch

Anshuman Gupta anshuman.gupta at intel.com
Thu May 27 16:50:40 UTC 2021


Run socwatch with a display PnP load to get socwatch
metrics. It will run the socwatch in a different thread
in parallel with Display PnP Load.

Cc: Petri Latvala <petri.latvala at intel.com>
Signed-off-by: Anshuman Gupta <anshuman.gupta at intel.com>
---
 tools/intel_display_pnp.c | 124 ++++++++++++++++++++++++++++++++++++--
 1 file changed, 118 insertions(+), 6 deletions(-)

diff --git a/tools/intel_display_pnp.c b/tools/intel_display_pnp.c
index 25a67a68..783f8383 100644
--- a/tools/intel_display_pnp.c
+++ b/tools/intel_display_pnp.c
@@ -23,6 +23,9 @@
  *
  * This programs runs display Power and Performance loads native to console and
  * runs socwatch with the pnp load to get the PnP metrics.
+ * SoCWatch is a tool to perform energy analysis on a Linux* or Android* system
+ * running on Intel® architecture.
+ * https://software.intel.com/content/www/us/en/develop/documentation/get-started-with-socwatch-system-bring-up-toolkit/top.html
  *
  * Authors:
  *    Anshuman Gupta <anshuman.gupta at intel.com>
@@ -34,6 +37,7 @@
 #include <errno.h>
 #include <stdbool.h>
 #include <glib.h>
+#include <pthread.h>
 #include "igt.h"
 #include "igt_sysfs.h"
 #include "igt_psr.h"
@@ -54,6 +58,9 @@ typedef struct {
 	enum psr_mode op_psr_mode;
 	drmModeModeInfo *mode;
 	igt_output_t *outputs[IGT_MAX_PIPES];
+	char socwatch_cmd[512];
+	int socwatch_len;
+	pthread_t socwatch_thread;
 } data_t;
 
 enum comp {
@@ -78,6 +85,7 @@ typedef struct {
 
 int load_type = -1;
 int load_time;
+bool socwatch;
 
 
 const char *load[MAX_LOADS] = {
@@ -167,6 +175,43 @@ setup_selective_update_fbs(data_t *data)
 					   &data->plane_update_clip_wb, blue);
 }
 
+static void *run_socwatch_thread(void *pdata)
+{
+	FILE *fp;
+	char tmp[512];
+	data_t *data = pdata;
+
+	fp = popen(data->socwatch_cmd, "r");
+
+	if (fp == NULL) {
+		igt_info("Failed to run socwatch\n");
+		perror("popen");
+		pthread_exit(0);
+	}
+
+	while (fgets(tmp, sizeof(tmp), fp) != NULL)
+		igt_info("%s\n", tmp);
+
+	pclose(fp);
+	igt_info("completed socwatch\n");
+
+	pthread_exit(0);
+}
+
+static void sleep_and_run_socwatch(data_t *data)
+{
+	int rc;
+
+	if (!socwatch)
+		return;
+
+	rc = pthread_create(&data->socwatch_thread, NULL, run_socwatch_thread, data);
+	igt_assert_eq(rc, 0);
+	sleep(load_time);
+	igt_info("display pnp load completed\n");
+	igt_assert(pthread_join(data->socwatch_thread, NULL) == 0);
+}
+
 static int get_compatible_outputs(data_t *data, uint32_t flags)
 {
 	igt_display_t *display = &data->display;
@@ -280,7 +325,7 @@ static void idle_display_on(data_t *data, uint32_t flags)
 	}
 
 	igt_info("**************idle display on, please start the power measurement**************\n");
-	sleep(load_time);
+	sleep_and_run_socwatch(data);
 }
 
 /*
@@ -293,7 +338,7 @@ static void selective_updates_flips(data_t *data, uint32_t flags, int fps)
 {
 	igt_output_t *output;
 	igt_plane_t *primary;
-	int delay;
+	int delay, rc;
 	time_t secs;
 	time_t startTime = time(NULL);
 
@@ -314,6 +359,11 @@ static void selective_updates_flips(data_t *data, uint32_t flags, int fps)
 	igt_info("**********selective update load started with fps %d,"
 		 "please start the power measurement**********\n", fps);
 
+	if (socwatch) {
+		rc = pthread_create(&data->socwatch_thread, NULL, run_socwatch_thread, data);
+		igt_assert_eq(rc, 0);
+	}
+
 	while (time(NULL) - startTime < secs) {
 		igt_plane_set_fb(primary, &data->fb_wr);
 		igt_plane_replace_prop_blob(primary,
@@ -331,6 +381,11 @@ static void selective_updates_flips(data_t *data, uint32_t flags, int fps)
 		igt_display_commit2(&data->display, COMMIT_ATOMIC);
 		usleep(delay);
 	}
+
+	igt_info("display pnp load completed\n");
+
+	if (socwatch)
+		igt_assert(pthread_join(data->socwatch_thread, NULL) == 0);
 }
 
 static void idle_display_on_with_dpms(data_t *data, uint32_t flags)
@@ -351,7 +406,7 @@ static void idle_display_on_with_dpms(data_t *data, uint32_t flags)
 	}
 
 	igt_info("****idle display on with another dpms_off, please start the power measurement****\n");
-	sleep(load_time);
+	sleep_and_run_socwatch(data);
 }
 
 static void idle_display_off(data_t *data)
@@ -363,7 +418,7 @@ static void idle_display_off(data_t *data)
 	}
 
 	igt_info("**************idle display off, please start the power measurement**************\n");
-	sleep(load_time);
+	sleep_and_run_socwatch(data);
 }
 
 static void run_kms_cube(data_t *data, enum comp compression)
@@ -398,13 +453,38 @@ static void run_kms_cube(data_t *data, enum comp compression)
 	igt_info("kms_cube, please start the power measurement\n");
 }
 
+char sw_version[64];
+char sw_path[256];
+
+static void setup_socwatch_cmd(data_t *data, const char *load_name)
+{
+	time_t t;
+	struct tm *tm;
+	char *tmp;
+	int len = sizeof(data->socwatch_cmd) - data->socwatch_len;
+
+	if (!socwatch)
+		return;
+
+	tmp = data->socwatch_cmd;
+	tmp += data->socwatch_len;
+	time(&t);
+	igt_require(tm = localtime(&t));
+	snprintf(tmp, len, "%s_%04d-%02d-%02d_%02d:%02d:%02d", load_name, 1900 + tm->tm_year,
+		 tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_hour, tm->tm_sec);
+	igt_info("scwatch_cmd  %s\n", data->socwatch_cmd);
+}
+
 const char *help_str =
 	"  -h\t\tShow help\n"
 	"  -l\t\tList supported PnP loads\n"
 	"  -r\t\tProvide the load to be run\n"
-	"  -t\t\tProvide time to run display PnP load in seconds.";
+	"  -t\t\tProvide time to run display PnP load in seconds.\n"
+	"  -s\t\tRun the socwatch with PnP load.\n"
+	"  -p\t\tProvide socwatch absloute path.\n"
+	"  -v\t\tsocwatch module version to load";
 
-const char *optstr = "lr:t:";
+const char *optstr = "lr:t:sp:v:";
 
 static void usage(const char *name)
 {
@@ -417,6 +497,7 @@ int main(int argc, char **argv)
 	data_t data = {};
 	int fps, c, i;
 	bool kms_cube = false;
+	char tmp[64];
 
 	while ((c = getopt(argc, argv, optstr)) != -1) {
 		switch (c) {
@@ -440,6 +521,15 @@ int main(int argc, char **argv)
 		case 't':
 			load_time = atoi(optarg);
 			break;
+		case 's':
+			socwatch = true;
+			break;
+		case 'p':
+			strcpy(sw_path, optarg);
+			break;
+		case 'v':
+			strcpy(sw_version, optarg);
+			break;
 		default:
 		case 'h':
 			usage(argv[0]);
@@ -447,6 +537,18 @@ int main(int argc, char **argv)
 		}
 	}
 
+	if (socwatch) {
+		snprintf(tmp, sizeof(tmp), "socwatch%s", sw_version);
+		igt_info("moulde to be checked %s\n", tmp);
+		if (!igt_kmod_is_loaded(tmp))
+			igt_skip("%s module is not loaded.\n", tmp);
+
+		data.socwatch_len =
+			snprintf(data.socwatch_cmd, sizeof(data.socwatch_cmd),
+				 "%s/socwatch -m --max-detail -f sys -f ddr-bw -t %d -o %s/results/",
+				 sw_path, load_time, sw_path);
+	}
+
 	data.drm_fd = drm_open_driver_master(DRIVER_INTEL);
 	data.debugfs_fd = igt_debugfs_dir(data.drm_fd);
 	igt_require(data.debugfs_fd != -1);
@@ -467,35 +569,45 @@ int main(int argc, char **argv)
 
 	switch (load_type) {
 	case IDLE_DISPLAY_OFF:
+		setup_socwatch_cmd(&data, load[load_type]);
 		idle_display_off(&data);
 		break;
 	case IDLE_DISPLAY_ON_PSR:
+		setup_socwatch_cmd(&data, load[load_type]);
 		idle_display_on(&data, PSR_ON);
 		break;
 	case IDLE_DISPLAY_ON_EDP_FBC:
+		setup_socwatch_cmd(&data, load[load_type]);
 		idle_display_on(&data, EDP_ON);
 		break;
 	case IDLE_DISPLAY_ON_HDMI_4K:
+		setup_socwatch_cmd(&data, load[load_type]);
 		idle_display_on(&data, HDMI_ON);
 		break;
 	case IDLE_DISPLAY_ON_DP_4K:
+		setup_socwatch_cmd(&data, load[load_type]);
 		idle_display_on(&data, DP_ON);
 		break;
 	case IDLE_DISPLAY_ON_EDP_EXTERNAL:
+		setup_socwatch_cmd(&data, load[load_type]);
 		idle_display_on(&data, PSR_ON | ANY_EXTERNAL_ON);
 		break;
 	case DPMS_EDP_ON_EXTERNAL_OFF:
+		setup_socwatch_cmd(&data, load[load_type]);
 		idle_display_on_with_dpms(&data, PSR_ON);
 		break;
 	case DPMS_EDP_OFF_EXTERNAL_ON:
+		setup_socwatch_cmd(&data, load[load_type]);
 		idle_display_on_with_dpms(&data, ANY_EXTERNAL_ON);
 		break;
 	case PSR2_IDLE_SELECTIVE_UPDATES_1FPS:
 		fps = 1;
+		setup_socwatch_cmd(&data, load[load_type]);
 		selective_updates_flips(&data, PSR2_ON, fps);
 		break;
 	case PSR2_SELECTIVE_UPDATES_30FPS:
 		fps = 30;
+		setup_socwatch_cmd(&data, load[load_type]);
 		selective_updates_flips(&data, PSR2_ON, fps);
 		break;
 	case KMS_CUBE:
-- 
2.26.2



More information about the igt-dev mailing list