Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/tools/perf/arch/s390/util/auxtrace.c
26292 views
1
#include <stdbool.h>
2
#include <stdlib.h>
3
#include <linux/kernel.h>
4
#include <linux/types.h>
5
#include <linux/bitops.h>
6
#include <linux/log2.h>
7
#include <linux/zalloc.h>
8
9
#include "../../util/evlist.h"
10
#include "../../util/auxtrace.h"
11
#include "../../util/evsel.h"
12
#include "../../util/record.h"
13
14
#define PERF_EVENT_CPUM_SF 0xB0000 /* Event: Basic-sampling */
15
#define PERF_EVENT_CPUM_SF_DIAG 0xBD000 /* Event: Combined-sampling */
16
#define DEFAULT_AUX_PAGES 128
17
#define DEFAULT_FREQ 4000
18
19
static void cpumsf_free(struct auxtrace_record *itr)
20
{
21
free(itr);
22
}
23
24
static size_t cpumsf_info_priv_size(struct auxtrace_record *itr __maybe_unused,
25
struct evlist *evlist __maybe_unused)
26
{
27
return 0;
28
}
29
30
static int
31
cpumsf_info_fill(struct auxtrace_record *itr __maybe_unused,
32
struct perf_session *session __maybe_unused,
33
struct perf_record_auxtrace_info *auxtrace_info __maybe_unused,
34
size_t priv_size __maybe_unused)
35
{
36
auxtrace_info->type = PERF_AUXTRACE_S390_CPUMSF;
37
return 0;
38
}
39
40
static unsigned long
41
cpumsf_reference(struct auxtrace_record *itr __maybe_unused)
42
{
43
return 0;
44
}
45
46
static int
47
cpumsf_recording_options(struct auxtrace_record *ar __maybe_unused,
48
struct evlist *evlist __maybe_unused,
49
struct record_opts *opts)
50
{
51
unsigned int factor = 1;
52
unsigned int pages;
53
54
opts->full_auxtrace = true;
55
56
/*
57
* The AUX buffer size should be set properly to avoid
58
* overflow of samples if it is not set explicitly.
59
* DEFAULT_AUX_PAGES is an proper size when sampling frequency
60
* is DEFAULT_FREQ. It is expected to hold about 1/2 second
61
* of sampling data. The size used for AUX buffer will scale
62
* according to the specified frequency and DEFAULT_FREQ.
63
*/
64
if (!opts->auxtrace_mmap_pages) {
65
if (opts->user_freq != UINT_MAX)
66
factor = (opts->user_freq + DEFAULT_FREQ
67
- 1) / DEFAULT_FREQ;
68
pages = DEFAULT_AUX_PAGES * factor;
69
opts->auxtrace_mmap_pages = roundup_pow_of_two(pages);
70
}
71
72
return 0;
73
}
74
75
static int
76
cpumsf_parse_snapshot_options(struct auxtrace_record *itr __maybe_unused,
77
struct record_opts *opts __maybe_unused,
78
const char *str __maybe_unused)
79
{
80
return 0;
81
}
82
83
/*
84
* auxtrace_record__init is called when perf record
85
* check if the event really need auxtrace
86
*/
87
struct auxtrace_record *auxtrace_record__init(struct evlist *evlist,
88
int *err)
89
{
90
struct auxtrace_record *aux;
91
struct evsel *pos;
92
int diagnose = 0;
93
94
*err = 0;
95
if (evlist->core.nr_entries == 0)
96
return NULL;
97
98
evlist__for_each_entry(evlist, pos) {
99
if (pos->core.attr.config == PERF_EVENT_CPUM_SF_DIAG) {
100
diagnose = 1;
101
pos->needs_auxtrace_mmap = true;
102
break;
103
}
104
}
105
106
if (!diagnose)
107
return NULL;
108
109
/* sampling in diagnose mode. alloc aux buffer */
110
aux = zalloc(sizeof(*aux));
111
if (aux == NULL) {
112
*err = -ENOMEM;
113
return NULL;
114
}
115
116
aux->parse_snapshot_options = cpumsf_parse_snapshot_options;
117
aux->recording_options = cpumsf_recording_options;
118
aux->info_priv_size = cpumsf_info_priv_size;
119
aux->info_fill = cpumsf_info_fill;
120
aux->free = cpumsf_free;
121
aux->reference = cpumsf_reference;
122
123
return aux;
124
}
125
126