aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/tools/testing/selftests/thermal/intel/workload_hint/workload_hint_test.c
blob: 217c3a641c5379c6e4384c867eb833fb02081909 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
// SPDX-License-Identifier: GPL-2.0

#define _GNU_SOURCE

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <poll.h>
#include <signal.h>

#define WORKLOAD_NOTIFICATION_DELAY_ATTRIBUTE "/sys/bus/pci/devices/0000:00:04.0/workload_hint/notification_delay_ms"
#define WORKLOAD_ENABLE_ATTRIBUTE "/sys/bus/pci/devices/0000:00:04.0/workload_hint/workload_hint_enable"
#define WORKLOAD_TYPE_INDEX_ATTRIBUTE  "/sys/bus/pci/devices/0000:00:04.0/workload_hint/workload_type_index"

static const char * const workload_types[] = {
	"idle",
	"battery_life",
	"sustained",
	"bursty",
	NULL
};

#define WORKLOAD_TYPE_MAX_INDEX	3

void workload_hint_exit(int signum)
{
	int fd;

	/* Disable feature via sysfs knob */

	fd = open(WORKLOAD_ENABLE_ATTRIBUTE, O_RDWR);
	if (fd < 0) {
		perror("Unable to open workload type feature enable file\n");
		exit(1);
	}

	if (write(fd, "0\n", 2) < 0) {
		perror("Can' disable workload hints\n");
		exit(1);
	}

	printf("Disabled workload type prediction\n");

	close(fd);
}

int main(int argc, char **argv)
{
	struct pollfd ufd;
	char index_str[4];
	int fd, ret, index;
	char delay_str[64];
	int delay = 0;

	printf("Usage: workload_hint_test [notification delay in milli seconds]\n");

	if (argc > 1) {
		ret = sscanf(argv[1], "%d", &delay);
		if (ret < 0) {
			printf("Invalid delay\n");
			exit(1);
		}

		printf("Setting notification delay to %d ms\n", delay);
		if (delay < 0)
			exit(1);

		sprintf(delay_str, "%s\n", argv[1]);

		sprintf(delay_str, "%s\n", argv[1]);
		fd = open(WORKLOAD_NOTIFICATION_DELAY_ATTRIBUTE, O_RDWR);
		if (fd < 0) {
			perror("Unable to open workload notification delay\n");
			exit(1);
		}

		if (write(fd, delay_str, strlen(delay_str)) < 0) {
			perror("Can't set delay\n");
			exit(1);
		}

		close(fd);
	}

	if (signal(SIGINT, workload_hint_exit) == SIG_IGN)
		signal(SIGINT, SIG_IGN);
	if (signal(SIGHUP, workload_hint_exit) == SIG_IGN)
		signal(SIGHUP, SIG_IGN);
	if (signal(SIGTERM, workload_hint_exit) == SIG_IGN)
		signal(SIGTERM, SIG_IGN);

	/* Enable feature via sysfs knob */
	fd = open(WORKLOAD_ENABLE_ATTRIBUTE, O_RDWR);
	if (fd < 0) {
		perror("Unable to open workload type feature enable file\n");
		exit(1);
	}

	if (write(fd, "1\n", 2) < 0) {
		perror("Can' enable workload hints\n");
		exit(1);
	}

	close(fd);

	printf("Enabled workload type prediction\n");

	while (1) {
		fd = open(WORKLOAD_TYPE_INDEX_ATTRIBUTE, O_RDONLY);
		if (fd < 0) {
			perror("Unable to open workload type file\n");
			exit(1);
		}

		if ((lseek(fd, 0L, SEEK_SET)) < 0) {
			fprintf(stderr, "Failed to set pointer to beginning\n");
			exit(1);
		}

		if (read(fd, index_str, sizeof(index_str)) < 0) {
			fprintf(stderr, "Failed to read from:%s\n",
			WORKLOAD_TYPE_INDEX_ATTRIBUTE);
			exit(1);
		}

		ufd.fd = fd;
		ufd.events = POLLPRI;

		ret = poll(&ufd, 1, -1);
		if (ret < 0) {
			perror("poll error");
			exit(1);
		} else if (ret == 0) {
			printf("Poll Timeout\n");
		} else {
			if ((lseek(fd, 0L, SEEK_SET)) < 0) {
				fprintf(stderr, "Failed to set pointer to beginning\n");
				exit(1);
			}

			if (read(fd, index_str, sizeof(index_str)) < 0)
				exit(0);

			ret = sscanf(index_str, "%d", &index);
			if (ret < 0)
				break;
			if (index > WORKLOAD_TYPE_MAX_INDEX)
				printf("Invalid workload type index\n");
			else
				printf("workload type:%s\n", workload_types[index]);
		}

		close(fd);
	}
}