Skip to content

Commit 83fbeb9

Browse files
Patryk Wlazlynlenb
authored andcommitted
tools/power turbostat: Allow adding PMT counters directly by sysfs path
Allow user to add PMT counters by either identifying the source with: guid=%u,seq=%u or, since this patch, with direct sysfs path: path=%s, for example path=/sys/class/intel_pmt/telem5 In the later case, the guid and sequence number will be infered by turbostat. Signed-off-by: Patryk Wlazlyn <[email protected]> Signed-off-by: Len Brown <[email protected]>
1 parent 16ce467 commit 83fbeb9

File tree

1 file changed

+106
-1
lines changed

1 file changed

+106
-1
lines changed

tools/power/x86/turbostat/turbostat.c

Lines changed: 106 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9788,11 +9788,96 @@ bool starts_with(const char *str, const char *prefix)
97889788
return strncmp(prefix, str, strlen(prefix)) == 0;
97899789
}
97909790

9791+
int pmt_parse_from_path(const char *target_path, unsigned int *out_guid, unsigned int *out_seq)
9792+
{
9793+
struct pmt_diriter_t pmt_iter;
9794+
const struct dirent *dirname;
9795+
struct stat stat, target_stat;
9796+
int fd_telem_dir = -1;
9797+
int fd_target_dir;
9798+
unsigned int seq = 0;
9799+
unsigned long guid, target_guid;
9800+
int ret = -1;
9801+
9802+
fd_target_dir = open(target_path, O_RDONLY | O_DIRECTORY);
9803+
if (fd_target_dir == -1) {
9804+
return -1;
9805+
}
9806+
9807+
if (fstat(fd_target_dir, &target_stat) == -1) {
9808+
fprintf(stderr, "%s: Failed to stat the target: %s", __func__, strerror(errno));
9809+
exit(1);
9810+
}
9811+
9812+
if (parse_telem_info_file(fd_target_dir, "guid", "%lx", &target_guid)) {
9813+
fprintf(stderr, "%s: Failed to parse the target guid file: %s", __func__, strerror(errno));
9814+
exit(1);
9815+
}
9816+
9817+
close(fd_target_dir);
9818+
9819+
pmt_diriter_init(&pmt_iter);
9820+
9821+
for (dirname = pmt_diriter_begin(&pmt_iter, SYSFS_TELEM_PATH); dirname != NULL;
9822+
dirname = pmt_diriter_next(&pmt_iter)) {
9823+
9824+
fd_telem_dir = openat(dirfd(pmt_iter.dir), dirname->d_name, O_RDONLY | O_DIRECTORY);
9825+
if (fd_telem_dir == -1) {
9826+
continue;
9827+
}
9828+
9829+
if (parse_telem_info_file(fd_telem_dir, "guid", "%lx", &guid)) {
9830+
fprintf(stderr, "%s: Failed to parse the guid file: %s", __func__, strerror(errno));
9831+
continue;
9832+
}
9833+
9834+
if (fstat(fd_telem_dir, &stat) == -1) {
9835+
fprintf(stderr, "%s: Failed to stat %s directory: %s", __func__,
9836+
dirname->d_name, strerror(errno));
9837+
continue;
9838+
}
9839+
9840+
/*
9841+
* If reached the same directory as target, exit the loop.
9842+
* Seq has the correct value now.
9843+
*/
9844+
if (stat.st_dev == target_stat.st_dev && stat.st_ino == target_stat.st_ino) {
9845+
ret = 0;
9846+
break;
9847+
}
9848+
9849+
/*
9850+
* If reached directory with the same guid,
9851+
* but it's not the target directory yet,
9852+
* increment seq and continue the search.
9853+
*/
9854+
if (guid == target_guid)
9855+
++seq;
9856+
9857+
close(fd_telem_dir);
9858+
fd_telem_dir = -1;
9859+
}
9860+
9861+
pmt_diriter_remove(&pmt_iter);
9862+
9863+
if (fd_telem_dir != -1)
9864+
close(fd_telem_dir);
9865+
9866+
if (!ret) {
9867+
*out_guid = target_guid;
9868+
*out_seq = seq;
9869+
}
9870+
9871+
return ret;
9872+
}
9873+
97919874
void parse_add_command_pmt(char *add_command)
97929875
{
97939876
char *name = NULL;
97949877
char *type_name = NULL;
97959878
char *format_name = NULL;
9879+
char *direct_path = NULL;
9880+
static const char direct_path_prefix[] = "path=";
97969881
unsigned int offset;
97979882
unsigned int lsb;
97989883
unsigned int msb;
@@ -9881,6 +9966,10 @@ void parse_add_command_pmt(char *add_command)
98819966
goto next;
98829967
}
98839968

9969+
if (strncmp(add_command, direct_path_prefix, strlen(direct_path_prefix)) == 0) {
9970+
direct_path = add_command + strlen(direct_path_prefix);
9971+
goto next;
9972+
}
98849973
next:
98859974
add_command = strchr(add_command, ',');
98869975
if (add_command) {
@@ -9952,8 +10041,24 @@ void parse_add_command_pmt(char *add_command)
995210041
exit(1);
995310042
}
995410043

10044+
if (direct_path && has_guid) {
10045+
printf("%s: path and guid+seq parameters are mutually exclusive\n"
10046+
"notice: passed guid=0x%x and path=%s\n", __func__, guid, direct_path);
10047+
exit(1);
10048+
}
10049+
10050+
if (direct_path) {
10051+
if (pmt_parse_from_path(direct_path, &guid, &seq)) {
10052+
printf("%s: failed to parse PMT file from %s\n", __func__, direct_path);
10053+
exit(1);
10054+
}
10055+
10056+
/* GUID was just infered from the direct path. */
10057+
has_guid = true;
10058+
}
10059+
995510060
if (!has_guid) {
9956-
printf("%s: missing %s\n", __func__, "guid");
10061+
printf("%s: missing %s\n", __func__, "guid or path");
995710062
exit(1);
995810063
}
995910064

0 commit comments

Comments
 (0)