Commit 2a535d6c authored by Zhang Rui's avatar Zhang Rui Committed by Len Brown
Browse files

tools/power turbostat: Dump RAPL sysfs info



for example:

intel-rapl:1: psys 28.0s:100W 976.0us:100W
intel-rapl:0: package-0 28.0s:57W,max:15W 2.4ms:57W
intel-rapl:0/intel-rapl:0:0: core disabled
intel-rapl:0/intel-rapl:0:1: uncore disabled
intel-rapl-mmio:0: package-0 28.0s:28W,max:15W 2.4ms:57W

[lenb: simplified format]

Signed-off-by: default avatarZhang Rui <rui.zhang@intel.com>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>

squish me

Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent 69078520
Loading
Loading
Loading
Loading
+156 −0
Original line number Diff line number Diff line
@@ -7404,6 +7404,160 @@ void print_power_limit_msr(int cpu, unsigned long long msr, char *label)
	return;
}

static int fread_int(char *path, int *val)
{
	FILE *filep;
	int ret;

	filep = fopen (path, "r");
	if (!filep)
		return -1;

	ret = fscanf(filep, "%d", val);
	fclose(filep);
	return ret;
}

static int fread_ull(char *path, unsigned long long *val)
{
	FILE *filep;
	int ret;

	filep = fopen (path, "r");
	if (!filep)
		return -1;

	ret = fscanf(filep, "%llu", val);
	fclose(filep);
	return ret;
}

static int fread_str(char *path, char *buf, int size)
{
	FILE *filep;
	int ret;
	char *cp;

	filep = fopen (path, "r");
	if (!filep)
		return -1;

	ret = fread(buf, 1, size, filep);
	fclose(filep);

	/* replace '\n' with '\0' */
	cp = strchr(buf, '\n');
	if (cp != NULL)
		*cp = '\0';

	return ret;
}

#define PATH_RAPL_SYSFS	"/sys/class/powercap"

static int dump_one_domain(char *domain_path)
{
	char path[PATH_MAX];
	char str[PATH_MAX];
	unsigned long long val;
	int constraint;
	int enable;
	int ret;

	snprintf(path, PATH_MAX, "%s/name", domain_path);
	ret = fread_str(path, str, PATH_MAX);
	if (ret <= 0)
		return -1;

	fprintf(outf, "%s: %s", domain_path + strlen(PATH_RAPL_SYSFS) + 1, str);

	snprintf(path, PATH_MAX, "%s/enabled", domain_path);
	ret = fread_int(path, &enable);
	if (ret <= 0)
		return -1;

	if (!enable) {
		fputs(" disabled\n", outf);
		return 0;
	}

	for (constraint = 0;; constraint++)
	{
		snprintf(path, PATH_MAX, "%s/constraint_%d_time_window_us", domain_path, constraint);
		ret = fread_ull(path, &val);
		if (ret <= 0)
			break;

		if (val > 1000000)
			fprintf(outf, " %0.1fs", (double)val/1000000);
		else if (val > 1000)
			fprintf(outf, " %0.1fms", (double)val/1000);
		else
			fprintf(outf, " %0.1fus", (double)val);

		snprintf(path, PATH_MAX, "%s/constraint_%d_power_limit_uw", domain_path, constraint);
		ret = fread_ull(path, &val);
		if (ret > 0 && val)
			fprintf(outf, ":%lluW", val / 1000000);

		snprintf(path, PATH_MAX, "%s/constraint_%d_max_power_uw", domain_path, constraint);
		ret = fread_ull(path, &val);
		if (ret > 0 && val)
			fprintf(outf, ",max:%lluW", val / 1000000);
	}
	fputc('\n', outf);

	return 0;
}

static int print_rapl_sysfs(void)
{
	DIR *dir, *cdir;
	struct dirent *entry, *centry;
	char path[PATH_MAX];
	char str[PATH_MAX];

	if ((dir = opendir(PATH_RAPL_SYSFS)) == NULL) {
		warn("open %s failed", PATH_RAPL_SYSFS);
		return 1;
	}

	while ((entry = readdir (dir)) != NULL) {
		if (strlen(entry->d_name) > 100)
                        continue;

		if (strncmp(entry->d_name, "intel-rapl", strlen("intel-rapl")))
                        continue;

		snprintf(path, PATH_MAX, "%s/%s/name", PATH_RAPL_SYSFS, entry->d_name);

		/* Parse top level domains first, including package and psys */
		fread_str(path, str, PATH_MAX);
		if (strncmp(str, "package", strlen("package")) &&
		    strncmp(str, "psys", strlen("psys")))
			continue;

		snprintf(path, PATH_MAX, "%s/%s", PATH_RAPL_SYSFS, entry->d_name);
		if ((cdir = opendir(path)) == NULL) {
			perror ("opendir() error");
			return 1;
		}

		dump_one_domain(path);

		while ((centry = readdir (cdir)) != NULL) {
			if (strncmp(centry->d_name, "intel-rapl", strlen("intel-rapl")))
				continue;
			snprintf(path, PATH_MAX, "%s/%s/%s", PATH_RAPL_SYSFS, entry->d_name, centry->d_name);
			dump_one_domain(path);
		}
		closedir(cdir);
	}

	closedir(dir);
	return 0;
}

int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p)
{
	unsigned long long msr;
@@ -7538,6 +7692,8 @@ void probe_rapl(void)
	if (quiet)
		return;

	print_rapl_sysfs();

	if (!platform->rapl_msrs || no_msr)
		return;