[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