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
|
#include "topology.h"
#include "trace_ops.h"
#include "utils.h"
#include "idlestat.h"
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <assert.h>
#include <values.h>
#define TRACE_FORMAT "%*[^]]] %*s %lf:%*[^=]=%u%*[^=]=%d"
static int ftrace_magic(const char *filename)
{
FILE *f;
char *line;
char buffer[BUFSIZE];
f = fopen(filename, "r");
if (!f) {
fprintf(stderr, "%s: failed to open '%s': %m\n", __func__,
filename);
return -1;
}
line = fgets(buffer, BUFSIZE, f);
fclose(f);
return (line != NULL) && !strncmp(buffer, "# tracer", 8);
}
static struct cpuidle_datas * ftrace_load(const char *filename)
{
FILE *f;
unsigned int nrcpus;
struct cpuidle_datas *datas;
int ret;
char *line;
char buffer[BUFSIZE];
f = fopen(filename, "r");
if (!f) {
fprintf(stderr, "%s: failed to open '%s': %m\n", __func__,
filename);
return ptrerror(NULL);
}
/* Version line */
line = fgets(buffer, BUFSIZE, f);
if (!line)
goto error_close;
/* Number of CPUs */
nrcpus = 0;
while(!feof(f)) {
if (buffer[0] != '#')
break;
if (strncmp(buffer, "#P:", 3)) {
ret = sscanf(buffer, "#%*[^#]#P:%u", &nrcpus);
if (ret != 1)
nrcpus = 0;
}
line = fgets(buffer, BUFSIZE, f);
}
if (!line)
goto error_close;
if (!nrcpus) {
fclose(f);
return ptrerror("Cannot load trace file (nrcpus == 0)");
}
datas = calloc(sizeof(*datas), 1);
if (!datas) {
fclose(f);
return ptrerror(__func__);
}
datas->nrcpus = nrcpus;
datas->pstates = build_pstate_info(nrcpus);
if (!datas->pstates)
goto propagate_error_free_datas;
datas->topo = read_sysfs_cpu_topo();
if (is_err(datas->topo))
goto propagate_error_free_datas;
/* Build C-state information from current host sysfs */
datas->cstates = build_cstate_info(nrcpus);
if (is_err(datas->cstates))
goto propagate_error_free_datas;
load_text_data_lines(f, buffer, datas);
fclose(f);
return datas;
propagate_error_free_datas:
fclose(f);
if (!is_err(datas->topo))
release_cpu_topo_info(datas->topo);
if (!is_err(datas->cstates))
release_cstate_info(datas->cstates, nrcpus);
free(datas);
return ptrerror(NULL);
error_close:
fclose(f);
fprintf(stderr, "%s: error or EOF while reading '%s': %m",
__func__, filename);
return ptrerror(NULL);
}
static const struct trace_ops ftrace_trace_ops = {
.name = "ftrace",
.check_magic = ftrace_magic,
.load = ftrace_load
};
EXPORT_TRACE_OPS(ftrace);
|